diff --git a/.github/workflows/greetings-pr.yml.disabled b/.github/workflows/greetings-pr.yml.disabled new file mode 100644 index 00000000000..2a930929a6d --- /dev/null +++ b/.github/workflows/greetings-pr.yml.disabled @@ -0,0 +1,13 @@ +# See syntax file on https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +name: Greetings PR + +on: [pull_request] + +jobs: + greeting: + runs-on: ubuntu-latest + steps: + - uses: actions/first-interaction@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + pr-message: 'Welcome to the Dolibarr army. You are on the road to become an Admiral (see https://wiki.dolibarr.org/index.php/Dolibarr_Project)' diff --git a/.github/workflows/stale-issues-safe.yml b/.github/workflows/stale-issues-safe.yml new file mode 100644 index 00000000000..c8139b37caf --- /dev/null +++ b/.github/workflows/stale-issues-safe.yml @@ -0,0 +1,24 @@ +# See syntax file on https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +name: "Close stale issues (bugs and feature requests)" + +on: + schedule: + - cron: "0 21 * * *" + issue_comment: + types: [created] + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: DeMoorJasper/stale@master + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-message: 'This issue is stale because it has been open 1 year with no activity. If this is a bug, please comment to confirm it is still present on latest stable version. if this is a feature request, please comment to notify the request is still relevant and not yet covered by latest stable version. This issue may be closed automatically by stale bot in 15 days (you should still be able to re-open it if required).' + stale-label: 'Issue Stale (automatic label)' + exempt-label: 'Priority High / Blocking' + days-before-stale: 365 + days-before-close: 15 + operations-per-run: 100 + dry-run: false + \ No newline at end of file diff --git a/.github/workflows/stale-issues.yml b/.github/workflows/stale-issues.yml new file mode 100644 index 00000000000..6e7dad5dc9b --- /dev/null +++ b/.github/workflows/stale-issues.yml @@ -0,0 +1,25 @@ +# See syntax file on https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +name: "Close stale issues (bugs and feature requests)" + +on: + schedule: + - cron: "0 20 * * *" + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: Dolibarr/stale@master + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'This issue is stale because it has been open 1 year with no activity. If this is a bug, please comment to confirm it is still present on latest stable version. if this is a feature request, please comment to notify the request is still relevant and not yet covered by latest stable version. This issue may be closed automatically by stale bot in 15 days (you should still be able to re-open it if required).' + stale-issue-label: 'Issue Stale (automatic label)' + exempt-issue-label: 'Priority High / Blocking' + days-before-stale: 365 + days-before-close: -1 + operations-per-run: 100 + #stale-pr-message: 'This PR is stale because it has been open 1 year with no activity. If this PR is still mergeable (no conflict, nor Continuous Integration errors), please comment to confirm this merge is still expected. Without comment, this issue will be closed automatically by stale bot in 15 days.' + stale-pr-label: 'PR Stale (automatic label)' + stale-pr-message: + exempt-pr-label: 'Priority Top Strategic' + \ No newline at end of file diff --git a/.gitignore b/.gitignore index ffacba65feb..30151359365 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,4 @@ htdocs/includes/sebastian/ htdocs/includes/squizlabs/ htdocs/includes/symfony/ htdocs/includes/webmozart/ +htdocs/.well-known/apple-developer-merchantid-domain-association diff --git a/.travis.yml b/.travis.yml index dd3322e5cf7..613d2fa2420 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ # For syntax, see http://about.travis-ci.org/docs/user/languages/php/ # We use dist: xenial to have php 5.6+ available +os: linux dist: xenial sudo: required @@ -43,7 +44,7 @@ env: global: # Set to true for very verbose output - DEBUG=false - matrix: + jobs: # MariaDB overrides MySQL installation so it's not possible to test both yet #- DB=mariadb - DB=mysql @@ -53,7 +54,7 @@ env: # See https://github.com/DracoBlue/travis-ci-nginx-php-fpm-test #- WS=nginx -matrix: +jobs: fast_finish: true allow_failures: - php: nightly diff --git a/COPYRIGHT b/COPYRIGHT index fe707c1d63d..09557f6520e 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -37,10 +37,11 @@ TCPDF 6.3.2 LGPL-3+ Yes TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes FPDI replacement JS libraries: -Ace 1.4.6 BSD Yes JS library to get code syntaxique coloration in a textarea. +Ace 1.4.8 BSD Yes JS library to get code syntaxique coloration in a textarea. +Chart 2.9.3 MIT License Yes JS library for graph jQuery 3.4.1 MIT License Yes JS library jQuery UI 1.12.1 GPL and MIT License Yes JS library plugin UI -jQuery select2 4.0.5 GPL and Apache License Yes JS library plugin for sexier multiselect +jQuery select2 4.0.13 GPL and Apache License Yes JS library plugin for sexier multiselect jQuery blockUI 2.70.0 GPL and MIT License Yes JS library plugin blockUI (to use ajax popups) jQuery Colorpicker 1.1 MIT License Yes JS library for color picker for a defined list of colors jQuery Flot 0.8.3 MIT License Yes JS library to build graph diff --git a/ChangeLog b/ChangeLog index 83c1adfe3d8..279fc01cfa8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,10 +2,73 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +***** ChangeLog for 11.0.2 compared to 11.0.1 ***** +FIX: #10309 +FIX: #13110 +FIX: #13118 +FIX: #13124 +FIX: #13131 +FIX: #13135 +FIX: #13146 #13198 +FIX: #13175 +FIX: #13182 +FIX: #13183 +FIX: #13184 +FIX: #13263 +FIX: #13267 +FIX: an external user can not approve +FIX: API Get list of documents for supplier_invoice +FIX: API to push an expense report +FIX: API upload/download doc for expensereport +FIX: Avoid to download the export if we just press enter to refresh form +FIX: Bad link to template invoices +FIX: Bad sort link in accounting report +FIX: Bad translation for productlot EatBy and SellBy +FIX: better method to check user rights AND usergroup rights ! +FIX: CA by product list filter +FIX: CSS +FIX: Disable js if no javascript +FIX: duplicate class name into some log lines +FIX: etrafield with visibilty=5 were not in read only. +FIX: excess paid from situation invoices not counted when calculating remain to pay. +FIX: Force FEC export to txt format. +FIX: Free input for email no more visible. +FIX: Keep assigned users in session when loading projects and tasks +FIX: List of viewed projects too large in task widget. +FIX: Menu truncated. Add tooltip to have all content. +FIX: Missing field "billed" in export. +FIX: missing "statut" for getNomUrl() function +FIX: modFournisseur is required by modSupplierProposal +FIX: Multicompany compatibility +FIX: must be == and not = +FIX: option for topbar search and bookmarks +FIX: option MAIN_OPTIMIZEFORTEXTBROWSER +FIX: some responsive troubles +FIX: round MT in accountancy books +FIX: search with '0' +FIX: sort link +FIX: SQL Overload in default contact trigger. +FIX: SQl syntax error. +FIX: Submit of documents for supplier invoices. +FIX: timezone must be tzserver and not tzuser as on contract card +FIX: token in barcode tools page missing +FIX: Bad name of trigger PROPAL_SUPPLIER_TRIGGER, should be PROPOSAL_SUPPLIER_TRIGGER +FIX: Type of contact for event does not exists and not supported +FIX: Type of contact not saved when creating a contact +FIX: typo on ckeck method +FIX: undefined function measuringUnitString in product list +FIX: Usage of project not available in export. +FIX: wrong test +FIX: z-index for moretabsList with constant MAIN_MAXTABS_IN_CARD +FIX: Use GETPOST instead of POST +FIX: HTML Injection +FIX: Visualization rights correction on last modified contacts box. +FIX: Vulnerability in module from modulebuilder. +FIX: Vulnerability reported by code16 ***** ChangeLog for 12.0.0 compared to 11.0.0 ***** For Users: - +NEW: Module MO (Manufacturing Order) is available as stable module. For Developers or integrators: @@ -15,9 +78,86 @@ WARNING: Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: * PHP 5.5 is no more supported. Minimum PHP is now 5.6+. +* Default mode for GETPOST function is now 'alphanohtml' instead of 'none'. So check when you make POST or GET requests + with HTML content that you make a GETPOST('myparam', 'restricthtml') or GETPOST('myparam', 'none') if you really need posted content without sanitizing + the HTML into content (in such a case, sanitize data later) +* Removed hidden constant MAIN_EXTRAFIELDS_IN_ONE_TD that was useless. +* Reference of object including a "/" are no more allowed. It is never used by default but to support setup that introduced it, the "/" will be replaced + by a "_" automatically when a reference is generated. + +***** ChangeLog for 11.0.1 compared to 11.0.0 ***** +FIX: advanced target emailing sql and ergonomy. +FIX: After import of a website template, home page was not set. +FIX: Avoid deletion of bank record if in accounting +FIX: compatibility with multicompany (avoid duplicate data) +FIX: Confusion between 'bank reconciled' and 'accounted'. Show both data. +FIX: Count of Stripe payment mode must take test/live into account +FIX: Creation of Stripe card from backoffice must return a clean message +FIX: CVE-2019–17223 +FIX: CVE-2019–17223 +FIX: CVE-2020-7994 +FIX: CVE Need permission to be able to develop modules +FIX: #13053 +FIX: Disable ticket status change if ticket closed +FIX: doc of dictionnary API +FIX: expedition ceate line new parameter is not required. +FIX: export ledger +FIX: FEC export have specific name +FIX: Filenames must not contains non ascii char or we will get non ascii +FIX: Filter on list of events were lost after "Back to list" +FIX: hasDelay for retained warranty +FIX: If we can change vendor status, we must be able to chane vendor code +FIX: links in products/services index +FIX: Log of authentication ok or ko + CVE-2020-7996 +FIX: Look and feel v11 +FIX: Mail smtps truncated if content has a line with single . +FIX: missing hook parameter +FIX: Missing include +FIX: need weight short label in shipping doc +FIX: Picture of contact not visible in tooltip +FIX: Problem with column label in subscription list +FIX: ref_client not visible in tooltip. +FIX: search filter on extrafields were not restored after "Back to list" +FIX: situation invoice: allow excess paid to be converted to discount +FIX: situation invoice: bad amount for previous payments because of local variable overwriting a more global one +FIX: situation invoice: can't convert excess received to discount & bad previous payment amount +FIX: SQL request and phpunit +FIX: Update export_files.php +FIX: Use ref into label of ticket message +FIX: use "usergroup" instead of "user" +FIX: Warning on admin/export_files +FIX: #10203 +FIX: default filtering for 'select' extrafields should use "=", not "LIKE" +FIX: #11975 When a product is split between multiple pages in a document, prices/quantity/etc appear on the last relevant page +FIX: #12760 #12763 #12755 #12765 #12751 +FIX: #12874 +FIX: #12892 +FIX: #12908 User login with credentials from self-subscription form fails +FIX: #12932 +FIX: #12966 +FIX: #12973 +FIX: #12974 +FIX: #12975 +FIX: #12978 +FIX: #12986 +FIX: #12991 +FIX: #12992 +FIX: #12995 +FIX: #13018 Extrafields Supplier invoice +FIX: #13019 +FIX: #13022 +FIX: #13028 +FIX: #13038 ExpenseReport PDF - custom category description is not correct +FIX: #13046 More complete +FIX: #13048 +FIX: #13050 +FIX: #13077 Replace left join with inner join (left join was useless) +FIX: #13085 +FIX: #13094 +FIX: #13096 +FIX: #13100 + - - ***** ChangeLog for 11.0.0 compared to 10.0.0 ***** For Users: diff --git a/README-FR.md b/README-FR.md index 94af10cb04f..bccb7b0143b 100644 --- a/README-FR.md +++ b/README-FR.md @@ -151,6 +151,7 @@ La documentation utilisateur, développeur et traducteur est disponible sous for ## CONTRIBUER Ce projet existe grâce à ses nombreux contributeurs [[Contribuer](https://github.com/Dolibarr/dolibarr/blob/develop/.github/CONTRIBUTING.md)]. + ## CREDITS diff --git a/README.md b/README.md index 085ab808488..b8d067ffb7a 100644 --- a/README.md +++ b/README.md @@ -170,7 +170,8 @@ Administrator, user, developer and translator's documentations are available alo ## CONTRIBUTING -This project exists thanks to all the people who contribute. [[Contribute](https://github.com/Dolibarr/dolibarr/blob/develop/.github/CONTRIBUTING.md)]. +This project exists thanks to all the people who contribute. [[Contribute](https://github.com/Dolibarr/dolibarr/blob/develop/.github/CONTRIBUTING.md)] + ## CREDITS diff --git a/build/README b/build/README index 07f0ebe3b55..67ceb05c8d2 100644 --- a/build/README +++ b/build/README @@ -45,9 +45,12 @@ Dolibarr working. It is here only to build Dolibarr packages, and those generated packages will not contains this "build" directory. -We can find in "build", following sub-directories: +You can find in "build", following sub-directories: -* debian: +* composer +To test an upgrade of a lib. + +* debian To build Debian package. * dmg: diff --git a/build/obs/README b/build/obs/README index c8a29e1dac4..44427c01d49 100644 --- a/build/obs/README +++ b/build/obs/README @@ -1,20 +1,24 @@ README (English) ################################################## OBS Package tools +OBE - openSUSE Build Service ################################################## -This directory contains files to explain how to publish -a package onto OBS +This directory contains an instruction to explain +how to publish a package onto OBS. -# Create a project onto OBS -#---------------------------------- -https://build.opensuse.org +# Create a project onto OBS +--------------------------- +https://build.opensuse.org -Packaging rules: http://en.opensuse.org/Portal:Packaging + +# Packaging rules: +------------------ +https://en.opensuse.org/Portal:Packaging Add attributes: -OBS:Screenshots URL of screenshot http://www.dolibarr.org/images/dolibarr_screenshot1.png +OBS:Screenshots URL of screenshot https://www.dolibarr.org/images/dolibarr_screenshot1.png OBS:QualityCategory Development|Testing|Stable|Private OBS:Maintained 1 @@ -28,22 +32,24 @@ To submit a snapshot for building, we should have a service file with content -How to have such a service file created automatically ? -Go into project you want to update. It mught be: +# How to have such a service file created automatically ? +--------------------------------------------------------- +Go into project you want to update. It might be: - openSUSE Build Service > Projects > Application:ERP:Dolibarr > dolibarr - or your private project Once logged, click on "Add file" in section "Source Files", then select mode "Upload From: Remote URL" Keep empty for "Filename", choose "Remote URL" and enter into last field, URL that should looks like this: -http://www.dolibarr.org/files/stable/package_rpm_generic/dolibarr-x.y.v-0.4.src.rpm +https://www.dolibarr.org/files/stable/package_rpm_generic/dolibarr-x.y.v-0.4.src.rpm Then add into Advanded - Attributes -OBS:Screenshots http://www.dolibarr.org/images/dolibarr_screenshot1.png -OBS:QualityCategory Stable|Testing|Development|Private +OBS:Screenshots https://www.dolibarr.org/images/dolibarr_screenshot1.png +OBS:QualityCategory Stable|Testing|Development|Private # Move project into official directory +-------------------------------------- - Enter a bug to ask to be a maintener of a category or to add a new one. For example: https://bugzilla.novell.com/show_bug.cgi?id=848083 to be a maintener of category https://build.opensuse.org/project/show/Application:ERP diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index 107f561eca6..81a273d102a 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -253,6 +253,24 @@ PARSEDOWN $shortage = 4 - $len % 4; + +OAUTH +----- +Add into Class Google of file OAuth2/Service/Google: + + // LDR CHANGE Add approval_prompt to force the prompt if value is set to 'force' so it force return of a "refresh token" in addition to "standard token" + public $approvalPrompt='auto'; + public function setApprouvalPrompt($prompt) + { + if (!in_array($prompt, array('auto', 'force'), true)) { + // @todo Maybe could we rename this exception + throw new InvalidAccessTypeException('Invalid approuvalPrompt, expected either auto or force.'); + } + $this->approvalPrompt = $prompt; + } + + + JEDITABLE.JS ------------ diff --git a/dev/examples/code/create_invoice.php b/dev/examples/code/create_invoice.php index dbbe9d84c1c..1b212e0a5d7 100755 --- a/dev/examples/code/create_invoice.php +++ b/dev/examples/code/create_invoice.php @@ -66,8 +66,9 @@ $obj = new Facture($db); $obj->ref = 'ABCDE'; $obj->socid = 4; // Put id of third party (rowid in llx_societe table) -$obj->date = mktime(); -$obj->note = 'A comment'; +$obj->date = dol_now(); +$obj->note_public = 'A public comment'; +$obj->note_private = 'A private comment'; $obj->cond_reglement_id = 1; $line1=new FactureLigne($db); diff --git a/dev/examples/code/create_order.php b/dev/examples/code/create_order.php index 30265d5462e..703254ad5e9 100755 --- a/dev/examples/code/create_order.php +++ b/dev/examples/code/create_order.php @@ -66,8 +66,9 @@ $com = new Commande($db); $com->ref = 'ABCDE'; $com->socid = 4; // Put id of third party (rowid in llx_societe table) -$com->date_commande = mktime(); -$com->note = 'A comment'; +$com->date = dol_now(); +$com->note_public = 'A public comment'; +$com->note_private = 'A private comment'; $com->source = 1; $com->remise_percent = 0; diff --git a/dev/examples/ldap/ldapadd_sample1.txt b/dev/examples/ldap/ldapadd_sample1.txt index 8a28529acb8..e998d6013a3 100644 --- a/dev/examples/ldap/ldapadd_sample1.txt +++ b/dev/examples/ldap/ldapadd_sample1.txt @@ -11,4 +11,4 @@ objectclass: dcObject objectClass: organization objectClass: top dc: my-domain -o: Mon organisation \ No newline at end of file +o: my organisation diff --git a/dev/examples/ldap/ldapmodify_sample1.txt b/dev/examples/ldap/ldapmodify_sample1.txt index e3a8361ca31..e95d1dc03a7 100644 --- a/dev/examples/ldap/ldapmodify_sample1.txt +++ b/dev/examples/ldap/ldapmodify_sample1.txt @@ -12,4 +12,4 @@ objectclass: dcObject objectClass: organization objectClass: top dc: my-domain -o: Mon organisation \ No newline at end of file +o: my organisation diff --git a/dev/initdata/generate-invoice.php b/dev/initdata/generate-invoice.php index 220144f2a7d..3fe058e8d3e 100755 --- a/dev/initdata/generate-invoice.php +++ b/dev/initdata/generate-invoice.php @@ -23,6 +23,10 @@ * \brief Script example to inject random customer invoices (for load tests) */ +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + // Test si mode batch $sapi_type = php_sapi_name(); if (substr($sapi_type, 0, 3) == 'cgi') { diff --git a/dev/initdata/generate-order.php b/dev/initdata/generate-order.php index 129313c70fd..1dc56aa5582 100755 --- a/dev/initdata/generate-order.php +++ b/dev/initdata/generate-order.php @@ -24,6 +24,10 @@ * \brief Script example to inject random orders (for load tests) */ +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + // Test si mode batch $sapi_type = php_sapi_name(); if (substr($sapi_type, 0, 3) == 'cgi') { diff --git a/dev/initdata/generate-product.php b/dev/initdata/generate-product.php index 49fd9860467..a82c0262360 100755 --- a/dev/initdata/generate-product.php +++ b/dev/initdata/generate-product.php @@ -24,6 +24,10 @@ * \brief Script example to inject random products (for load tests) */ +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + // Test si mode batch $sapi_type = php_sapi_name(); if (substr($sapi_type, 0, 3) == 'cgi') { diff --git a/dev/initdata/generate-proposal.php b/dev/initdata/generate-proposal.php index d0b2cd4aa56..4c5d70aadc4 100755 --- a/dev/initdata/generate-proposal.php +++ b/dev/initdata/generate-proposal.php @@ -24,6 +24,10 @@ * \brief Script example to inject random proposals (for load tests) */ +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + // Test si mode batch $sapi_type = php_sapi_name(); if (substr($sapi_type, 0, 3) == 'cgi') { diff --git a/dev/initdata/generate-thirdparty.php b/dev/initdata/generate-thirdparty.php index 91c7c969b75..05ac6416aa3 100755 --- a/dev/initdata/generate-thirdparty.php +++ b/dev/initdata/generate-thirdparty.php @@ -24,6 +24,10 @@ * \brief Script example to inject random thirdparties (for load tests) */ +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + // Test si mode batch $sapi_type = php_sapi_name(); if (substr($sapi_type, 0, 3) == 'cgi') { diff --git a/dev/initdata/import-users.php b/dev/initdata/import-users.php index 60a672adf12..4247415288c 100755 --- a/dev/initdata/import-users.php +++ b/dev/initdata/import-users.php @@ -20,7 +20,7 @@ */ /** - * \file dev/initdata/import-thirdparties.php + * \file dev/initdata/import-users.php * \brief Script example to insert thirdparties from a csv file. * To purge data, you can have a look at purge-data.php */ diff --git a/dev/resources/licence/Links on GPL.txt b/dev/resources/licence/Links on GPL.txt index bb9c1597f68..0fb3b63c851 100644 --- a/dev/resources/licence/Links on GPL.txt +++ b/dev/resources/licence/Links on GPL.txt @@ -1,7 +1,7 @@ -* Page with licence compatibility +* Page with license compatibility https://www.gnu.org/licenses/quick-guide-gplv3.fr.html -* FAQ on GPL licence +* FAQ on GPL license https://www.fsf.org/licensing/licenses/gpl-faq.html * Questions/Answers on Fork for using Dolibarr as a SaaS diff --git a/dev/resources/sepa/text.txt b/dev/resources/sepa/text.txt index 0a5336a128e..e6c05276be2 100644 --- a/dev/resources/sepa/text.txt +++ b/dev/resources/sepa/text.txt @@ -1,2 +1,2 @@ -To test a SEPA file: -http://www.mesfluxdepaiement.fr/testez-vos-fichiers-sepa \ No newline at end of file +To test a SEPA file: +https://www.mesfluxdepaiement.fr/testez-vos-fichiers-sepa diff --git a/dev/setup/codesniffer/ruleset.dtd b/dev/setup/codesniffer/ruleset.dtd index 276626a3a16..24aa32970ea 100644 --- a/dev/setup/codesniffer/ruleset.dtd +++ b/dev/setup/codesniffer/ruleset.dtd @@ -1,13 +1,18 @@ - + + + + - + + + diff --git a/dev/setup/codesniffer/ruleset.xml b/dev/setup/codesniffer/ruleset.xml index 460f815755e..8bd3ff8b319 100644 --- a/dev/setup/codesniffer/ruleset.xml +++ b/dev/setup/codesniffer/ruleset.xml @@ -2,6 +2,7 @@ Dolibarr coding standard. + build/html build/aps @@ -188,7 +189,6 @@ - diff --git a/dev/setup/eclipse/PSR-12 [built-in].xml b/dev/setup/eclipse/PSR-12 [built-in].xml new file mode 100644 index 00000000000..47925209682 --- /dev/null +++ b/dev/setup/eclipse/PSR-12 [built-in].xml @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dev/tools/dolibarr-postgres2mysql.php b/dev/tools/dolibarr-postgres2mysql.php new file mode 100644 index 00000000000..f2794455ca3 --- /dev/null +++ b/dev/tools/dolibarr-postgres2mysql.php @@ -0,0 +1,578 @@ +#!/usr/bin/env php + Lightbox Technologies Inc. + * Copyright (C) 2020 Laurent Destailleur + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * This file is base on pg2mysql provided as Open source by lightbox.org. + * It was enhanced and updated by the Dolibarr team. + */ + +/** + * \file dev/tools/dolibarr-postgres2mysql.php + * \brief Script to migrate a postgresql dump into a mysql dump + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path = dirname(__FILE__) . '/'; + +// Test si mode batch +$sapi_type = php_sapi_name(); +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute " . $script_file . " from command line, you must use PHP for CLI mode.\n"; + exit(); +} + +error_reporting(E_ALL & ~ E_DEPRECATED); +define('PRODUCT', "pg2mysql"); +define('VERSION', "2.0"); + +// this is the default, it can be overridden here, or specified as the third parameter on the command line +$config['engine'] = "InnoDB"; + +if (! ($argv[1] && $argv[2])) { + echo "Usage: php pg2mysql_cli.php [engine]\n"; + exit(); +} else { + if (isset($argv[3])) + $config['engine'] = $argv[3]; + pg2mysql_large($argv[1], $argv[2]); + + echo <<=0 if OK + */ +function pg2mysql_large($infilename, $outfilename) +{ + $infp = fopen($infilename, "rt"); + $outfp = fopen($outfilename, "wt"); + + $outputatend = ''; + $arrayofprimaryalreadyintabledef = array(); + + // we read until we get a semicolon followed by a newline (;\n); + $pgsqlchunk = array(); + $chunkcount = 1; + $linenum = 0; + $inquotes = false; + $first = true; + + if (empty($infp)) { + print 'Failed to open file '.$infilename."\n"; + return -1; + } + + $fs = filesize($infilename); + echo "Filesize: " . formatsize($fs) . "\n"; + + while ($instr = fgets($infp)) { + $linenum ++; + $memusage = round(memory_get_usage(true) / 1024 / 1024); + $len = strlen($instr); + $pgsqlchunk[] = $instr; + $c = substr_count($instr, "'"); + // we have an odd number of ' marks + if ($c % 2 != 0) { + if ($inquotes) + $inquotes = false; + else + $inquotes = true; + } + + if ($linenum % 10000 == 0) { + $currentpos = ftell($infp); + $percent = round($currentpos / $fs * 100); + $position = formatsize($currentpos); + printf("Reading progress: %3d%% position: %7s line: %9d sql chunk: %9d mem usage: %4dM\r", $percent, $position, $linenum, $chunkcount, $memusage); + } + + if (strlen($instr) > 3 && ($instr[$len - 3] == ")" && $instr[$len - 2] == ";" && $instr[$len - 1] == "\n") && $inquotes == false) { + $chunkcount ++; + + if ($linenum % 10000 == 0) { + $currentpos = ftell($infp); + $percent = round($currentpos / $fs * 100); + $position = formatsize($currentpos); + printf("Processing progress: %3d%% position: %7s line: %9d sql chunk: %9d mem usage: %4dM\r", $percent, $position, $linenum, $chunkcount, $memusage); + } + /* + * echo "sending chunk:\n"; + * echo "=======================\n"; + * print_r($pgsqlchunk); + * echo "=======================\n"; + */ + + /* + * foreach ($pgsqlchunk as $aaa) { + * if (preg_match('/MAIN_ENABLE_DEFAULT|MAIN_MAIL_SMTP_SE/', $aaa)) { + * var_dump($pgsqlchunk); + * } + * } + */ + + $mysqlchunk = pg2mysql($pgsqlchunk, $arrayofprimaryalreadyintabledef, $first); + fputs($outfp, $mysqlchunk['output']); + + /* + * $break = false; + * foreach ($pgsqlchunk as $aaa) { + * if (preg_match('/MAIN_ENABLE_DEFAULT|MAIN_MAIL_SMTP_SE/', $aaa)) { + * var_dump($mysqlchunk); + * } + * if (preg_match('/MAIN_MAIL_SMTP_SE/', $aaa)) { + * $break = true; + * } + * } + * if ($break) break; + */ + + $outputatend .= $mysqlchunk['outputatend']; + + $first = false; + $pgsqlchunk = array(); + $mysqlchunk = ""; + } + } + echo "\n\n"; + + fputs($outfp, $outputatend); + + fputs($outfp, "\n"); + + fputs($outfp, '/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;' . "\n"); + fputs($outfp, '/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;' . "\n"); + fputs($outfp, '/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;' . "\n"); + fputs($outfp, '/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;' . "\n"); + fputs($outfp, '/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;' . "\n"); + fputs($outfp, '/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;' . "\n"); + fputs($outfp, '/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;' . "\n"); + + printf("Completed! %9d lines %9d sql chunks\n\n", $linenum, $chunkcount); + + fclose($infp); + fclose($outfp); + + return 0; +} + +/** + * pg2mysql + * + * @param array $input Array of input + * @param array $arrayofprimaryalreadyintabledef Array of table already output with a primary key set into definition + * @param boolean $header Boolean + * @return string[] Array of output + */ +function pg2mysql(&$input, &$arrayofprimaryalreadyintabledef, $header = true) +{ + global $config; + + if (is_array($input)) { + $lines = $input; + } else { + $lines = split("\n", $input); + } + + if ($header) { + $output = "-- Converted with " . PRODUCT . "-" . VERSION . "\n"; + $output .= "-- Converted on " . date("r") . "\n"; + $output .= "\n"; + + $output .= "/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;\n"; + $output .= "/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;\n"; + $output .= "/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;\n"; + $output .= "/*!40101 SET NAMES utf8 */;\n"; + $output .= "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;\n"; + $output .= "/*!40103 SET TIME_ZONE='+00:00' */;\n"; + $output .= "/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n"; + $output .= "/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;\n"; + $output .= "/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;\n"; + $output .= "/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;\n"; + $output .= "\n"; + + $outputatend = ""; + } else { + $output = ""; + $outputatend = ""; + } + + $in_create_table = $in_insert = false; + + $linenumber = 0; + $tbl_extra = ""; + while (isset($lines[$linenumber])) { + $line = $lines[$linenumber]; + // $line =str_replace('ALTER TABLE public\.', '', $line); + + $reg = array(); + if (preg_match('/CREATE SEQUENCE (?:public\.)(.*)_(id|rowid|id_comment)_seq/', $line, $reg)) { + $outputatend .= '-- Make field ' . $reg[2] . ' auto_increment for table ' . $reg[1] . "\n"; + $outputatend .= 'ALTER TABLE ' . $reg[1] . ' CHANGE COLUMN ' . $reg[2] . ' ' . $reg[2] . ' INTEGER NOT NULL AUTO_INCREMENT;' . "\n\n"; + // var_dump($outputatend); + } + + if (substr($line, 0, 12) == "CREATE TABLE") { + $in_create_table = true; + $line = str_replace("\"", "`", $line); + $line = str_replace('public.', '', $line); + + $reg2 = array(); + if (preg_match('/CREATE TABLE ([^\s]+)/', $line, $reg2)) { + $in_create_table = $reg2[1]; + } + + $reg2 = array(); + if (preg_match('/CREATE TABLE ([^\s]+)/', $line, $reg2)) { + $output .= 'DROP TABLE IF EXISTS `' . $reg2[1] . '`;' . "\n"; + } + $output .= $line; + $linenumber ++; + continue; + } + + if (substr($line, 0, 2) == ");" && $in_create_table) { + $in_create_table = false; + $line = ") ENGINE={$config['engine']};\n\n"; + + $output .= $tbl_extra; + $output .= $line; + + $linenumber ++; + $tbl_extra = ""; + continue; + } + + if ($in_create_table) { + $regs = array(); + $line = str_replace("\"", "`", $line); + $line = str_replace(" integer", " int(11)", $line); + $line = str_replace(" int_unsigned", " int(11) UNSIGNED", $line); + $line = str_replace(" smallint_unsigned", " smallint UNSIGNED", $line); + $line = str_replace(" bigint_unsigned", " bigint UNSIGNED", $line); + $line = str_replace(" serial ", " int(11) auto_increment ", $line); + $line = str_replace(" bytea", " BLOB", $line); + $line = str_replace(" boolean", " bool", $line); + $line = str_replace(" bool DEFAULT true", " bool DEFAULT 1", $line); + $line = str_replace(" bool DEFAULT false", " bool DEFAULT 0", $line); + if (preg_match("/ character varying\(([0-9]*)\)/", $line, $regs)) { + $num = $regs[1]; + if ($num <= 255) + $line = preg_replace("/ character varying\([0-9]*\)/", " varchar($num)", $line); + else + $line = preg_replace("/ character varying\([0-9]*\)/", " text", $line); + } + // character varying with no size, we will default to varchar(255) + if (preg_match("/ character varying/", $line)) { + $line = preg_replace("/ character varying/", " varchar(255)", $line); + } + + if (preg_match("/ DEFAULT \('([0-9]*)'::int/", $line, $regs) || preg_match("/ DEFAULT \('([0-9]*)'::smallint/", $line, $regs) || preg_match("/ DEFAULT \('([0-9]*)'::bigint/", $line, $regs)) { + $num = $regs[1]; + $line = preg_replace("/ DEFAULT \('([0-9]*)'[^ ,]*/", " DEFAULT $num ", $line); + } + if (preg_match("/ DEFAULT \(([0-9\-]*)\)/", $line, $regs)) { + $num = $regs[1]; + $line = preg_replace("/ DEFAULT \(([0-9\-]*)\)/", " DEFAULT $num ", $line); + } + $line = preg_replace("/ DEFAULT nextval\(.*\) /", " auto_increment ", $line); + $line = preg_replace("/::.*,/", ",", $line); + $line = preg_replace("/::.*$/", "\n", $line); + if (preg_match("/character\(([0-9]*)\)/", $line, $regs)) { + $num = $regs[1]; + if ($num <= 255) + $line = preg_replace("/ character\([0-9]*\)/", " varchar($num)", $line); + else + $line = preg_replace("/ character\([0-9]*\)/", " text", $line); + } + // timestamps + $line = str_replace(" timestamp with time zone", " datetime", $line); + $line = str_replace(" timestamp without time zone", " datetime", $line); + + // time + $line = str_replace(" time with time zone", " time", $line); + $line = str_replace(" time without time zone", " time", $line); + + $line = str_replace(" timestamp DEFAULT now()", " timestamp DEFAULT CURRENT_TIMESTAMP", $line); + $line = str_replace(" timestamp without time zone DEFAULT now()", " timestamp DEFAULT CURRENT_TIMESTAMP", $line); + + if (strstr($line, "auto_increment") || preg_match('/ rowid int/', $line) || preg_match('/ id int/', $line)) { + $field = getfieldname($line); + $tbl_extra .= ", PRIMARY KEY(`$field`)\n"; + $arrayofprimaryalreadyintabledef[$in_create_table] = $in_create_table; + } + + $specialfields = array("repeat","status","type","call"); + + $field = getfieldname($line); + if (in_array($field, $specialfields)) { + $line = str_replace("$field ", "`$field` ", $line); + } + + // text/blob fields are not allowed to have a default, so if we find a text DEFAULT, change it to varchar(255) DEFAULT + if (strstr($line, "text DEFAULT")) { + $line = str_replace(" text DEFAULT ", " varchar(255) DEFAULT ", $line); + } + + // just skip a CONSTRAINT line + if (strstr($line, " CONSTRAINT ")) { + $line = ""; + // and if the previous output ended with a , remove the , + $lastchr = substr($output, - 2, 1); + // echo "lastchr=$lastchr"; + if ($lastchr == ",") { + $output = substr($output, 0, - 2) . "\n"; + } + } + + $output .= $line; + } + + if (substr($line, 0, 11) == "INSERT INTO") { + $line = str_replace('public.', '', $line); + + if (substr($line, - 3, - 1) == ");") { + // we have a complete insert on one line + list ($before, $after) = explode(" VALUES ", $line, 2); + // we only replace the " with ` in what comes BEFORE the VALUES + // (ie, field names, like INSERT INTO table ("bla","bla2") VALUES ('s:4:"test"','bladata2'); + // should convert to INSERT INTO table (`bla`,`bla2`) VALUES ('s:4:"test"','bladata2'); + + $before = str_replace("\"", "`", $before); + + // in after, we need to watch out for escape format strings, ie (E'escaped \r in a string'), and ('bla',E'escaped \r in a string'), but could also be (number, E'string'); so we cant search for the previoous ' + // ugh i guess its possible these strings could exist IN the data as well, but the only way to solve that is to process these lines one character + // at a time, and thats just stupid, so lets just hope this doesnt appear anywhere in the actual data + $after = str_replace(" (E'", " ('", $after); + $after = str_replace(", E'", ", '", $after); + + $output .= $before . " VALUES " . $after; + $linenumber ++; + continue; + } else { + // this insert spans multiple lines, so keep dumping the lines until we reach a line + // that ends with ");" + + list ($before, $after) = explode(" VALUES ", $line, 2); + // we only replace the " with ` in what comes BEFORE the VALUES + // (ie, field names, like INSERT INTO table ("bla","bla2") VALUES ('s:4:"test"','bladata2'); + // should convert to INSERT INTO table (`bla`,`bla2`) VALUES ('s:4:"test"','bladata2'); + + $before = str_replace("\"", "`", $before); + + // in after, we need to watch out for escape format strings, ie (E'escaped \r in a string'), and ('bla',E'escaped \r in a string') + // ugh i guess its possible these strings could exist IN the data as well, but the only way to solve that is to process these lines one character + // at a time, and thats just stupid, so lets just hope this doesnt appear anywhere in the actual data + $after = str_replace(" (E'", " ('", $after); + $after = str_replace(", E'", ", '", $after); + + $c = substr_count($line, "'"); + // we have an odd number of ' marks + if ($c % 2 != 0) { + $inquotes = true; + } else { + $inquotes = false; + } + + $output .= $before . " VALUES " . $after; + do { + $linenumber ++; + + // in after, we need to watch out for escape format strings, ie (E'escaped \r in a string'), and ('bla',E'escaped \r in a string') + // ugh i guess its possible these strings could exist IN the data as well, but the only way to solve that is to process these lines one character + // at a time, and thats just stupid, so lets just hope this doesnt appear anywhere in the actual data + + // after the first line, we only need to check for it in the middle, not at the beginning of an insert (becuase the beginning will be on the first line) + // $after=str_replace(" (E'","' ('",$after); + $line = $lines[$linenumber]; + $line = str_replace("', E'", "', '", $line); + $output .= $line; + + // printf("inquotes: %d linenumber: %4d line: %s\n",$inquotes,$linenumber,$lines[$linenumber]); + + $c = substr_count($line, "'"); + // we have an odd number of ' marks + if ($c % 2 != 0) { + if ($inquotes) + $inquotes = false; + else + $inquotes = true; + // echo "inquotes=$inquotes\n"; + } + } while (substr($lines[$linenumber], - 3, - 1) != ");" || $inquotes); + } + } + if (substr($line, 0, 16) == "ALTER TABLE ONLY") { + $line = preg_replace('/ ONLY/', '', $line); + $line = str_replace("\"", "`", $line); + $line = str_replace("public.", "", $line); + $pkey = $line; + + $linenumber ++; + if (! empty($lines[$linenumber])) { + $line = $lines[$linenumber]; + } else { + $line = ''; + } + + if (strstr($line, " PRIMARY KEY ") && substr($line, - 3, - 1) == ");") { + $reg2 = array(); + if (preg_match('/ALTER TABLE ([^\s]+)/', $pkey, $reg2)) { + if (empty($arrayofprimaryalreadyintabledef[$reg2[1]])) { + // looks like we have a single line PRIMARY KEY definition, lets go ahead and add it + $output .= str_replace("\n", "", $pkey); + // the postgres and mysql syntax for this is (at least, in the example im looking at) + // identical, so we can just add it as is. + $output .= $line . "\n"; + } else { + $output .= '-- ' . str_replace("\n", "", $pkey); + $output .= '-- ' . $line . "\n"; + } + } else { + $output .= '-- ' . str_replace("\n", "", $pkey); + $output .= '-- ' . $line . "\n"; + } + } + } + + // while we're here, we might as well catch CREATE INDEX as well + if (substr($line, 0, 12) == "CREATE INDEX") { + $matches = array(); + preg_match('/CREATE INDEX "?([a-zA-Z0-9_]*)"? ON "?([a-zA-Z0-9_\.]*)"? USING btree \((.*)\);/', $line, $matches); + if (! empty($matches[3])) { + $indexname = $matches[1]; + $tablename = str_replace('public.', '', $matches[2]); + $columns = $matches[3]; + if ($tablename && $columns) { + $output .= "ALTER TABLE `" . $tablename . "` ADD INDEX " . $indexname . "( {$columns} ) ;\n"; + } + } + } + if (substr($line, 0, 19) == "CREATE UNIQUE INDEX") { + $matches = array(); + preg_match('/CREATE UNIQUE INDEX "?([a-zA-Z0-9_]*)"? ON "?([a-zA-Z0-9_\.]*)"? USING btree \((.*)\);/', $line, $matches); + if (! empty($matches[3])) { + $indexname = $matches[1]; + $tablename = str_replace('public.', '', $matches[2]); + $columns = str_replace('"', '', $matches[3]); + if ($tablename && $columns) { + $output .= "ALTER TABLE `" . $tablename . "` ADD UNIQUE INDEX " . $indexname . " ( {$columns} ) ;\n"; + } + } + } + + if (substr($line, 0, 13) == 'DROP DATABASE') + $output .= $line; + + if (substr($line, 0, 15) == 'CREATE DATABASE') { + $matches = array(); + preg_match('/CREATE DATABASE ([a-zA-Z0-9_]*) .* ENCODING = \'(.*)\'/', $line, $matches); + $output .= "CREATE DATABASE `$matches[1]` DEFAULT CHARACTER SET $matches[2];\n\n"; + } + + if (substr($line, 0, 8) == '\\connect') { + $matches = array(); + preg_match('/connect ([a-zA-Z0-9_]*)/', $line, $matches); + $output .= "USE `$matches[1]`;\n\n"; + } + + if (substr($line, 0, 5) == 'COPY ') { + $matches = array(); + preg_match('/COPY (.*) FROM stdin/', $line, $matches); + $heads = str_replace('"', "`", $matches[1]); + $values = array(); + $in_insert = true; + } elseif ($in_insert) { + if ($line == "\\.\n") { + $in_insert = false; + if ($values) { + $output .= "INSERT INTO $heads VALUES\n" . implode(",\n", $values) . ";\n\n"; + } + } else { + $vals = explode(' ', $line); + foreach ($vals as $i => $val) { + $vals[$i] = ($val == '\\N') ? 'NULL' : "'" . str_replace("'", "\\'", trim($val)) . "'"; + } + $values[] = '(' . implode(',', $vals) . ')'; + if (count($values) >= 1000) { + $output .= "INSERT INTO $heads VALUES\n" . implode(",\n", $values) . ";\n"; + $values = array(); + } + } + } + + $linenumber ++; + } + + return array('output' => $output,'outputatend' => $outputatend); +} diff --git a/dev/translation/README b/dev/translation/README index b470e4228d8..9727f91e2e6 100644 --- a/dev/translation/README +++ b/dev/translation/README @@ -3,11 +3,12 @@ README (English) This directory contains tools to generate translation files for a new languages or to update translation files for existing languages. See Dolibarr Wiki page: -http://wiki.dolibarr.org/index.php/Translator_documentation +https://wiki.dolibarr.org/index.php/Translator_documentation For more information on how to use them. +for Linux OS: To install transifex client: sudo pip install --upgrade transifex-client To update transifex client: -sudo pip install --upgrade transifex-client \ No newline at end of file +sudo pip install --upgrade transifex-client diff --git a/dev/translation/erp_comparison_translation.txt b/dev/translation/erp_comparison_translation.txt index c99a5f4cc1c..6cf7c4f7c60 100644 --- a/dev/translation/erp_comparison_translation.txt +++ b/dev/translation/erp_comparison_translation.txt @@ -1,17 +1,25 @@ +comparison of terms -Term Dolibarr SAP Odoo ... ----------------------------------------------------------------------------- -Thirdparty Contact partner Partner/Contact (company) -Contact/address Contact person Partner/Contact (individual) +Dolibarr SAP ERP Odoo +------------------------------------------------------------------------- +Thirdparty Contact partner Partner/Contact (company) +Contact/address Contact person Partner/Contact (individual) -Financial ?? Invoicing - -Income / Expense ?? Profit / Loss -Balance ?? Net profit -Subledger account Subledger account ?? +Financial Finance (FI) Accounting +Accounting -Proposal ?? Quotation Proposal is ok but proposition looks better (proposal is for a detailed proposition). We can say also "business proposition or business proposal". - Indian are using "Quotation". +Income / Expense ?? Profit / Loss +Balance ?? Net profit +Subledger account Subledger account ?? + +CRM Sales & Distribution Sales +Proposal ?? Quotation + + + +Proposal is ok but proposition looks better (proposal is for a detailed proposition). +We can say also "business proposition or business proposal". +In India they are using "Quotation". diff --git a/doc/user/README-DE.md b/doc/user/README-DE.md new file mode 100644 index 00000000000..ea9458f4563 --- /dev/null +++ b/doc/user/README-DE.md @@ -0,0 +1,12 @@ +README (german) +LiesMich (deutsch) + +-------------------------------- +Benutzeranleitung +-------------------------------- + +Alle Dolibarr-Informationen sind online verfuegbar ueber die Webseiten: +https://www.dolibarr.de +oder +https://www.dolibarr.org +https://wiki.dolibarr.org diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index 9de858da26b..6d59a9de1f6 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -45,7 +45,8 @@ $search_label = GETPOST('search_label', 'alpha'); $search_labelshort = GETPOST('search_labelshort', 'alpha'); $search_accountparent = GETPOST('search_accountparent', 'alpha'); $search_pcgtype = GETPOST('search_pcgtype', 'alpha'); -$search_pcgsubtype = GETPOST('search_pcgsubtype', 'alpha'); + +$chartofaccounts = GETPOST('chartofaccounts', 'int'); // Security check if ($user->socid > 0) accessforbidden(); @@ -69,8 +70,7 @@ $arrayfields = array( 'aa.labelshort'=>array('label'=>$langs->trans("LabelToShow"), 'checked'=>1), 'aa.account_parent'=>array('label'=>$langs->trans("Accountparent"), 'checked'=>1), 'aa.pcg_type'=>array('label'=>$langs->trans("Pcgtype"), 'checked'=>1, 'help'=>'PcgtypeDesc'), - 'aa.pcg_subtype'=>array('label'=>$langs->trans("Pcgsubtype"), 'checked'=>0, 'help'=>'PcgtypeDesc'), - 'aa.active'=>array('label'=>$langs->trans("Activated"), 'checked'=>1) + 'aa.active'=>array('label'=>$langs->trans("Activated"), 'checked'=>1) ); $accounting = new AccountingAccount($db); @@ -101,14 +101,11 @@ if (empty($reshook)) $search_labelshort = ""; $search_accountparent = ""; $search_pcgtype = ""; - $search_pcgsubtype = ""; $search_array_options = array(); } - - if (GETPOST('change_chart', 'alpha') && (GETPOST('valid_change_chart', 'int') || empty($conf->use_javascript_ajax))) + if ((GETPOST('valid_change_chart', 'alpha') && GETPOST('chartofaccounts', 'int') > 0) // explicit click on button 'Change and load' with js on + || (GETPOST('chartofaccounts', 'int') > 0 && GETPOST('chartofaccounts', 'int') != $conf->global->CHARTOFACCOUNTS)) // a submit of form is done and chartofaccounts combo has been modified { - $chartofaccounts = GETPOST('chartofaccounts', 'int'); - if ($chartofaccounts > 0) { // Get language code for this $chartofaccounts @@ -195,7 +192,7 @@ if ($action == 'delete') { $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.labelshort, aa.active, "; +$sql = "SELECT aa.rowid, aa.fk_pcg_version, aa.pcg_type, aa.account_number, aa.account_parent , aa.label, aa.labelshort, aa.active, "; $sql .= " a2.rowid as rowid2, a2.label as label2, a2.account_number as account_number2"; $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as aa"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version AND aa.entity = ".$conf->entity; @@ -241,7 +238,6 @@ if (strlen(trim($search_label))) $sql .= natural_search("aa.label", $search_la if (strlen(trim($search_labelshort))) $sql .= natural_search("aa.labelshort", $search_labelshort); if (strlen(trim($search_accountparent)) && $search_accountparent != '-1') $sql .= natural_search("aa.account_parent", $search_accountparent, 2); if (strlen(trim($search_pcgtype))) $sql .= natural_search("aa.pcg_type", $search_pcgtype); -if (strlen(trim($search_pcgsubtype))) $sql .= natural_search("aa.pcg_subtype", $search_pcgsubtype); $sql .= $db->order($sortfield, $sortorder); // Count total nb of records @@ -274,23 +270,17 @@ if ($resql) if ($search_labelshort) $param .= '&search_labelshort='.urlencode($search_labelshort); if ($search_accountparent > 0 || $search_accountparent == '0') $param .= '&search_accountparent='.urlencode($search_accountparent); if ($search_pcgtype) $param .= '&search_pcgtype='.urlencode($search_pcgtype); - if ($search_pcgsubtype) $param .= '&search_pcgsubtype='.urlencode($search_pcgsubtype); - if ($optioncss != '') $param .= '&optioncss='.$optioncss; + if ($optioncss != '') $param .= '&optioncss='.$optioncss; if (!empty($conf->use_javascript_ajax)) { - print ' + print ' '; @@ -337,8 +327,7 @@ if ($resql) else dol_print_error($db); print ""; print ajax_combobox("chartofaccounts"); - print ''; - print ''; + print ''; print '
'; print '
'; @@ -363,7 +352,6 @@ if ($resql) print ''; } if (!empty($arrayfields['aa.pcg_type']['checked'])) print ''; - if (!empty($arrayfields['aa.pcg_subtype']['checked'])) print ''; if (!empty($arrayfields['aa.active']['checked'])) print ' '; print ''; $searchpicto = $form->showFilterAndCheckAddButtons($massactionbutton ? 1 : 0, 'checkforselect', 1); @@ -377,7 +365,6 @@ if ($resql) if (!empty($arrayfields['aa.labelshort']['checked'])) print_liste_field_titre($arrayfields['aa.labelshort']['label'], $_SERVER["PHP_SELF"], "aa.labelshort", "", $param, '', $sortfield, $sortorder); if (!empty($arrayfields['aa.account_parent']['checked'])) print_liste_field_titre($arrayfields['aa.account_parent']['label'], $_SERVER["PHP_SELF"], "aa.account_parent", "", $param, '', $sortfield, $sortorder, 'left '); if (!empty($arrayfields['aa.pcg_type']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_type']['label'], $_SERVER["PHP_SELF"], 'aa.pcg_type', '', $param, '', $sortfield, $sortorder, '', $arrayfields['aa.pcg_type']['help']); - if (!empty($arrayfields['aa.pcg_subtype']['checked'])) print_liste_field_titre($arrayfields['aa.pcg_subtype']['label'], $_SERVER["PHP_SELF"], 'aa.pcg_subtype', '', $param, '', $sortfield, $sortorder, '', $arrayfields['aa.pcg_subtype']['help']); if (!empty($arrayfields['aa.active']['checked'])) print_liste_field_titre($arrayfields['aa.active']['label'], $_SERVER["PHP_SELF"], 'aa.active', '', $param, '', $sortfield, $sortorder); print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); print "\n"; @@ -454,15 +441,6 @@ if ($resql) if (!$i) $totalarray['nbfield']++; } - // Chart of accounts subtype - if (!empty($arrayfields['aa.pcg_subtype']['checked'])) - { - print ""; - print $obj->pcg_subtype; - print "\n"; - if (!$i) $totalarray['nbfield']++; - } - // Activated or not if (!empty($arrayfields['aa.active']['checked'])) { diff --git a/htdocs/accountancy/admin/accountmodel.php b/htdocs/accountancy/admin/accountmodel.php index 2e39105eb21..2ed3ad44695 100644 --- a/htdocs/accountancy/admin/accountmodel.php +++ b/htdocs/accountancy/admin/accountmodel.php @@ -39,31 +39,31 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; -if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php'; +if (!empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; // Load translation files required by the page -$langs->loadLangs(array("errors","admin","companies","resource","holiday","compta","accountancy","hrm")); +$langs->loadLangs(array("errors", "admin", "companies", "resource", "holiday", "compta", "accountancy", "hrm")); -$action=GETPOST('action', 'aZ09')?GETPOST('action', 'aZ09'):'view'; -$confirm=GETPOST('confirm', 'alpha'); -$id=31; -$rowid=GETPOST('rowid', 'alpha'); -$code=GETPOST('code', 'alpha'); +$action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; +$confirm = GETPOST('confirm', 'alpha'); +$id = 31; +$rowid = GETPOST('rowid', 'alpha'); +$code = GETPOST('code', 'alpha'); $acts[0] = "activate"; $acts[1] = "disable"; $actl[0] = img_picto($langs->trans("Disabled"), 'switch_off'); $actl[1] = img_picto($langs->trans("Activated"), 'switch_on'); -$listoffset=GETPOST('listoffset', 'alpha'); -$listlimit=GETPOST('listlimit', 'int')>0?GETPOST('listlimit', 'int'):1000; +$listoffset = GETPOST('listoffset', 'alpha'); +$listlimit = GETPOST('listlimit', 'int') > 0 ?GETPOST('listlimit', 'int') : 1000; $active = 1; $sortfield = GETPOST("sortfield", 'aZ09comma'); $sortorder = GETPOST("sortorder", 'aZ09comma'); $page = GETPOST("page", 'int'); if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 -$offset = $listlimit * $page ; +$offset = $listlimit * $page; $pageprev = $page - 1; $pagenext = $page + 1; @@ -72,7 +72,7 @@ $search_country_id = GETPOST('search_country_id', 'int'); // Security check if ($user->socid > 0) accessforbidden(); -if (! $user->rights->accounting->chartofaccount) accessforbidden(); +if (!$user->rights->accounting->chartofaccount) accessforbidden(); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context @@ -82,56 +82,56 @@ $hookmanager->initHooks(array('admin')); // Put here declaration of dictionaries properties // Name of SQL tables of dictionaries -$tabname=array(); +$tabname = array(); -$tabname[31]= MAIN_DB_PREFIX."accounting_system"; +$tabname[31] = MAIN_DB_PREFIX."accounting_system"; // Dictionary labels -$tablib=array(); -$tablib[31]= "Pcg_version"; +$tablib = array(); +$tablib[31] = "Pcg_version"; // Requests to extract data -$tabsql=array(); -$tabsql[31]= "SELECT s.rowid as rowid, pcg_version, s.label, s.fk_country as country_id, c.code as country_code, c.label as country, s.active FROM ".MAIN_DB_PREFIX."accounting_system as s, ".MAIN_DB_PREFIX."c_country as c WHERE s.fk_country=c.rowid and c.active=1"; +$tabsql = array(); +$tabsql[31] = "SELECT s.rowid as rowid, pcg_version, s.label, s.fk_country as country_id, c.code as country_code, c.label as country, s.active FROM ".MAIN_DB_PREFIX."accounting_system as s, ".MAIN_DB_PREFIX."c_country as c WHERE s.fk_country=c.rowid and c.active=1"; // Criteria to sort dictionaries -$tabsqlsort=array(); -$tabsqlsort[31]="pcg_version ASC"; +$tabsqlsort = array(); +$tabsqlsort[31] = "pcg_version ASC"; // Nom des champs en resultat de select pour affichage du dictionnaire -$tabfield=array(); -$tabfield[31]= "pcg_version,label,country_id,country"; +$tabfield = array(); +$tabfield[31] = "pcg_version,label,country_id,country"; // Nom des champs d'edition pour modification d'un enregistrement -$tabfieldvalue=array(); -$tabfieldvalue[31]= "pcg_version,label,country"; +$tabfieldvalue = array(); +$tabfieldvalue[31] = "pcg_version,label,country"; // Nom des champs dans la table pour insertion d'un enregistrement -$tabfieldinsert=array(); -$tabfieldinsert[31]= "pcg_version,label,fk_country"; +$tabfieldinsert = array(); +$tabfieldinsert[31] = "pcg_version,label,fk_country"; // Nom du rowid si le champ n'est pas de type autoincrement // Example: "" if id field is "rowid" and has autoincrement on // "nameoffield" if id field is not "rowid" or has not autoincrement on -$tabrowid=array(); -$tabrowid[31]= ""; +$tabrowid = array(); +$tabrowid[31] = ""; // Condition to show dictionary in setup page -$tabcond=array(); -$tabcond[31]= ! empty($conf->accounting->enabled); +$tabcond = array(); +$tabcond[31] = !empty($conf->accounting->enabled); // List of help for fields -$tabhelp=array(); +$tabhelp = array(); $tabhelp[31] = array('pcg_version'=>$langs->trans("EnterAnyCode")); // List of check for fields (NOT USED YET) -$tabfieldcheck=array(); +$tabfieldcheck = array(); $tabfieldcheck[31] = array(); // Define elementList and sourceList (used for dictionary type of contacts "llx_c_type_contact") $elementList = array(); -$sourceList=array(); +$sourceList = array(); @@ -147,38 +147,38 @@ if (GETPOST('button_removefilter', 'alpha') || GETPOST('button_removefilter.x', // Actions add or modify an entry into a dictionary if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { - $listfield=explode(',', str_replace(' ', '', $tabfield[$id])); - $listfieldinsert=explode(',', $tabfieldinsert[$id]); - $listfieldmodify=explode(',', $tabfieldinsert[$id]); - $listfieldvalue=explode(',', $tabfieldvalue[$id]); + $listfield = explode(',', str_replace(' ', '', $tabfield[$id])); + $listfieldinsert = explode(',', $tabfieldinsert[$id]); + $listfieldmodify = explode(',', $tabfieldinsert[$id]); + $listfieldvalue = explode(',', $tabfieldvalue[$id]); // Check that all fields are filled - $ok=1; + $ok = 1; foreach ($listfield as $f => $value) { - if ($value == 'country_id' && in_array($tablib[$id], array('Pcg_version'))) continue; // For some pages, country is not mandatory - if ((! isset($_POST[$value]) || $_POST[$value]=='')) + if ($value == 'country_id' && in_array($tablib[$id], array('Pcg_version'))) continue; // For some pages, country is not mandatory + if ((!GETPOSTISSET($value)) || GETPOST($value) == '') { - $ok=0; - $fieldnamekey=$listfield[$f]; + $ok = 0; + $fieldnamekey = $listfield[$f]; // We take translate key of field - if ($fieldnamekey == 'pcg_version') $fieldnamekey='Pcg_version'; - if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) $fieldnamekey='Label'; + if ($fieldnamekey == 'pcg_version') $fieldnamekey = 'Pcg_version'; + if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) $fieldnamekey = 'Label'; setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors'); } } // Other checks - if ($tabname[$id] == MAIN_DB_PREFIX."c_actioncomm" && isset($_POST["type"]) && in_array($_POST["type"], array('system','systemauto'))) { - $ok=0; + if ($tabname[$id] == MAIN_DB_PREFIX."c_actioncomm" && GETPOSTISSET("type") && in_array($_POST["type"], array('system', 'systemauto'))) { + $ok = 0; setEventMessages($langs->transnoentities('ErrorReservedTypeSystemSystemAuto'), null, 'errors'); } - if (isset($_POST["pcg_version"])) + if (GETPOSTISSET("pcg_version")) { - if ($_POST["pcg_version"]=='0') + if (GETPOST("pcg_version") == '0') { - $ok=0; + $ok = 0; setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors'); } /*if (!is_numeric($_POST['code'])) // disabled, code may not be in numeric base @@ -187,9 +187,9 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) $msg .= $langs->transnoentities('ErrorFieldFormat', $langs->transnoentities('Code')).'
'; }*/ } - if (isset($_POST["country"]) && ($_POST["country"]=='0') && ($id != 2)) + if (isset($_POST["country"]) && ($_POST["country"] == '0') && ($id != 2)) { - $ok=0; + $ok = 0; setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities("Country")), null, 'errors'); } @@ -199,13 +199,13 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) if ($tabrowid[$id]) { // Recupere id libre pour insertion - $newid=0; + $newid = 0; $sql = "SELECT max(".$tabrowid[$id].") newid from ".$tabname[$id]; $result = $db->query($sql); if ($result) { $obj = $db->fetch_object($result); - $newid=($obj->newid + 1); + $newid = ($obj->newid + 1); } else { dol_print_error($db); } @@ -214,16 +214,16 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) // Add new entry $sql = "INSERT INTO ".$tabname[$id]." ("; // List of fields - if ($tabrowid[$id] && ! in_array($tabrowid[$id], $listfieldinsert)) - $sql.= $tabrowid[$id].","; - $sql.= $tabfieldinsert[$id]; - $sql.=",active)"; - $sql.= " VALUES("; + if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) + $sql .= $tabrowid[$id].","; + $sql .= $tabfieldinsert[$id]; + $sql .= ",active)"; + $sql .= " VALUES("; // List of values - if ($tabrowid[$id] && ! in_array($tabrowid[$id], $listfieldinsert)) - $sql.= $newid.","; - $i=0; + if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) + $sql .= $newid.","; + $i = 0; foreach ($listfieldinsert as $f => $value) { if ($value == 'price' || preg_match('/^amount/i', $value) || $value == 'taux') { @@ -232,19 +232,19 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) elseif ($value == 'entity') { $_POST[$listfieldvalue[$i]] = $conf->entity; } - if ($i) $sql.=","; - if ($_POST[$listfieldvalue[$i]] == '') $sql.="null"; - else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + if ($i) $sql .= ","; + if ($_POST[$listfieldvalue[$i]] == '') $sql .= "null"; + else $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; $i++; } - $sql.=",1)"; + $sql .= ",1)"; dol_syslog("actionadd", LOG_DEBUG); $result = $db->query($sql); if ($result) // Add is ok { setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs'); - $_POST=array('id'=>$id); // Clean $_POST array, we keep only + $_POST = array('id'=>$id); // Clean $_POST array, we keep only } else { @@ -260,16 +260,16 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) // Si verif ok et action modify, on modifie la ligne if ($ok && GETPOST('actionmodify', 'alpha')) { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } + if ($tabrowid[$id]) { $rowidcol = $tabrowid[$id]; } + else { $rowidcol = "rowid"; } // Modify entry $sql = "UPDATE ".$tabname[$id]." SET "; // Modifie valeur des champs - if ($tabrowid[$id] && ! in_array($tabrowid[$id], $listfieldmodify)) + if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldmodify)) { - $sql.= $tabrowid[$id]."="; - $sql.= "'".$db->escape($rowid)."', "; + $sql .= $tabrowid[$id]."="; + $sql .= "'".$db->escape($rowid)."', "; } $i = 0; foreach ($listfieldmodify as $field) @@ -280,18 +280,18 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) elseif ($field == 'entity') { $_POST[$listfieldvalue[$i]] = $conf->entity; } - if ($i) $sql.=","; - $sql.= $field."="; - if ($_POST[$listfieldvalue[$i]] == '') $sql.="null"; - else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + if ($i) $sql .= ","; + $sql .= $field."="; + if ($_POST[$listfieldvalue[$i]] == '') $sql .= "null"; + else $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; $i++; } - $sql.= " WHERE ".$rowidcol." = '".$rowid."'"; + $sql .= " WHERE ".$rowidcol." = '".$rowid."'"; dol_syslog("actionmodify", LOG_DEBUG); //print $sql; $resql = $db->query($sql); - if (! $resql) + if (!$resql) { setEventMessages($db->error(), null, 'errors'); } @@ -306,14 +306,14 @@ if (GETPOST('actioncancel', 'alpha')) if ($action == 'confirm_delete' && $confirm == 'yes') // delete { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } + if ($tabrowid[$id]) { $rowidcol = $tabrowid[$id]; } + else { $rowidcol = "rowid"; } $sql = "DELETE from ".$tabname[$id]." WHERE ".$rowidcol."='".$rowid."'"; dol_syslog("delete", LOG_DEBUG); $result = $db->query($sql); - if (! $result) + if (!$result) { if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') { @@ -329,8 +329,8 @@ if ($action == 'confirm_delete' && $confirm == 'yes') // delete // activate if ($action == $acts[0]) { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } + if ($tabrowid[$id]) { $rowidcol = $tabrowid[$id]; } + else { $rowidcol = "rowid"; } if ($rowid) { $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE ".$rowidcol."='".$rowid."'"; @@ -349,8 +349,8 @@ if ($action == $acts[0]) // disable if ($action == $acts[1]) { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } + if ($tabrowid[$id]) { $rowidcol = $tabrowid[$id]; } + else { $rowidcol = "rowid"; } if ($rowid) { $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE ".$rowidcol."='".$rowid."'"; @@ -369,8 +369,8 @@ if ($action == $acts[1]) // favorite if ($action == 'activate_favorite') { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } + if ($tabrowid[$id]) { $rowidcol = $tabrowid[$id]; } + else { $rowidcol = "rowid"; } if ($rowid) { $sql = "UPDATE ".$tabname[$id]." SET favorite = 1 WHERE ".$rowidcol."='".$rowid."'"; @@ -389,8 +389,8 @@ if ($action == 'activate_favorite') // disable favorite if ($action == 'disable_favorite') { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } + if ($tabrowid[$id]) { $rowidcol = $tabrowid[$id]; } + else { $rowidcol = "rowid"; } if ($rowid) { $sql = "UPDATE ".$tabname[$id]." SET favorite = 0 WHERE ".$rowidcol."='".$rowid."'"; @@ -412,12 +412,12 @@ if ($action == 'disable_favorite') */ $form = new Form($db); -$formadmin=new FormAdmin($db); +$formadmin = new FormAdmin($db); llxHeader(); -$titre=$langs->trans($tablib[$id]); -$linkback=''; +$titre = $langs->trans($tablib[$id]); +$linkback = ''; print load_fiche_titre($titre, $linkback, 'title_accountancy'); @@ -425,7 +425,7 @@ print load_fiche_titre($titre, $linkback, 'title_accountancy'); // Confirmation de la suppression de la ligne if ($action == 'delete') { - print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page?'page='.urlencode($page).'&':'').'sortfield='.urlencode($sortfield).'&sortorder='.urlencode($sortorder).'&rowid='.urlencode($rowid).'&code='.urlencode($code).'&id='.urlencode($id), $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1); + print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page ? 'page='.urlencode($page).'&' : '').'sortfield='.urlencode($sortfield).'&sortorder='.urlencode($sortorder).'&rowid='.urlencode($rowid).'&code='.urlencode($code).'&id='.urlencode($id), $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1); } //var_dump($elementList); @@ -435,22 +435,22 @@ if ($action == 'delete') if ($id) { // Complete requete recherche valeurs avec critere de tri - $sql=$tabsql[$id]; + $sql = $tabsql[$id]; if ($search_country_id > 0) { - if (preg_match('/ WHERE /', $sql)) $sql.= " AND "; - else $sql.=" WHERE "; - $sql.= " c.rowid = ".$search_country_id; + if (preg_match('/ WHERE /', $sql)) $sql .= " AND "; + else $sql .= " WHERE "; + $sql .= " c.rowid = ".$search_country_id; } // If sort order is "country", we use country_code instead - if ($sortfield == 'country') $sortfield='country_code'; - $sql.=$db->order($sortfield, $sortorder); - $sql.=$db->plimit($listlimit+1, $offset); + if ($sortfield == 'country') $sortfield = 'country_code'; + $sql .= $db->order($sortfield, $sortorder); + $sql .= $db->plimit($listlimit + 1, $offset); //print $sql; - $fieldlist=explode(',', $tabfield[$id]); + $fieldlist = explode(',', $tabfield[$id]); print '
'; print ''; @@ -461,10 +461,10 @@ if ($id) // Form to add a new line if ($tabname[$id]) { - $alabelisused=0; - $var=false; + $alabelisused = 0; + $var = false; - $fieldlist=explode(',', $tabfield[$id]); + $fieldlist = explode(',', $tabfield[$id]); // Line for title print ''; @@ -472,33 +472,33 @@ if ($id) { // Determine le nom du champ par rapport aux noms possibles // dans les dictionnaires de donnees - $valuetoshow=ucfirst($fieldlist[$field]); // Par defaut - $valuetoshow=$langs->trans($valuetoshow); // try to translate - $class="left"; - if ($fieldlist[$field]=='code') { $valuetoshow=$langs->trans("Code"); } - if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') + $valuetoshow = ucfirst($fieldlist[$field]); // Par defaut + $valuetoshow = $langs->trans($valuetoshow); // try to translate + $class = "left"; + if ($fieldlist[$field] == 'code') { $valuetoshow = $langs->trans("Code"); } + if ($fieldlist[$field] == 'libelle' || $fieldlist[$field] == 'label') { - $valuetoshow=$langs->trans("Label"); + $valuetoshow = $langs->trans("Label"); } - if ($fieldlist[$field]=='country') { + if ($fieldlist[$field] == 'country') { if (in_array('region_id', $fieldlist)) { print ' '; continue; } // For region page, we do not show the country input - $valuetoshow=$langs->trans("Country"); + $valuetoshow = $langs->trans("Country"); } - if ($fieldlist[$field]=='country_id') { $valuetoshow=''; } - if ($fieldlist[$field]=='pcg_version' || $fieldlist[$field]=='fk_pcg_version') { $valuetoshow=$langs->trans("Pcg_version"); } + if ($fieldlist[$field] == 'country_id') { $valuetoshow = ''; } + if ($fieldlist[$field] == 'pcg_version' || $fieldlist[$field] == 'fk_pcg_version') { $valuetoshow = $langs->trans("Pcg_version"); } if ($valuetoshow != '') { print ''; - if (! empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { + if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { print ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; - } elseif (! empty($tabhelp[$id][$value])) { + } elseif (!empty($tabhelp[$id][$value])) { print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]); } else { print $valuetoshow; } print ''; } - if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') $alabelisused=1; + if ($fieldlist[$field] == 'libelle' || $fieldlist[$field] == 'label') $alabelisused = 1; } print ''; @@ -518,14 +518,14 @@ if ($id) foreach ($fieldlist as $key=>$val) { if (GETPOST($val)) - $obj->$val=GETPOST($val); + $obj->$val = GETPOST($val); } } $tmpaction = 'create'; - $parameters=array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); - $reshook=$hookmanager->executeHooks('createDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks - $error=$hookmanager->error; $errors=$hookmanager->errors; + $parameters = array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $reshook = $hookmanager->executeHooks('createDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks + $error = $hookmanager->error; $errors = $hookmanager->errors; if (empty($reshook)) { @@ -537,32 +537,32 @@ if ($id) print ''; print ""; - $colspan=count($fieldlist)+3; + $colspan = count($fieldlist) + 3; - print ' '; // Keep   to have a line with enough height + print ' '; // Keep   to have a line with enough height } // List of available values in database dol_syslog("htdocs/admin/dict", LOG_DEBUG); - $resql=$db->query($sql); + $resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); $i = 0; $param = '&id='.$id; - if ($search_country_id > 0) $param.= '&search_country_id='.$search_country_id; + if ($search_country_id > 0) $param .= '&search_country_id='.$search_country_id; $paramwithsearch = $param; - if ($sortorder) $paramwithsearch.= '&sortorder='.$sortorder; - if ($sortfield) $paramwithsearch.= '&sortfield='.$sortfield; + if ($sortorder) $paramwithsearch .= '&sortorder='.$sortorder; + if ($sortfield) $paramwithsearch .= '&sortfield='.$sortfield; // There is several pages if ($num > $listlimit) { - print ''; - print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num > $listlimit), ''); + print ''; + print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num > $listlimit), ''); print ''; } @@ -570,9 +570,9 @@ if ($id) print ''; foreach ($fieldlist as $field => $value) { - $showfield=1; // By defaut + $showfield = 1; // By defaut - if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') { $showfield=0; } + if ($fieldlist[$field] == 'region_id' || $fieldlist[$field] == 'country_id') { $showfield = 0; } if ($showfield) { @@ -590,17 +590,17 @@ if ($id) } print ''; print ''; - $searchpicto=$form->showFilterAndCheckAddButtons(0); + $searchpicto = $form->showFilterAndCheckAddButtons(0); print $searchpicto; print ''; print ''; // Title of lines print ''; - print getTitleFieldOfList($langs->trans("Pcg_version"), 0, $_SERVER["PHP_SELF"], "pcg_version", ($page?'page='.$page.'&':''), $param, '', $sortfield, $sortorder, ''); - print getTitleFieldOfList($langs->trans("Label"), 0, $_SERVER["PHP_SELF"], "label", ($page?'page='.$page.'&':''), $param, '', $sortfield, $sortorder, ''); - print getTitleFieldOfList($langs->trans("Country"), 0, $_SERVER["PHP_SELF"], "country_code", ($page?'page='.$page.'&':''), $param, '', $sortfield, $sortorder, ''); - print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], "active", ($page?'page='.$page.'&':''), $param, '', $sortfield, $sortorder, 'center '); + print getTitleFieldOfList($langs->trans("Pcg_version"), 0, $_SERVER["PHP_SELF"], "pcg_version", ($page ? 'page='.$page.'&' : ''), $param, '', $sortfield, $sortorder, ''); + print getTitleFieldOfList($langs->trans("Label"), 0, $_SERVER["PHP_SELF"], "label", ($page ? 'page='.$page.'&' : ''), $param, '', $sortfield, $sortorder, ''); + print getTitleFieldOfList($langs->trans("Country"), 0, $_SERVER["PHP_SELF"], "country_code", ($page ? 'page='.$page.'&' : ''), $param, '', $sortfield, $sortorder, ''); + print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], "active", ($page ? 'page='.$page.'&' : ''), $param, '', $sortfield, $sortorder, 'center '); print getTitleFieldOfList(''); print getTitleFieldOfList(''); print ''; @@ -613,81 +613,81 @@ if ($id) $obj = $db->fetch_object($resql); //print_r($obj); print ''; - if ($action == 'edit' && ($rowid == (! empty($obj->rowid)?$obj->rowid:$obj->code))) + if ($action == 'edit' && ($rowid == (!empty($obj->rowid) ? $obj->rowid : $obj->code))) { print ''; print ''; print ''; print ''; - $tmpaction='edit'; - $parameters=array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); - $reshook=$hookmanager->executeHooks('editDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks - $error=$hookmanager->error; $errors=$hookmanager->errors; + $tmpaction = 'edit'; + $parameters = array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $reshook = $hookmanager->executeHooks('editDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks + $error = $hookmanager->error; $errors = $hookmanager->errors; if (empty($reshook)) fieldListAccountModel($fieldlist, $obj, $tabname[$id], 'edit'); - print ' '; + print ' '; print ' '; } else { $tmpaction = 'view'; - $parameters=array('var'=>$var, 'fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); - $reshook=$hookmanager->executeHooks('viewDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks + $parameters = array('var'=>$var, 'fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $reshook = $hookmanager->executeHooks('viewDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks - $error=$hookmanager->error; $errors=$hookmanager->errors; + $error = $hookmanager->error; $errors = $hookmanager->errors; if (empty($reshook)) { foreach ($fieldlist as $field => $value) { - $showfield=1; - $class="left"; - $valuetoshow=$obj->{$fieldlist[$field]}; + $showfield = 1; + $class = "left"; + $valuetoshow = $obj->{$fieldlist[$field]}; if ($value == 'type_template') { - $valuetoshow = isset($elementList[$valuetoshow])?$elementList[$valuetoshow]:$valuetoshow; + $valuetoshow = isset($elementList[$valuetoshow]) ? $elementList[$valuetoshow] : $valuetoshow; } if ($value == 'element') { - $valuetoshow = isset($elementList[$valuetoshow])?$elementList[$valuetoshow]:$valuetoshow; + $valuetoshow = isset($elementList[$valuetoshow]) ? $elementList[$valuetoshow] : $valuetoshow; } elseif ($value == 'source') { - $valuetoshow = isset($sourceList[$valuetoshow])?$sourceList[$valuetoshow]:$valuetoshow; + $valuetoshow = isset($sourceList[$valuetoshow]) ? $sourceList[$valuetoshow] : $valuetoshow; } - elseif ($valuetoshow=='all') { - $valuetoshow=$langs->trans('All'); + elseif ($valuetoshow == 'all') { + $valuetoshow = $langs->trans('All'); } - elseif ($fieldlist[$field]=='country') { + elseif ($fieldlist[$field] == 'country') { if (empty($obj->country_code)) { - $valuetoshow='-'; + $valuetoshow = '-'; } else { - $key=$langs->trans("Country".strtoupper($obj->country_code)); - $valuetoshow=($key != "Country".strtoupper($obj->country_code)?$obj->country_code." - ".$key:$obj->country); + $key = $langs->trans("Country".strtoupper($obj->country_code)); + $valuetoshow = ($key != "Country".strtoupper($obj->country_code) ? $obj->country_code." - ".$key : $obj->country); } } - elseif ($fieldlist[$field]=='country_id') { - $showfield=0; + elseif ($fieldlist[$field] == 'country_id') { + $showfield = 0; } - $class='tddict'; - if ($fieldlist[$field] == 'tracking') $class.=' tdoverflowauto'; + $class = 'tddict'; + if ($fieldlist[$field] == 'tracking') $class .= ' tdoverflowauto'; // Show value for field if ($showfield) print ''.$valuetoshow.''; } } // Can an entry be erased or disabled ? - $iserasable=1;$canbedisabled=1;$canbemodified=1; // true by default + $iserasable = 1; $canbedisabled = 1; $canbemodified = 1; // true by default - $url = $_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&code='.(! empty($obj->code)?urlencode($obj->code):''); + $url = $_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')).'&code='.(!empty($obj->code) ?urlencode($obj->code) : ''); if ($param) $url .= '&'.$param; - $url.='&'; + $url .= '&'; // Active print ''; @@ -737,10 +737,10 @@ $db->close(); */ function fieldListAccountModel($fieldlist, $obj = '', $tabname = '', $context = '') { - global $conf,$langs,$db; + global $conf, $langs, $db; global $form; global $region_id; - global $elementList,$sourceList; + global $elementList, $sourceList; $formadmin = new FormAdmin($db); $formcompany = new FormCompany($db); @@ -758,15 +758,15 @@ function fieldListAccountModel($fieldlist, $obj = '', $tabname = '', $context = continue; } // For state page, we do not show the country input (we link to region, not country) print ''; - $fieldname='country'; - print $form->select_country((! empty($obj->country_code)?$obj->country_code:(! empty($obj->country)?$obj->country:'')), $fieldname, '', 28, 'maxwidth200 maxwidthonsmartphone'); + $fieldname = 'country'; + print $form->select_country((!empty($obj->country_code) ? $obj->country_code : (!empty($obj->country) ? $obj->country : '')), $fieldname, '', 28, 'maxwidth200 maxwidthonsmartphone'); print ''; } elseif ($fieldlist[$field] == 'country_id') { - if (! in_array('country', $fieldlist)) // If there is already a field country, we don't show country_id (avoid duplicate) + if (!in_array('country', $fieldlist)) // If there is already a field country, we don't show country_id (avoid duplicate) { - $country_id = (! empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : 0); + $country_id = (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]} : 0); print ''; print ''; print ''; @@ -776,24 +776,24 @@ function fieldListAccountModel($fieldlist, $obj = '', $tabname = '', $context = if ($fieldlist[$field] == 'type_cdr') print ''; else print ''; if ($fieldlist[$field] == 'type_cdr') { - print $form->selectarray($fieldlist[$field], array(0=>$langs->trans('None'), 1=>$langs->trans('AtEndOfMonth'), 2=>$langs->trans('CurrentNext')), (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'')); + print $form->selectarray($fieldlist[$field], array(0=>$langs->trans('None'), 1=>$langs->trans('AtEndOfMonth'), 2=>$langs->trans('CurrentNext')), (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]}:'')); } else { - print $form->selectyesno($fieldlist[$field], (! empty($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:''), 1); + print $form->selectyesno($fieldlist[$field], (!empty($obj->{$fieldlist[$field]}) ? $obj->{$fieldlist[$field]}:''), 1); } print ''; } elseif ($fieldlist[$field] == 'code' && isset($obj->{$fieldlist[$field]})) { - print ''; + print ''; } else { print ''; - $size=''; $class=''; - if ($fieldlist[$field]=='code') $size='size="8" '; - if ($fieldlist[$field]=='position') $size='size="4" '; - if ($fieldlist[$field]=='libelle') $size='centpercent'; - if ($fieldlist[$field]=='sortorder' || $fieldlist[$field]=='sens' || $fieldlist[$field]=='category_type') $size='size="2" '; - print ''; + $size = ''; $class = ''; + if ($fieldlist[$field] == 'code') $size = 'size="8" '; + if ($fieldlist[$field] == 'position') $size = 'size="4" '; + if ($fieldlist[$field] == 'libelle') $size = 'centpercent'; + if ($fieldlist[$field] == 'sortorder' || $fieldlist[$field] == 'sens' || $fieldlist[$field] == 'category_type') $size = 'size="2" '; + print ''; print ''; } } diff --git a/htdocs/accountancy/admin/card.php b/htdocs/accountancy/admin/card.php index f2bc1907c7c..7449750f958 100644 --- a/htdocs/accountancy/admin/card.php +++ b/htdocs/accountancy/admin/card.php @@ -92,7 +92,6 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) $object->fk_pcg_version = $obj->pcg_version; $object->pcg_type = GETPOST('pcg_type', 'alpha'); - $object->pcg_subtype = GETPOST('pcg_subtype', 'alpha'); $object->account_number = $account_number; $object->account_parent = $account_parent; $object->account_category = GETPOST('account_category', 'alpha'); @@ -158,7 +157,6 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) $object->fk_pcg_version = $obj->pcg_version; $object->pcg_type = GETPOST('pcg_type', 'alpha'); - $object->pcg_subtype = GETPOST('pcg_subtype', 'alpha'); $object->account_number = $account_number; $object->account_parent = $account_parent; $object->account_category = GETPOST('account_category', 'alpha'); @@ -260,12 +258,6 @@ if ($action == 'create') { print ''; print ''; - // Chart of accounts subtype - print ''.$langs->trans("Pcgsubtype").''; - print ''; - print ''; - print ''; - print ''; dol_fiche_end(); @@ -329,12 +321,6 @@ elseif ($id > 0 || $ref) { print ''; print ''; - // Chart of accounts subtype - print ''.$langs->trans("Pcgsubtype").''; - print ''; - print ''; - print ''; - print ''; dol_fiche_end(); @@ -383,10 +369,6 @@ elseif ($id > 0 || $ref) { print ''.$langs->trans("Pcgtype").''; print ''.$object->pcg_type.''; - // Chart of accounts subtype - print ''.$langs->trans("Pcgsubtype").''; - print ''.$object->pcg_subtype.''; - print ''; print ''; diff --git a/htdocs/accountancy/admin/categories_list.php b/htdocs/accountancy/admin/categories_list.php index dbe20bba99d..50cf04a490a 100644 --- a/htdocs/accountancy/admin/categories_list.php +++ b/htdocs/accountancy/admin/categories_list.php @@ -153,7 +153,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) if ($value == 'formula' && empty($_POST['formula'])) continue; if ($value == 'range_account' && empty($_POST['range_account'])) continue; if ($value == 'country' || $value == 'country_id') continue; - if (!isset($_POST[$value]) || $_POST[$value] == '') + if (!GETPOSTISSET($value) || GETPOST($value) == '') { $ok = 0; $fieldnamekey = $listfield[$f]; @@ -677,9 +677,6 @@ if ($id) } if ($fieldlist[$field] == 'pcg_type') { $valuetoshow = $langs->trans("Pcg_type"); - } - if ($fieldlist[$field] == 'pcg_subtype') { - $valuetoshow = $langs->trans("Pcg_subtype"); } if ($fieldlist[$field] == 'type_template') { $valuetoshow = $langs->trans("TypeOfTemplate"); diff --git a/htdocs/accountancy/admin/defaultaccounts.php b/htdocs/accountancy/admin/defaultaccounts.php index 611aa8fc321..43dc3ccea67 100644 --- a/htdocs/accountancy/admin/defaultaccounts.php +++ b/htdocs/accountancy/admin/defaultaccounts.php @@ -1,7 +1,7 @@ * Copyright (C) 2013-2014 Florian Henry - * Copyright (C) 2013-2019 Alexandre Spangaro + * Copyright (C) 2013-2020 Alexandre Spangaro * Copyright (C) 2014-2015 Ari Elbaz (elarifr) * Copyright (C) 2014 Marcos García * Copyright (C) 2014 Juanjo Menent @@ -54,19 +54,27 @@ $list_account_main = array ( $list_account = array (); $list_account[] = '---Product---'; -$list_account[] = 'ACCOUNTING_PRODUCT_BUY_ACCOUNT'; $list_account[] = 'ACCOUNTING_PRODUCT_SOLD_ACCOUNT'; if ($mysoc->isInEEC()) { $list_account[] = 'ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT'; } $list_account[] = 'ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT'; +$list_account[] = 'ACCOUNTING_PRODUCT_BUY_ACCOUNT'; +if ($mysoc->isInEEC()) { + $list_account[] = 'ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT'; +} +$list_account[] = 'ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT'; $list_account[] = '---Service---'; -$list_account[] = 'ACCOUNTING_SERVICE_BUY_ACCOUNT'; $list_account[] = 'ACCOUNTING_SERVICE_SOLD_ACCOUNT'; if ($mysoc->isInEEC()) { $list_account[] = 'ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT'; } $list_account[] = 'ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT'; +$list_account[] = 'ACCOUNTING_SERVICE_BUY_ACCOUNT'; +if ($mysoc->isInEEC()) { + $list_account[] = 'ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT'; +} +$list_account[] = 'ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT'; $list_account[] = '---Other---'; $list_account[] = 'ACCOUNTING_VAT_BUY_ACCOUNT'; $list_account[] = 'ACCOUNTING_VAT_SOLD_ACCOUNT'; @@ -161,6 +169,7 @@ print ''; // Define main accounts for thirdparty print ''; +print ''; foreach ($list_account_main as $key) { print ''; @@ -180,15 +189,6 @@ foreach ($list_account_main as $key) { } -print "
'.$langs->trans("ThirdParties").' | '.$langs->trans("Users").'
\n"; - - -print '
'; - -// Define default accounts - -print ''; - foreach ($list_account as $key) { $reg=array(); if (preg_match('/---(.*)---/', $key, $reg)) { diff --git a/htdocs/accountancy/admin/export.php b/htdocs/accountancy/admin/export.php index edc73688389..b2262c603f9 100644 --- a/htdocs/accountancy/admin/export.php +++ b/htdocs/accountancy/admin/export.php @@ -134,13 +134,13 @@ if ($action == 'update') { $form = new Form($db); -$title = $langs->trans('ConfigAccountingExpert'); +$title = $langs->trans('ExportOptions'); llxHeader('', $title); $linkback = ''; // $linkback = '' . $langs->trans("BackToModuleList") . ''; -print load_fiche_titre($langs->trans('ConfigAccountingExpert'), $linkback, 'accountancy'); +print load_fiche_titre($langs->trans('ExportOptions'), $linkback, 'accountancy'); print "\n".''; print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $button, $result, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit); @@ -228,7 +237,7 @@ if ($action != 'export_csv') print '
'; print ''; - print ''; print_liste_field_titre("AccountAccounting", $_SERVER['PHP_SELF'], "t.numero_compte", "", $param, "", $sortfield, $sortorder); print_liste_field_titre("Label", $_SERVER['PHP_SELF'], "t.label_operation", "", $param, "", $sortfield, $sortorder); + print_liste_field_titre("Opening Balance", $_SERVER['PHP_SELF'], "", $param, "", 'class="right"', $sortfield, $sortorder); print_liste_field_titre("Debit", $_SERVER['PHP_SELF'], "t.debit", "", $param, 'class="right"', $sortfield, $sortorder); print_liste_field_titre("Credit", $_SERVER['PHP_SELF'], "t.credit", "", $param, 'class="right"', $sortfield, $sortorder); print_liste_field_titre("Balance", $_SERVER["PHP_SELF"], "", $param, "", 'class="right"', $sortfield, $sortorder); @@ -257,6 +267,16 @@ if ($action != 'export_csv') $sous_total_credit = 0; $displayed_account = ""; + $sql = "select t.numero_compte, (SUM(t.debit) - SUM(t.credit)) as opening_balance from ".MAIN_DB_PREFIX."accounting_bookkeeping as t where entity in ".$conf->entity; + $sql .= " AND t.doc_date < '".$db->idate($search_date_start)."' GROUP BY t.numero_compte"; + $resql = $db->query($sql); + $nrows = $resql->num_rows; + $opening_balances = array(); + for ($i = 0; $i < $nrows; $i++) { + $arr = $resql->fetch_array(); + $opening_balances["'".$arr['numero_compte']."'"] = $arr['opening_balance']; + } + foreach ($object->lines as $line) { $link = ''; @@ -274,14 +294,14 @@ if ($action != 'export_csv') { // Affiche un Sous-Total par compte comptable if ($displayed_account != "") { - print ''; + print ''; print "\n"; print ''; } // Show first line of a break print ''; - print ''; + print ''; print ''; $displayed_account = $root_account_description; @@ -293,6 +313,7 @@ if ($action != 'export_csv') print ''; print ''; + print ''; print ''; print ''; print ''; @@ -305,11 +326,11 @@ if ($action != 'export_csv') $sous_total_credit += $line->credit; } - print ''; + print ''; print "\n"; print ''; - print ''; + print ''; print "\n"; print ''; diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index bd5b780a0b6..9b6ad2fbbb0 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -29,6 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancyexport.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; @@ -538,6 +539,7 @@ if ($action == 'export_file' && $user->rights->accounting->mouvements->export) { */ $formother = new FormOther($db); +$formfile = new FormFile($db); $title_page = $langs->trans("Bookkeeping"); @@ -914,7 +916,69 @@ while ($i < min($num, $limit)) // Document ref if (!empty($arrayfields['t.doc_ref']['checked'])) { - print ''; + if ($line->doc_type == 'customer_invoice') + { + $langs->loadLangs(array('bills')); + + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; + $objectstatic = new Facture($db); + $objectstatic->fetch($line->fk_doc); + //$modulepart = 'facture'; + + $filename = dol_sanitizeFileName($line->doc_ref); + $filedir = $conf->facture->dir_output.'/'.dol_sanitizeFileName($line->doc_ref); + $urlsource = $_SERVER['PHP_SELF'].'?id='.$objectstatic->id; + $documentlink = $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir); + } + elseif ($line->doc_type == 'supplier_invoice') + { + $langs->loadLangs(array('bills')); + + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; + $objectstatic = new FactureFournisseur($db); + $objectstatic->fetch($line->fk_doc); + //$modulepart = 'invoice_supplier'; + + $filename = dol_sanitizeFileName($line->doc_ref); + $filedir = $conf->fournisseur->facture->dir_output.'/'.get_exdir($line->fk_doc, 2, 0, 0, $objectstatic, $modulepart).dol_sanitizeFileName($line->doc_ref); + $subdir = get_exdir($objectstatic->id, 2, 0, 0, $objectstatic, $modulepart).dol_sanitizeFileName($line->doc_ref); + $documentlink = $formfile->getDocumentsLink($objectstatic->element, $subdir, $filedir); + } + elseif ($line->doc_type == 'expense_report') + { + $langs->loadLangs(array('trips')); + + require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; + $objectstatic = new ExpenseReport($db); + $objectstatic->fetch($line->fk_doc); + //$modulepart = 'expensereport'; + + $filename=dol_sanitizeFileName($line->doc_ref); + $filedir=$conf->expensereport->dir_output . '/' . dol_sanitizeFileName($line->doc_ref); + $urlsource=$_SERVER['PHP_SELF'].'?id='.$objectstatic->id; + $documentlink = $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir); + } + else + { + // Other type + } + + print '\n"; if (!$i) $totalarray['nbfield']++; } diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index d945513f952..847aa3ef47e 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -125,7 +125,7 @@ class AccountancyExport * @param int $type Format id * @return string Format code */ - private static function getFormatCode($type) + public static function getFormatCode($type) { $formatcode = array( self::$EXPORT_TYPE_CONFIGURABLE => 'csv', @@ -239,6 +239,7 @@ class AccountancyExport $filename = 'general_ledger-'.$this->getFormatCode($formatexportset); $type_export = 'general_ledger'; + global $db; // The tpl file use $db include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php'; @@ -935,6 +936,7 @@ class AccountancyExport foreach ($objectLines as $line) { $date_document = dol_print_date($line->doc_date, '%Y%m%d'); $date_creation = dol_print_date($line->date_creation, '%Y%m%d'); + $date_lim_reglement = dol_print_date($line->date_lim_reglement, '%Y%m%d'); // TYPE $type_enregistrement = 'E'; // For write movement @@ -950,7 +952,7 @@ class AccountancyExport // LIBE print $line->label_operation.$separator; // DATH - print $line->date_lim_reglement.$separator; + print $date_lim_reglement.$separator; // CNPI if ($line->doc_type == 'supplier_invoice') { if ($line->montant < 0) { @@ -969,21 +971,19 @@ class AccountancyExport } print $nature_piece.$separator; // RACI - /* - if (! empty($line->subledger_account)) { - if ($line->doc_type == 'supplier_invoice') { - $racine_subledger_account = '40'; - } elseif ($line->doc_type == 'customer_invoice') { - $racine_subledger_account = '41'; - } else { - $nature_piece = ''; - } - print $racine_subledger_account . $separator; - } else { - print $separator; - } - */ - print $separator; // deprecated CPTG & CPTA use instead + // if (! empty($line->subledger_account)) { + // if ($line->doc_type == 'supplier_invoice') { + // $racine_subledger_account = '40'; + // } elseif ($line->doc_type == 'customer_invoice') { + // $racine_subledger_account = '41'; + // } else { + // $racine_subledger_account = ''; + // } + // } else { + $racine_subledger_account = ''; // for records of type E leave this field blank + // } + + print $racine_subledger_account.$separator; // deprecated CPTG & CPTA use instead // MONT print price(abs($line->montant), 0, '', 1, 2).$separator; // CODC diff --git a/htdocs/accountancy/class/accountancysystem.class.php b/htdocs/accountancy/class/accountancysystem.class.php index c59e87dfd93..02d5f0bb183 100644 --- a/htdocs/accountancy/class/accountancysystem.class.php +++ b/htdocs/accountancy/class/accountancysystem.class.php @@ -53,11 +53,6 @@ class AccountancySystem */ public $pcg_type; - /** - * @var string pcg subtype - */ - public $pcg_subtype; - /** * @var string Accountancy System numero */ diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index 1fc953af959..21f7c1cb210 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -90,11 +90,6 @@ class AccountingAccount extends CommonObject */ public $pcg_type; - /** - * @var string pcg subtype - */ - public $pcg_subtype; - /** * @var string account number */ @@ -167,7 +162,7 @@ class AccountingAccount extends CommonObject global $conf; if ($rowid || $account_number) { - $sql = "SELECT a.rowid as rowid, a.datec, a.tms, a.fk_pcg_version, a.pcg_type, a.pcg_subtype, a.account_number, a.account_parent, a.label, a.labelshort, a.fk_accounting_category, a.fk_user_author, a.fk_user_modif, a.active"; + $sql = "SELECT a.rowid as rowid, a.datec, a.tms, a.fk_pcg_version, a.pcg_type, a.account_number, a.account_parent, a.label, a.labelshort, a.fk_accounting_category, a.fk_user_author, a.fk_user_modif, a.active"; $sql .= ", ca.label as category_label"; $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as a"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_accounting_category as ca ON a.fk_accounting_category = ca.rowid"; @@ -198,7 +193,6 @@ class AccountingAccount extends CommonObject $this->tms = $obj->tms; $this->fk_pcg_version = $obj->fk_pcg_version; $this->pcg_type = $obj->pcg_type; - $this->pcg_subtype = $obj->pcg_subtype; $this->account_number = $obj->account_number; $this->account_parent = $obj->account_parent; $this->label = $obj->label; @@ -240,8 +234,6 @@ class AccountingAccount extends CommonObject $this->fk_pcg_version = trim($this->fk_pcg_version); if (isset($this->pcg_type)) $this->pcg_type = trim($this->pcg_type); - if (isset($this->pcg_subtype)) - $this->pcg_subtype = trim($this->pcg_subtype); if (isset($this->account_number)) $this->account_number = trim($this->account_number); if (isset($this->label)) @@ -253,10 +245,6 @@ class AccountingAccount extends CommonObject { $this->pcg_type = 'XXXXXX'; } - if (empty($this->pcg_subtype) || $this->pcg_subtype == '-1') - { - $this->pcg_subtype = 'XXXXXX'; - } // Check parameters // Put here code to add control on parameters values @@ -266,7 +254,6 @@ class AccountingAccount extends CommonObject $sql .= ", entity"; $sql .= ", fk_pcg_version"; $sql .= ", pcg_type"; - $sql .= ", pcg_subtype"; $sql .= ", account_number"; $sql .= ", account_parent"; $sql .= ", label"; @@ -279,7 +266,6 @@ class AccountingAccount extends CommonObject $sql .= ", " . $conf->entity; $sql .= ", " . (empty($this->fk_pcg_version) ? 'NULL' : "'" . $this->db->escape($this->fk_pcg_version) . "'"); $sql .= ", " . (empty($this->pcg_type) ? 'NULL' : "'" . $this->db->escape($this->pcg_type) . "'"); - $sql .= ", " . (empty($this->pcg_subtype) ? 'NULL' : "'" . $this->db->escape($this->pcg_subtype) . "'"); $sql .= ", " . (empty($this->account_number) ? 'NULL' : "'" . $this->db->escape($this->account_number) . "'"); $sql .= ", " . (empty($this->account_parent) ? 0 : (int) $this->account_parent); $sql .= ", " . (empty($this->label) ? "''" : "'" . $this->db->escape($this->label) . "'"); @@ -341,17 +327,12 @@ class AccountingAccount extends CommonObject { $this->pcg_type = 'XXXXXX'; } - if (empty($this->pcg_subtype) || $this->pcg_subtype == '-1') - { - $this->pcg_subtype = 'XXXXXX'; - } $this->db->begin(); $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"); $sql .= " , account_number = '" . $this->db->escape($this->account_number) . "'"; $sql .= " , account_parent = " . (int) $this->account_parent; $sql .= " , label = " . ($this->label ? "'" . $this->db->escape($this->label) . "'" : "''"); diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index ebc4a29793c..2da8e4e24e1 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -926,6 +926,7 @@ class BookKeeping extends CommonObject $sql .= " t.debit,"; $sql .= " t.credit,"; $sql .= " t.lettering_code,"; + $sql .= " t.date_lettering,"; $sql .= " t.montant,"; $sql .= " t.sens,"; $sql .= " t.fk_user_author,"; @@ -934,6 +935,7 @@ class BookKeeping extends CommonObject $sql .= " t.journal_label,"; $sql .= " t.piece_num,"; $sql .= " t.date_creation,"; + $sql .= " t.date_lim_reglement,"; $sql .= " t.tms as date_modification,"; $sql .= " t.date_export"; $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; @@ -1006,12 +1008,14 @@ class BookKeeping extends CommonObject $line->montant = $obj->montant; $line->sens = $obj->sens; $line->lettering_code = $obj->lettering_code; + $line->date_lettering = $obj->date_lettering; $line->fk_user_author = $obj->fk_user_author; $line->import_key = $obj->import_key; $line->code_journal = $obj->code_journal; $line->journal_label = $obj->journal_label; $line->piece_num = $obj->piece_num; $line->date_creation = $this->db->jdate($obj->date_creation); + $line->date_lim_reglement = $this->db->jdate($obj->date_lim_reglement); $line->date_modification = $this->db->jdate($obj->date_modification); $line->date_export = $this->db->jdate($obj->date_export); @@ -1550,7 +1554,7 @@ class BookKeeping extends CommonObject $sql .= " WHERE piece_num = ".$piecenum; $sql .= " AND entity IN (".getEntity('accountancy').")"; - dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG); + dol_syslog(__METHOD__, LOG_DEBUG); $result = $this->db->query($sql); if ($result) { $obj = $this->db->fetch_object($result); @@ -1564,7 +1568,7 @@ class BookKeeping extends CommonObject $this->date_creation = $obj->date_creation; } else { $this->error = "Error ".$this->db->lasterror(); - dol_syslog(get_class($this)."::".__METHOD__.$this->error, LOG_ERR); + dol_syslog(__METHOD__.$this->error, LOG_ERR); return -1; } @@ -1618,7 +1622,7 @@ class BookKeeping extends CommonObject $sql .= " WHERE piece_num = ".$piecenum; $sql .= " AND entity IN (".getEntity('accountancy').")"; - dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG); + dol_syslog(__METHOD__, LOG_DEBUG); $result = $this->db->query($sql); if ($result) { while ($obj = $this->db->fetch_object($result)) { @@ -1650,7 +1654,7 @@ class BookKeeping extends CommonObject } } else { $this->error = "Error ".$this->db->lasterror(); - dol_syslog(get_class($this)."::".__METHOD__.$this->error, LOG_ERR); + dol_syslog(__METHOD__.$this->error, LOG_ERR); return -1; } diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php index 71fce0be43a..ec193b2922a 100644 --- a/htdocs/accountancy/index.php +++ b/htdocs/accountancy/index.php @@ -66,7 +66,7 @@ if ($conf->accounting->enabled) $resultboxes = FormOther::getBoxesArea($user, "27"); // Load $resultboxes (selectboxlist + boxactivated + boxlista + boxlistb) - $helpisexpanded = empty($resultboxes['boxactivated']); // If there is no widget, the tooltip help is expanded by default. + $helpisexpanded = empty($resultboxes['boxactivated']) || (empty($resultboxes['boxlista']) && empty($resultboxes['boxlistb'])); // If there is no widget, the tooltip help is expanded by default. $showtutorial = ''; if (!$helpisexpanded) @@ -222,10 +222,6 @@ if ($conf->accounting->enabled) $boxlist .= '
'; $boxlist .= '
'; - if (!empty($nbworkboardcount)) - { - $boxlist .= $boxwork; - } $boxlist .= $resultboxes['boxlista']; @@ -233,7 +229,6 @@ if ($conf->accounting->enabled) $boxlist .= '
'; - $boxlist .= $boxstat; $boxlist .= $resultboxes['boxlistb']; $boxlist .= '
'; diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index bab853c35b2..d849496d965 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -663,7 +663,7 @@ if (! $error && $action == 'writebookkeeping') { } elseif ($tabtype[$key] == 'payment_various') { $bookkeeping->subledger_account = $k; $bookkeeping->subledger_label = $tabcompany[$key]['name']; - $bookkeeping->numero_compte = $tabpay[$obj->rowid]["account_various"]; + $bookkeeping->numero_compte = $tabpay[$key]["account_various"]; $accountingaccount->fetch(null, $bookkeeping->numero_compte, true); $bookkeeping->label_compte = $accountingaccount->label; @@ -760,7 +760,7 @@ if (! $error && $action == 'writebookkeeping') { } } - if (price2num($totaldebit) != price2num($totalcredit)) + if (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT')) { $error++; $errorforline++; @@ -968,8 +968,8 @@ if (empty($action) || $action == 'view') { journalHead($nom, '', $period, $periodlink, $description, $builddate, $exportlink, array('action' => ''), '', $varlink); - // Test that setup is complete - $sql = 'SELECT COUNT(rowid) as nb FROM '.MAIN_DB_PREFIX.'bank_account WHERE fk_accountancy_journal IS NULL AND clos=0'; + // Test that setup is complete (we are in accounting, so test on entity is always on $conf->entity only, no sharing allowed) + $sql = 'SELECT COUNT(rowid) as nb FROM '.MAIN_DB_PREFIX.'bank_account WHERE entity = '.$conf->entity.' AND fk_accountancy_journal IS NULL AND clos=0'; $resql = $db->query($sql); if ($resql) { diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php index 1fbed52b9e3..29131274c7a 100644 --- a/htdocs/accountancy/journal/expensereportsjournal.php +++ b/htdocs/accountancy/journal/expensereportsjournal.php @@ -355,7 +355,7 @@ if ($action == 'writebookkeeping') { } // Protection against a bug on line before - if (price2num($totaldebit) != price2num($totalcredit)) + if (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT')) { $error++; $errorforline++; diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php index 4d4368ede62..c7fb4c06304 100644 --- a/htdocs/accountancy/journal/purchasesjournal.php +++ b/htdocs/accountancy/journal/purchasesjournal.php @@ -513,7 +513,7 @@ if ($action == 'writebookkeeping') { } // Protection against a bug on lines before - if (!$errorforline && (price2num($totaldebit) != price2num($totalcredit))) + if (! $errorforline && (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT'))) { $error++; $errorforline++; diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index 6043d2bf857..878270d3687 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -471,7 +471,7 @@ if ($action == 'writebookkeeping') { } // Protection against a bug on lines before - if (!$errorforline && (price2num($totaldebit) != price2num($totalcredit))) + if (! $errorforline && (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT'))) { $error++; $errorforline++; diff --git a/htdocs/accountancy/supplier/index.php b/htdocs/accountancy/supplier/index.php index 3bc44698029..07877378ce1 100644 --- a/htdocs/accountancy/supplier/index.php +++ b/htdocs/accountancy/supplier/index.php @@ -1,7 +1,7 @@ * Copyright (C) 2013-2014 Florian Henry - * Copyright (C) 2013-2015 Alexandre Spangaro + * Copyright (C) 2013-2020 Alexandre Spangaro * Copyright (C) 2014 Juanjo Menent * * This program is free software; you can redistribute it and/or modify @@ -119,8 +119,9 @@ if ($action == 'validatehistory') { // Supplier Invoice Lines (must be same request than into page list.php for manual binding) $sql = "SELECT f.rowid as facid, f.ref, f.ref_supplier, f.libelle as invoice_label, f.datef, f.type as ftype,"; $sql .= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,"; - $sql .= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, p.accountancy_code_buy as code_buy, p.tva_tx as tva_tx_prod,"; - $sql .= " aa.rowid as aarowid,"; + $sql .= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type,"; + $sql .= " p.accountancy_code_buy as code_buy, p.accountancy_code_buy_intra as code_buy_intra, p.accountancy_code_buy_export as code_buy_export, p.tva_tx as tva_tx_prod,"; + $sql .= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export,"; $sql .= " co.code as country_code, co.label as country_label,"; $sql .= " s.tva_intra"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; @@ -128,7 +129,9 @@ if ($action == 'validatehistory') { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON co.rowid = s.fk_pays "; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."facture_fourn_det as l ON f.rowid = l.fk_facture_fourn"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = l.fk_product"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON p.accountancy_code_buy = aa.account_number AND aa.active = 1 AND aa.fk_pcg_version = '".$chartaccountcode."' AND aa.entity = ".$conf->entity; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON p.accountancy_code_buy = aa.account_number AND aa.active = 1 AND aa.fk_pcg_version = '".$chartaccountcode."' AND aa.entity = ".$conf->entity; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa2 ON p.accountancy_code_buy_intra = aa2.account_number AND aa2.active = 1 AND aa2.fk_pcg_version = '".$chartaccountcode."' AND aa2.entity = ".$conf->entity; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa3 ON p.accountancy_code_buy_export = aa3.account_number AND aa3.active = 1 AND aa3.fk_pcg_version = '".$chartaccountcode."' AND aa3.entity = ".$conf->entity; $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; $sql .= " AND l.product_type <= 2"; @@ -157,16 +160,12 @@ if ($action == 'validatehistory') { $suggestedaccountingaccountfor = ''; } else { if ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale - //$objp->code_buy_p = $objp->code_buy_intra; - $objp->code_buy_p = $objp->code_buy; - //$objp->aarowid_suggest = $objp->aarowid_intra; - $objp->aarowid_suggest = $objp->aarowid; + $objp->code_buy_p = $objp->code_buy_intra; + $objp->aarowid_suggest = $objp->aarowid_intra; $suggestedaccountingaccountfor = 'eec'; } else { // Foreign sale - //$objp->code_buy_p = $objp->code_buy_export; - $objp->code_buy_p = $objp->code_buy; - //$objp->aarowid_suggest = $objp->aarowid_export; - $objp->aarowid_suggest = $objp->aarowid; + $objp->code_buy_p = $objp->code_buy_export; + $objp->aarowid_suggest = $objp->aarowid_export; $suggestedaccountingaccountfor = 'export'; } } diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index ecd41f2f9da..2c8ad2432a3 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -1,6 +1,6 @@ - * Copyright (C) 2013-2017 Alexandre Spangaro + * Copyright (C) 2013-2020 Alexandre Spangaro * Copyright (C) 2014-2015 Ari Elbaz (elarifr) * Copyright (C) 2013-2014 Florian Henry * Copyright (C) 2014 Juanjo Menent s @@ -211,7 +211,8 @@ if (empty($chartaccountcode)) $sql = "SELECT f.rowid as facid, f.ref, f.ref_supplier, f.libelle as invoice_label, f.datef, f.type as ftype,"; $sql .= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,"; $sql .= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, p.accountancy_code_buy as code_buy, p.tva_tx as tva_tx_prod,"; -$sql .= " aa.rowid as aarowid,"; +$sql .= " p.accountancy_code_buy_intra as code_buy_intra, p.accountancy_code_buy_export as code_buy_export,"; +$sql .= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export,"; $sql .= " co.code as country_code, co.label as country_label,"; $sql .= " s.tva_intra"; $parameters = array(); @@ -222,7 +223,9 @@ $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON co.rowid = s.fk_pays "; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."facture_fourn_det as l ON f.rowid = l.fk_facture_fourn"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = l.fk_product"; -$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON p.accountancy_code_buy = aa.account_number AND aa.active = 1 AND aa.fk_pcg_version = '".$chartaccountcode."' AND aa.entity = ".$conf->entity; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON p.accountancy_code_sell = aa.account_number AND aa.active = 1 AND aa.fk_pcg_version = '".$chartaccountcode."' AND aa.entity = ".$conf->entity; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa2 ON p.accountancy_code_sell_intra = aa2.account_number AND aa2.active = 1 AND aa2.fk_pcg_version = '".$chartaccountcode."' AND aa2.entity = ".$conf->entity; +$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa3 ON p.accountancy_code_sell_export = aa3.account_number AND aa3.active = 1 AND aa3.fk_pcg_version = '".$chartaccountcode."' AND aa3.entity = ".$conf->entity; $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; $sql .= " AND l.product_type <= 2"; // Add search filter like @@ -414,7 +417,6 @@ if ($result) { // issue : if we change product_type value in product DB it should differ from the value stored in facturedet DB ! $objp->code_buy_l = ''; $objp->code_buy_p = ''; - $objp->aarowid_suggest = ''; $product_static->ref = $objp->product_ref; $product_static->id = $objp->product_id; @@ -426,28 +428,67 @@ if ($result) { $facturefourn_static->type = $objp->type; $code_buy_p_notset = ''; - $objp->aarowid_suggest = $objp->aarowid; + $objp->aarowid_suggest = ''; // Will be set later + $isBuyerInEEC = isInEEC($objp); + + $suggestedaccountingaccountbydefaultfor = ''; if ($objp->type_l == 1) { - $objp->code_buy_l = (!empty($conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT : ''); - if ($objp->aarowid == '') - $objp->aarowid_suggest = $aarowid_s; + if ($objp->country_code == $mysoc->country_code || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) + $objp->code_buy_l = (!empty($conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = ''; + } else { + if ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale + $objp->code_buy_l = (!empty($conf->global->ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = 'eec'; + } else { // Foreign sale + $objp->code_buy_l = (!empty($conf->global->ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = 'export'; + } + } } elseif ($objp->type_l == 0) { - $objp->code_buy_l = (!empty($conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT : ''); - if ($objp->aarowid == '') - $objp->aarowid_suggest = $aarowid_p; + if ($objp->country_code == $mysoc->country_code || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) + $objp->code_buy_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = ''; + } else { + if ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale + $objp->code_buy_l = (!empty($conf->global->ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = 'eec'; + } else { + $objp->code_buy_l = (!empty($conf->global->ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT : ''); + $suggestedaccountingaccountbydefaultfor = 'export'; + } + } } - if ($objp->code_buy_l == -1) $objp->code_buy_l = ''; + if ($objp->code_sell_l == -1) $objp->code_sell_l = ''; - if (!empty($objp->code_buy)) { - $objp->code_buy_p = $objp->code_buy; // Code on product + // Search suggested account for product/service + $suggestedaccountingaccountfor = ''; + if (($objp->country_code == $mysoc->country_code) || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) + $objp->code_buy_p = $objp->code_buy; + $objp->aarowid_suggest = $objp->aarowid; + $suggestedaccountingaccountfor = ''; + } else { + if ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale + $objp->code_buy_p = $objp->code_buy_intra; + $objp->aarowid_suggest = $objp->aarowid_intra; + $suggestedaccountingaccountfor = 'eec'; + } else { // Foreign sale + $objp->code_buy_p = $objp->code_buy_export; + $objp->aarowid_suggest = $objp->aarowid_export; + $suggestedaccountingaccountfor = 'export'; + } + } + + if (! empty($objp->code_buy_p)) { + // Value was defined previously } else { $code_buy_p_notset = 'color:orange'; } if (empty($objp->code_buy_l) && empty($objp->code_buy_p)) $code_buy_p_notset = 'color:red'; - // $objp->code_buy_p is now code of product/service // $objp->code_buy_l is now default code of product/service + // $objp->code_buy_p is now code of product/service print '
'; @@ -520,6 +561,21 @@ if ($result) { // Suggested accounting account print ''; @@ -540,6 +596,9 @@ if ($result) { } else { print $db->error(); } +if ($db->type == 'mysqli') { + $db->query("SET SQL_BIG_SELECTS=0"); // Enable MAX_JOIN_SIZE limitation +} // Add code to auto check the box when we select an account print ''; } - - /* - print ''; - print $_POST["formtestfield"]; - print ''; - print $conf->global->FCKEDITOR_TEST; - */ } // End of page diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 3a9eed62fd0..70ea29360c8 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -58,6 +58,13 @@ if (GETPOST('cancel', 'alpha')) $action=''; } +// Convert action set_XXX and del_XXX to set var (this is used when no javascript on for ajax_constantonoff) +$regs = array(); +if (preg_match('/^(set|del)_([A-Z_]+)$/', $action, $regs)) { + if ($regs[1] == 'set') dolibarr_set_const($db, $regs[2], 1, 'chaine', 0, '', $conf->entity); + else dolibarr_del_const($db, $regs[2], $conf->entity); +} + if ($action == 'removebackgroundlogin' && ! empty($conf->global->MAIN_LOGIN_BACKGROUND)) { dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV+1, 'chaine', 0, '', $conf->entity); @@ -81,15 +88,15 @@ if ($action == 'removebackgroundlogin' && ! empty($conf->global->MAIN_LOGIN_BACK if ($action == 'update') { - dolibarr_set_const($db, "MAIN_LANG_DEFAULT", $_POST["MAIN_LANG_DEFAULT"], 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_LANG_DEFAULT", GETPOST("MAIN_LANG_DEFAULT", 'aZ09'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV+1, 'chaine', 0, '', $conf->entity); //dolibarr_set_const($db, "MAIN_MULTILANGS", $_POST["MAIN_MULTILANGS"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_THEME", $_POST["main_theme"], 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_THEME", GETPOST("main_theme", 'aZ09'), 'chaine', 0, '', $conf->entity); - $val=GETPOST('THEME_TOPMENU_DISABLE_IMAGE'); + /*$val=GETPOST('THEME_TOPMENU_DISABLE_IMAGE'); if (! $val) dolibarr_del_const($db, 'THEME_TOPMENU_DISABLE_IMAGE', $conf->entity); - else dolibarr_set_const($db, 'THEME_TOPMENU_DISABLE_IMAGE', GETPOST('THEME_TOPMENU_DISABLE_IMAGE'), 'chaine', 0, '', $conf->entity); + else dolibarr_set_const($db, 'THEME_TOPMENU_DISABLE_IMAGE', GETPOST('THEME_TOPMENU_DISABLE_IMAGE'), 'chaine', 0, '', $conf->entity);*/ $val=(implode(',', (colorStringToArray(GETPOST('THEME_ELDY_BACKBODY'), array())))); if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_BACKBODY', $conf->entity); @@ -141,25 +148,26 @@ if ($action == 'update') if ($val == '') dolibarr_del_const($db, 'THEME_ELDY_USE_CHECKED', $conf->entity); else dolibarr_set_const($db, "THEME_ELDY_USE_CHECKED", $val, 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_SIZE_LISTE_LIMIT", $_POST["main_size_liste_limit"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_SIZE_SHORTLIST_LIMIT", $_POST["main_size_shortliste_limit"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_DISABLE_JAVASCRIPT", $_POST["MAIN_DISABLE_JAVASCRIPT"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_BUTTON_HIDE_UNAUTHORIZED", $_POST["MAIN_BUTTON_HIDE_UNAUTHORIZED"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_START_WEEK", $_POST["MAIN_START_WEEK"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_DEFAULT_WORKING_DAYS", $_POST["MAIN_DEFAULT_WORKING_DAYS"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_DEFAULT_WORKING_HOURS", $_POST["MAIN_DEFAULT_WORKING_HOURS"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_SHOW_LOGO", $_POST["MAIN_SHOW_LOGO"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_FIRSTNAME_NAME_POSITION", $_POST["MAIN_FIRSTNAME_NAME_POSITION"], 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_SIZE_LISTE_LIMIT", GETPOST("main_size_liste_limit", 'int'), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_SIZE_SHORTLIST_LIMIT", GETPOST("main_size_shortliste_limit", 'int'), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_HELPCENTER_DISABLELINK", $_POST["MAIN_HELPCENTER_DISABLELINK"], 'chaine', 0, '', 0); // Param for all entities - dolibarr_set_const($db, "MAIN_MOTD", dol_htmlcleanlastbr($_POST["main_motd"]), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_HOME", dol_htmlcleanlastbr($_POST["main_home"]), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_HELP_DISABLELINK", $_POST["MAIN_HELP_DISABLELINK"], 'chaine', 0, '', 0); // Param for all entities - dolibarr_set_const($db, "MAIN_BUGTRACK_ENABLELINK", $_POST["MAIN_BUGTRACK_ENABLELINK"], 'chaine', 0, '', $conf->entity); + //dolibarr_set_const($db, "MAIN_DISABLE_JAVASCRIPT", GETPOST("MAIN_DISABLE_JAVASCRIPT", 'aZ09'), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_BUTTON_HIDE_UNAUTHORIZED", GETPOST("MAIN_BUTTON_HIDE_UNAUTHORIZED", 'aZ09'), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_START_WEEK", GETPOST("MAIN_START_WEEK", 'int'), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_DEFAULT_WORKING_DAYS", GETPOST("MAIN_DEFAULT_WORKING_DAYS", 'int'), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_DEFAULT_WORKING_HOURS", GETPOST("MAIN_DEFAULT_WORKING_HOURS", 'int'), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_FIRSTNAME_NAME_POSITION", GETPOST("MAIN_FIRSTNAME_NAME_POSITION", 'aZ09'), 'chaine', 0, '', $conf->entity); + + dolibarr_set_const($db, "MAIN_HELPCENTER_DISABLELINK", GETPOST('MAIN_HELPCENTER_DISABLELINK', 'aZ09'), 'chaine', 0, '', 0); // Param for all entities + dolibarr_set_const($db, "MAIN_MOTD", dol_htmlcleanlastbr(GETPOST("main_motd", 'none')), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_HOME", dol_htmlcleanlastbr(GETPOST("main_home", 'none')), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_HELP_DISABLELINK", GETPOST("MAIN_HELP_DISABLELINK", 'aZ09'), 'chaine', 0, '', 0); // Param for all entities + dolibarr_set_const($db, "MAIN_BUGTRACK_ENABLELINK", GETPOST('MAIN_BUGTRACK_ENABLELINK', 'aZ09'), 'chaine', 0, '', $conf->entity); $varforimage='imagebackground'; $dirforimage=$conf->mycompany->dir_output.'/logos/'; if ($_FILES[$varforimage]["tmp_name"]) { + $reg = array(); if (preg_match('/([^\\/:]+)$/i', $_FILES[$varforimage]["name"], $reg)) { $original_file=$reg[1]; @@ -248,8 +256,7 @@ print ''; // Multilingual GUI print ''; print ''; print ''; @@ -268,7 +275,7 @@ print ''; // Disable javascript and ajax print ''; print ''; print ''; diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php index 194475ab32c..fb49c947411 100644 --- a/htdocs/admin/ldap_groups.php +++ b/htdocs/admin/ldap_groups.php @@ -51,14 +51,14 @@ if ($action == 'setvalue' && $user->admin) $error = 0; $db->begin(); - if (!dolibarr_set_const($db, 'LDAP_GROUP_DN', GETPOST("group"), 'chaine', 0, '', $conf->entity)) $error++; - if (!dolibarr_set_const($db, 'LDAP_GROUP_OBJECT_CLASS', GETPOST("objectclass"), 'chaine', 0, '', $conf->entity)) $error++; + if (!dolibarr_set_const($db, 'LDAP_GROUP_DN', GETPOST("group", 'alphanohtml'), 'chaine', 0, '', $conf->entity)) $error++; + if (!dolibarr_set_const($db, 'LDAP_GROUP_OBJECT_CLASS', GETPOST("objectclass", 'alphanohtml'), 'chaine', 0, '', $conf->entity)) $error++; - if (!dolibarr_set_const($db, 'LDAP_GROUP_FIELD_FULLNAME', GETPOST("fieldfullname"), 'chaine', 0, '', $conf->entity)) $error++; - //if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_NAME',$_POST["fieldname"],'chaine',0,'',$conf->entity)) $error++; - if (!dolibarr_set_const($db, 'LDAP_GROUP_FIELD_DESCRIPTION', GETPOST("fielddescription"), 'chaine', 0, '', $conf->entity)) $error++; - if (!dolibarr_set_const($db, 'LDAP_GROUP_FIELD_GROUPMEMBERS', GETPOST("fieldgroupmembers"), 'chaine', 0, '', $conf->entity)) $error++; - if (!dolibarr_set_const($db, 'LDAP_GROUP_FIELD_GROUPID', GETPOST("fieldgroupid"), 'chaine', 0, '', $conf->entity)) $error++; + if (!dolibarr_set_const($db, 'LDAP_GROUP_FIELD_FULLNAME', GETPOST("fieldfullname", 'alphanohtml'), 'chaine', 0, '', $conf->entity)) $error++; + //if (! dolibarr_set_const($db, 'LDAP_GROUP_FIELD_NAME',GETPOST("fieldname", 'alphanohtml'),'chaine',0,'',$conf->entity)) $error++; + if (!dolibarr_set_const($db, 'LDAP_GROUP_FIELD_DESCRIPTION', GETPOST("fielddescription", 'alphanohtml'), 'chaine', 0, '', $conf->entity)) $error++; + if (!dolibarr_set_const($db, 'LDAP_GROUP_FIELD_GROUPMEMBERS', GETPOST("fieldgroupmembers", 'alphanohtml'), 'chaine', 0, '', $conf->entity)) $error++; + if (!dolibarr_set_const($db, 'LDAP_GROUP_FIELD_GROUPID', GETPOST("fieldgroupid", 'alphanohtml'), 'chaine', 0, '', $conf->entity)) $error++; // This one must be after the others $valkey = ''; diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index f74ee2fac7d..abf526544ac 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -134,9 +134,8 @@ $head = email_admin_prepare_head(); // List of sending methods $listofmethods = array(); $listofmethods['mail'] = 'PHP mail function'; -//$listofmethods['simplemail']='Simplemail class'; $listofmethods['smtps'] = 'SMTP/SMTPS socket library'; -$listofmethods['swiftmailer'] = 'Swift Mailer socket library'; +if (version_compare(phpversion(), '7.0', '>=')) $listofmethods['swiftmailer'] = 'Swift Mailer socket library'; if ($action == 'edit') diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index bb5fd72ec29..734bd9c88ce 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -58,6 +58,8 @@ $search_topic = GETPOST('search_topic', 'alpha'); if (!empty($user->socid)) accessforbidden(); +$acts = array(); +$actl = array(); $acts[0] = "activate"; $acts[1] = "disable"; $actl[0] = img_picto($langs->trans("Disabled"), 'switch_off'); @@ -261,28 +263,39 @@ if (empty($reshook)) $i = 0; foreach ($listfieldinsert as $f => $value) { - //var_dump($i.' - '.$listfieldvalue[$i].' - '.$_POST[$listfieldvalue[$i]].' - '.$value); $keycode = $listfieldvalue[$i]; - if ($value == 'label') $_POST[$keycode] = dol_escape_htmltag($_POST[$keycode]); if ($value == 'lang') $keycode = 'langcode'; + if (empty($keycode)) $keycode = $value; + if ($value == 'entity') $_POST[$keycode] = $conf->entity; - if ($i) $sql .= ","; if ($value == 'fk_user' && !($_POST[$keycode] > 0)) $_POST[$keycode] = ''; if ($value == 'private' && !is_numeric($_POST[$keycode])) $_POST[$keycode] = '0'; if ($value == 'position' && !is_numeric($_POST[$keycode])) $_POST[$keycode] = '1'; - if ($_POST[$keycode] == '' && $keycode != 'langcode') $sql .= "null"; // lang must be '' if not defined so the unique key that include lang will work - elseif ($_POST[$keycode] == '0' && $keycode == 'langcode') $sql .= "''"; // lang must be '' if not defined so the unique key that include lang will work - else $sql .= "'".$db->escape($_POST[$keycode])."'"; + //var_dump($keycode.' '.$value); + + if ($i) $sql .= ", "; + if (GETPOST($keycode) == '' && $keycode != 'langcode') $sql .= "null"; // langcode must be '' if not defined so the unique key that include lang will work + elseif (GETPOST($keycode) == '0' && $keycode == 'langcode') $sql .= "''"; // langcode must be '' if not defined so the unique key that include lang will work + elseif ($keycode == 'content') { + $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; + } + elseif (in_array($keycode, array('joinfile', 'private', 'position', 'scale'))) { + $sql .= (int) GETPOST($keycode, 'int'); + } + else { + $sql .= "'".$db->escape(GETPOST($keycode, 'nohtml'))."'"; + } + $i++; } - $sql .= ",1)"; + $sql .= ", 1)"; dol_syslog("actionadd", LOG_DEBUG); $result = $db->query($sql); if ($result) // Add is ok { setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs'); - $_POST = array('id'=>$id); // Clean $_POST array, we keep only + $_POST = array('id'=>$id); // Clean $_POST array, we keep only id } else { @@ -308,6 +321,7 @@ if (empty($reshook)) { $keycode = $listfieldvalue[$i]; if ($field == 'lang') $keycode = 'langcode'; + if (empty($keycode)) $keycode = $field; if ($field == 'fk_user' && !($_POST['fk_user'] > 0)) $_POST['fk_user'] = ''; if ($field == 'topic') $_POST['topic'] = $_POST['topic-'.$rowid]; @@ -315,15 +329,22 @@ if (empty($reshook)) if ($field == 'content') $_POST['content'] = $_POST['content-'.$rowid]; if ($field == 'content_lines') $_POST['content_lines'] = $_POST['content_lines-'.$rowid]; if ($field == 'entity') $_POST[$keycode] = $conf->entity; - if ($i) $sql .= ","; + + if ($i) $sql .= ", "; $sql .= $field."="; - //print $keycode.' - '.$_POST[$keycode].'
'; - if ($_POST[$keycode] == '' || ($keycode != 'langcode' && $keycode != 'position' && $keycode != 'private' && empty($_POST[$keycode]))) $sql .= "null"; // lang must be '' if not defined so the unique key that include lang will work - elseif ($_POST[$keycode] == '0' && $keycode == 'langcode') $sql .= "''"; // lang must be '' if not defined so the unique key that include lang will work - elseif ($keycode == 'private') $sql .= ((int) $_POST[$keycode]); // private must be 0 or 1 - elseif ($keycode == 'position') $sql .= ((int) $_POST[$keycode]); - else $sql .= "'".$db->escape($_POST[$keycode])."'"; + if (GETPOST($keycode) == '' || ($keycode != 'langcode' && $keycode != 'position' && $keycode != 'private' && !GETPOST($keycode))) $sql .= "null"; // langcode,... must be '' if not defined so the unique key that include lang will work + elseif (GETPOST($keycode) == '0' && $keycode == 'langcode') $sql .= "''"; // langcode must be '' if not defined so the unique key that include lang will work + elseif ($keycode == 'content') { + $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; + } + elseif (in_array($keycode, array('joinfile', 'private', 'position', 'scale'))) { + $sql .= (int) GETPOST($keycode, 'int'); + } + else { + $sql .= "'".$db->escape(GETPOST($keycode, 'nohtml'))."'"; + } + $i++; } $sql .= " WHERE ".$rowidcol." = '".$rowid."'"; diff --git a/htdocs/admin/menus/edit.php b/htdocs/admin/menus/edit.php index f82c423d438..ef58c1042d4 100644 --- a/htdocs/admin/menus/edit.php +++ b/htdocs/admin/menus/edit.php @@ -31,6 +31,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/menubase.class.php'; // Load translation files required by the page $langs->loadLangs(array("other", "admin")); +$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button + if (!$user->admin) accessforbidden(); $dirstandard = array(); @@ -64,12 +66,12 @@ if (GETPOST("menu_handler")) $menu_handler = GETPOST("menu_handler"); if ($action == 'update') { - if (!$_POST['cancel']) + if (!$cancel) { $leftmenu = ''; $mainmenu = ''; - if (!empty($_POST['menuIdParent']) && !is_numeric($_POST['menuIdParent'])) + if (GETPOST('menuIdParent', 'alpha') && !is_numeric(GETPOST('menuIdParent', 'alpha'))) { - $tmp = explode('&', $_POST['menuIdParent']); + $tmp = explode('&', GETPOST('menuIdParent', 'alpha')); foreach ($tmp as $s) { if (preg_match('/fk_mainmenu=/', $s)) @@ -138,7 +140,7 @@ if ($action == 'update') if ($action == 'add') { - if ($_POST['cancel']) + if ($cancel) { header("Location: ".DOL_URL_ROOT."/admin/menus/index.php?menu_handler=".$menu_handler); exit; diff --git a/htdocs/admin/oauthlogintokens.php b/htdocs/admin/oauthlogintokens.php index ca75eee69ef..d8c65f9a2c5 100644 --- a/htdocs/admin/oauthlogintokens.php +++ b/htdocs/admin/oauthlogintokens.php @@ -24,7 +24,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // This define $list require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; use OAuth\Common\Storage\DoliStorage; @@ -59,9 +59,18 @@ if ($action == 'setconst' && $user->admin) { $error = 0; $db->begin(); - foreach ($_POST['setupdriver'] as $setupconst) { + + $setupconstarray = GETPOST('setupdriver', 'array'); + + foreach ($setupconstarray as $setupconst) { //print '
'.print_r($setupconst, true).'
'; - $result = dolibarr_set_const($db, $setupconst['varname'], $setupconst['value'], 'chaine', 0, '', $conf->entity); + + $constname = dol_escape_htmltag($setupconst['varname']); + $constvalue = dol_escape_htmltag($setupconst['value']); + $consttype = dol_escape_htmltag($setupconst['type']); + $constnote = dol_escape_htmltag($setupconst['note']); + + $result = dolibarr_set_const($db, $constname, $constvalue, $consttype, 0, $constnote, $conf->entity); if (!$result > 0) $error++; } @@ -119,6 +128,9 @@ $head = oauthadmin_prepare_head(); dol_fiche_head($head, 'tokengeneration', '', -1, 'technic'); +if (GETPOST('error')) { + setEventMessages(GETPOST('error'), null, 'errors'); +} if ($mode == 'setup' && $user->admin) { @@ -135,17 +147,21 @@ if ($mode == 'setup' && $user->admin) if ($key[0] == 'OAUTH_GITHUB_NAME') { $OAUTH_SERVICENAME = 'GitHub'; - $state='user,public_repo'; // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service) - $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?state='.$state.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service). + // We pass this param list in to 'state' because we need it before and after the redirect. + $shortscope = 'user,public_repo'; + $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltocheckperms = 'https://github.com/settings/applications/'; } elseif ($key[0] == 'OAUTH_GOOGLE_NAME') { $OAUTH_SERVICENAME = 'Google'; - $state='userinfo_email,userinfo_profile,cloud_print'; // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service) - //$state.=',gmail_full'; - $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?state='.$state.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service). + // We pass this param list in to 'state' because we need it before and after the redirect. + $shortscope = 'userinfo_email,userinfo_profile,cloud_print'; + //$scope.=',gmail_full'; + $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltocheckperms = 'https://security.google.com/settings/security/permissions'; } diff --git a/htdocs/admin/pdf.php b/htdocs/admin/pdf.php index df62acee3a4..496a32923f7 100644 --- a/htdocs/admin/pdf.php +++ b/htdocs/admin/pdf.php @@ -58,12 +58,13 @@ if ($action == 'update') dolibarr_set_const($db, "MAIN_PDF_MARGIN_TOP", $_POST["MAIN_PDF_MARGIN_TOP"], 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_PDF_MARGIN_BOTTOM", $_POST["MAIN_PDF_MARGIN_BOTTOM"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PROFID1_IN_ADDRESS", $_POST["MAIN_PROFID1_IN_ADDRESS"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PROFID2_IN_ADDRESS", $_POST["MAIN_PROFID2_IN_ADDRESS"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PROFID3_IN_ADDRESS", $_POST["MAIN_PROFID3_IN_ADDRESS"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PROFID4_IN_ADDRESS", $_POST["MAIN_PROFID4_IN_ADDRESS"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PROFID5_IN_ADDRESS", $_POST["MAIN_PROFID5_IN_ADDRESS"], 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_PROFID6_IN_ADDRESS", $_POST["MAIN_PROFID6_IN_ADDRESS"], 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_PROFID1_IN_ADDRESS", GETPOST("MAIN_PROFID1_IN_ADDRESS", "nohtml"), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_PROFID2_IN_ADDRESS", GETPOST("MAIN_PROFID2_IN_ADDRESS", "nohtml"), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_PROFID3_IN_ADDRESS", GETPOST("MAIN_PROFID3_IN_ADDRESS", "nohtml"), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_PROFID4_IN_ADDRESS", GETPOST("MAIN_PROFID4_IN_ADDRESS", "nohtml"), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_PROFID5_IN_ADDRESS", GETPOST("MAIN_PROFID5_IN_ADDRESS", "nohtml"), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_PROFID6_IN_ADDRESS", GETPOST("MAIN_PROFID6_IN_ADDRESS", "nohtml"), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT", $_POST["MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT"], 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_TVAINTRA_NOT_IN_ADDRESS", $_POST["MAIN_TVAINTRA_NOT_IN_ADDRESS"], 'chaine', 0, '', $conf->entity); @@ -79,6 +80,9 @@ if ($action == 'update') dolibarr_set_const($db, "MAIN_PDF_MAIN_HIDE_SECOND_TAX", $_POST["MAIN_PDF_MAIN_HIDE_SECOND_TAX"], 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_PDF_MAIN_HIDE_THIRD_TAX", $_POST["MAIN_PDF_MAIN_HIDE_THIRD_TAX"], 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "PDF_USE_ALSO_LANGUAGE_CODE", GETPOST('PDF_USE_ALSO_LANGUAGE_CODE', 'alpha'), 'chaine', 0, '', $conf->entity); + + header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup"); exit; } @@ -295,6 +299,16 @@ print 'selectarray('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', $arraydetailsforpdffoot, $conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS); print ''; +print ''; + + print '
'; + print ''; print $langs->trans('From'); print $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', 1, array(), 1, 1, ''); print ' '; @@ -245,6 +254,7 @@ if ($action != 'export_csv') print '
' . $langs->trans("SubTotal") . ':' . price($sous_total_debit) . '' . price($sous_total_credit) . '' . price(price2num($sous_total_credit - $sous_total_debit)) . '
'.$langs->trans("SubTotal").':'.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_credit - $sous_total_debit)).' 
' . $line->numero_compte . ($root_account_description ? ' - ' . $root_account_description : '') . ''.$line->numero_compte.($root_account_description ? ' - '.$root_account_description : '').'
'.length_accountg($line->numero_compte).''.$description.''.price($opening_balances["'".$line->numero_compte."'"]).''.price($line->debit).''.price($line->credit).''.price($line->debit - $line->credit).'
'.$langs->trans("SubTotal").':'.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_debit - $sous_total_credit)).'
'.$langs->trans("SubTotal").':'.price($sous_total_debit).''.price($sous_total_credit).''.price(price2num($sous_total_debit - $sous_total_credit)).' 
'.$langs->trans("AccountBalance").':'.price($total_debit).''.price($total_credit).''.price(price2num($total_debit - $total_credit)).'
'.$langs->trans("AccountBalance").':'.price($total_debit).''.price($total_credit).''.price(price2num($total_debit - $total_credit)).' 
'.$line->doc_ref.''; + + print ''; + // Picto + Ref + print '
'; + + if($line->doc_type == 'customer_invoice' || $line->doc_type == 'supplier_invoice' || $line->doc_type == 'expense_report') + { + print $objectstatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1); + print $documentlink; + } else { + print $line->doc_ref; + } + print '
'; + + print "
'; $suggestedid = $objp->aarowid_suggest; + if (empty($suggestedid) && empty($objp->code_buy_p) && ! empty($objp->code_buy_l) && empty($conf->global->ACCOUNTANCY_DO_NOT_AUTOFILL_ACCOUNT_WITH_GENERIC)) + { + if (empty($accountingaccount_codetotid_cache[$objp->code_buy_l])) + { + $tmpaccount = new AccountingAccount($db); + $tmpaccount->fetch(0, $objp->code_buy_l, 1); + if ($tmpaccount->id > 0) { + $suggestedid = $tmpaccount->id; + } + $accountingaccount_codetotid_cache[$objp->code_buy_l] = $tmpaccount->id; + } + else { + $suggestedid = $accountingaccount_codetotid_cache[$objp->code_buy_l]; + } + } print $formaccounting->select_account($suggestedid, 'codeventil'.$objp->rowid, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone'); print '
'.$langs->trans("EnableMultilangInterface").''; -//print $form->selectyesno('MAIN_MULTILANGS', $conf->global->MAIN_MULTILANGS, 1); -print ajax_constantonoff('MAIN_MULTILANGS'); +print ajax_constantonoff("MAIN_MULTILANGS", array(), $conf->entity, 0, 0, 1, 0); print ' 
'.$langs->trans("DisableJavascript").''; -print $form->selectyesno('MAIN_DISABLE_JAVASCRIPT', isset($conf->global->MAIN_DISABLE_JAVASCRIPT)?$conf->global->MAIN_DISABLE_JAVASCRIPT:0, 1); +print ajax_constantonoff("MAIN_DISABLE_JAVASCRIPT", array(), $conf->entity, 0, 0, 1, 0); print ' 
'.$langs->trans("ShowDetailsInPDFPageFoot").'
'.$langs->trans("PDF_USE_ALSO_LANGUAGE_CODE").''; +//if (! empty($conf->global->MAIN_MULTILANGS)) +//{ +print $formadmin->select_language(GETPOSTISSET('PDF_USE_ALSO_LANGUAGE_CODE') ? GETPOST('PDF_USE_ALSO_LANGUAGE_CODE') : $conf->global->PDF_USE_ALSO_LANGUAGE_CODE, 'PDF_USE_ALSO_LANGUAGE_CODE', 0, null, 1); +//} else { +// print ''.$langs->trans("MultiLangNotEnabled").''; +//} +print '
'; print ''; diff --git a/htdocs/admin/perms.php b/htdocs/admin/perms.php index 1f811c325dd..b11f909bd37 100644 --- a/htdocs/admin/perms.php +++ b/htdocs/admin/perms.php @@ -35,6 +35,8 @@ $action = GETPOST('action', 'aZ09'); if (!$user->admin) accessforbidden(); +$entity=$conf->entity; + /* * Actions @@ -70,14 +72,12 @@ print ''.$langs->trans("DefaultRightsDesc")." ".$lan $db->begin(); -// Charge les modules soumis a permissions +// Search all modules with permission and reload permissions def. $modules = array(); $modulesdir = dolGetModulesDirs(); foreach ($modulesdir as $dir) { - // Load modules attributes in arrays (name, numero, orders) from dir directory - //print $dir."\n
"; $handle = @opendir(dol_osencode($dir)); if (is_resource($handle)) { @@ -102,7 +102,7 @@ foreach ($modulesdir as $dir) // Load all permissions if ($objMod->rights_class) { - $ret = $objMod->insert_permissions(0); + $ret = $objMod->insert_permissions(0, $entity); $modules[$objMod->rights_class] = $objMod; //print "modules[".$objMod->rights_class."]=$objMod;"; } @@ -122,35 +122,58 @@ dol_fiche_head($head, 'default', $langs->trans("Security"), -1); // Show warning about external users print info_admin(showModulesExludedForExternal($modules)).'
'."\n"; +print "\n"; print '
'; print ''; -// Show permissions lines -$sql = "SELECT r.id, r.libelle, r.module, r.perms, r.subperms, r.bydefault"; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''."\n"; + +//print "xx".$conf->global->MAIN_USE_ADVANCED_PERMS; +$sql = "SELECT r.id, r.libelle as label, r.module, r.module_position, r.perms, r.subperms, r.bydefault"; $sql .= " FROM ".MAIN_DB_PREFIX."rights_def as r"; $sql .= " WHERE r.libelle NOT LIKE 'tou%'"; // On ignore droits "tous" -$sql .= " AND entity = ".$conf->entity; +$sql .= " AND r.entity = ".$entity; if (empty($conf->global->MAIN_USE_ADVANCED_PERMS)) $sql .= " AND r.perms NOT LIKE '%_advance'"; // Hide advanced perms if option is not enabled -$sql .= " ORDER BY r.module, r.id"; +$sql .= " ORDER BY r.family_position, r.module_position, r.module, r.id"; $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); $i = 0; - $oldmod = ""; + $oldmod = ''; while ($i < $num) { $obj = $db->fetch_object($result); - // Si la ligne correspond a un module qui n'existe plus (absent de includes/module), on l'ignore - if (!$modules[$obj->module]) + // If line is for a module that doe snot existe anymore (absent of includes/module), we ignore it + if (empty($modules[$obj->module])) { $i++; continue; } + // Save field module_position in database if value is still zero + if (empty($obj->module_position)) + { + if (is_object($modules[$obj->module]) && ($modules[$obj->module]->module_position > 0)) + { + // TODO Define familyposition + $family = $modules[$obj->module]->family_position; + $familyposition = 0; + $sqlupdate = 'UPDATE '.MAIN_DB_PREFIX."rights_def SET module_position = ".$modules[$obj->module]->module_position.","; + $sqlupdate.= " family_position = ".$familyposition; + $sqlupdate.= " WHERE module_position = 0 AND module = '".$db->escape($obj->module)."'"; + $db->query($sqlupdate); + } + } + // Check if permission we found is inside a module definition. If not, we discard it. $found = false; foreach ($modules[$obj->module]->rights as $key => $val) @@ -169,49 +192,65 @@ if ($result) } // Break found, it's a new module to catch - if ($oldmod <> $obj->module) + if (isset($obj->module) && ($oldmod <> $obj->module)) { $oldmod = $obj->module; + + // Break detected, we get objMod $objMod = $modules[$obj->module]; $picto = ($objMod->picto ? $objMod->picto : 'generic'); - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; + // Show break line + print ''; + print ''; + print ''; + print ''; + print ''; + print ''."\n"; } + $perm_libelle = ($conf->global->MAIN_USE_ADVANCED_PERMS && ($langs->trans("PermissionAdvanced".$obj->id) != ("PermissionAdvanced".$obj->id)) ? $langs->trans("PermissionAdvanced".$obj->id) : (($langs->trans("Permission".$obj->id) != ("Permission".$obj->id)) ? $langs->trans("Permission".$obj->id) : $obj->label)); print ''; - print ''; - $perm_libelle = ($conf->global->MAIN_USE_ADVANCED_PERMS && ($langs->trans("PermissionAdvanced".$obj->id) != ("PermissionAdvanced".$obj->id)) ? $langs->trans("PermissionAdvanced".$obj->id) : (($langs->trans("Permission".$obj->id) != ("Permission".$obj->id)) ? $langs->trans("Permission".$obj->id) : $obj->libelle)); + // Tick + if ($obj->bydefault == 1) + { + print ''; + print ''; + } + else + { + print ''; + print ''; + } + + // Permission and tick print ''; - print ''."\n"; - print ''; $i++; } } - +else dol_print_error($db); print '
'.$langs->trans("Module").' '.$langs->trans("Default").''.$langs->trans("Permissions").'
'.$langs->trans("Module").''.$langs->trans("Permission").''.$langs->trans("Default").' 
'; + print img_object('', $picto, 'class="pictoobjectwidth"').' '.$objMod->getName(); + print ''; + print '   
'; - print img_object('', $picto, 'class="pictoobjectwidth"').' '.$objMod->getName(); - print ' '; + + // Picto and label of module + print ''; + //print img_object('', $picto, 'class="pictoobjectwidth"').' '.$objMod->getName(); + //print ' '; print ''; + print ''.img_edit_remove().''; + print ''; + print img_picto($langs->trans("Active"), 'tick'); + print ''; + print ''.img_edit_add().''; + print ''; + print ' '; + print ''.$perm_libelle.''; - if ($obj->bydefault == 1) - { - print img_picto($langs->trans("Active"), 'tick'); - print ''; - print ''.img_edit_remove().''; - } - else - { - print ' '; - print ''; - print ''.img_edit_add().''; - } + print '
'; print '
'; diff --git a/htdocs/admin/reception_setup.php b/htdocs/admin/reception_setup.php index bd126d98341..312038d3fcc 100644 --- a/htdocs/admin/reception_setup.php +++ b/htdocs/admin/reception_setup.php @@ -234,7 +234,7 @@ foreach ($dirmodels as $reldir) { $file = substr($file, 0, dol_strlen($file) - 4); - require_once $dir.$file.'.php'; + require_once $dir.'/'.$file.'.php'; $module = new $file; diff --git a/htdocs/admin/security_other.php b/htdocs/admin/security_other.php index e85853541de..f0ad4352b60 100644 --- a/htdocs/admin/security_other.php +++ b/htdocs/admin/security_other.php @@ -29,12 +29,12 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; // Load translation files required by the page -$langs->loadLangs(array("users","admin","other")); +$langs->loadLangs(array("users", "admin", "other")); -if (! $user->admin) +if (!$user->admin) accessforbidden(); -$action=GETPOST('action', 'alpha'); +$action = GETPOST('action', 'alpha'); @@ -44,8 +44,8 @@ $action=GETPOST('action', 'alpha'); if (preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) { - $code=$reg[1]; - $value=(GETPOST($code, 'alpha') ? GETPOST($code, 'alpha') : 1); + $code = $reg[1]; + $value = (GETPOST($code, 'alpha') ? GETPOST($code, 'alpha') : 1); if (dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity) > 0) { Header("Location: ".$_SERVER["PHP_SELF"]); @@ -56,7 +56,7 @@ if (preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) dol_print_error($db); } } elseif (preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) { - $code=$reg[1]; + $code = $reg[1]; if (dolibarr_del_const($db, $code, $conf->entity) > 0) { Header("Location: ".$_SERVER["PHP_SELF"]); @@ -70,8 +70,8 @@ if (preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) elseif ($action == 'updateform') { - $res1=dolibarr_set_const($db, "MAIN_APPLICATION_TITLE", $_POST["MAIN_APPLICATION_TITLE"], 'chaine', 0, '', $conf->entity); - $res2=dolibarr_set_const($db, "MAIN_SESSION_TIMEOUT", $_POST["MAIN_SESSION_TIMEOUT"], 'chaine', 0, '', $conf->entity); + $res1 = dolibarr_set_const($db, "MAIN_APPLICATION_TITLE", GETPOST("MAIN_APPLICATION_TITLE", 'alphanohtml'), 'chaine', 0, '', $conf->entity); + $res2 = dolibarr_set_const($db, "MAIN_SESSION_TIMEOUT", GETPOST("MAIN_SESSION_TIMEOUT", 'alphanohtml'), 'chaine', 0, '', $conf->entity); if ($res1 && $res2) setEventMessages($langs->trans("RecordModifiedSuccessfully"), null, 'mesgs'); } @@ -83,7 +83,7 @@ elseif ($action == 'updateform') $form = new Form($db); -$wikihelp='EN:Setup_Security|FR:Paramétrage_Sécurité|ES:Configuración_Seguridad'; +$wikihelp = 'EN:Setup_Security|FR:Paramétrage_Sécurité|ES:Configuración_Seguridad'; llxHeader('', $langs->trans("Miscellaneous"), $wikihelp); print load_fiche_titre($langs->trans("SecuritySetup"), '', 'title_setup'); @@ -97,7 +97,7 @@ print ''; print ''; print ''; -$head=security_prepare_head(); +$head = security_prepare_head(); dol_fiche_head($head, 'misc', $langs->trans("Security"), -1); @@ -115,7 +115,7 @@ print ''.$langs->trans("UseCaptchaCode").''; print ''; if (function_exists("imagecreatefrompng")) { - if (! empty($conf->use_javascript_ajax)) + if (!empty($conf->use_javascript_ajax)) { print ajax_constantonoff('MAIN_SECURITY_ENABLECAPTCHA'); } @@ -142,7 +142,7 @@ print ''; print ''; print ''.$langs->trans("UseAdvancedPerms").''; print ''; -if (! empty($conf->use_javascript_ajax)) +if (!empty($conf->use_javascript_ajax)) { print ajax_constantonoff('MAIN_USE_ADVANCED_PERMS'); } @@ -173,8 +173,8 @@ print ''.$langs->trans("Value").''; print "\n"; -$sessiontimeout=ini_get("session.gc_maxlifetime"); -if (empty($conf->global->MAIN_SESSION_TIMEOUT)) $conf->global->MAIN_SESSION_TIMEOUT=$sessiontimeout; +$sessiontimeout = ini_get("session.gc_maxlifetime"); +if (empty($conf->global->MAIN_SESSION_TIMEOUT)) $conf->global->MAIN_SESSION_TIMEOUT = $sessiontimeout; print ''; print ''.$langs->trans("SessionTimeOut").''; print $form->textwithpicto('', $langs->trans("SessionExplanation", ini_get("session.gc_probability"), ini_get("session.gc_divisor"))); @@ -185,8 +185,8 @@ print ''; print ''; -$sessiontimeout=ini_get("session.gc_maxlifetime"); -if (empty($conf->global->MAIN_APPLICATION_TITLE)) $conf->global->MAIN_APPLICATION_TITLE=""; +$sessiontimeout = ini_get("session.gc_maxlifetime"); +if (empty($conf->global->MAIN_APPLICATION_TITLE)) $conf->global->MAIN_APPLICATION_TITLE = ""; print ''; print ''.$langs->trans("MAIN_APPLICATION_TITLE").''; print ''; diff --git a/htdocs/admin/sms.php b/htdocs/admin/sms.php index b725a2e50ae..4a70104158b 100644 --- a/htdocs/admin/sms.php +++ b/htdocs/admin/sms.php @@ -28,6 +28,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; // Load translation files required by the page $langs->loadLangs(array("companies", "admin", "products", "sms", "other", "errors")); +$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button + if (!$user->admin) accessforbidden(); @@ -46,14 +48,13 @@ $action = GETPOST('action', 'aZ09'); * Actions */ -if ($action == 'update' && empty($_POST["cancel"])) +if ($action == 'update' && !$cancel) { - dolibarr_set_const($db, "MAIN_DISABLE_ALL_SMS", $_POST["MAIN_DISABLE_ALL_SMS"], 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_DISABLE_ALL_SMS", GETPOST("MAIN_DISABLE_ALL_SMS", 'alphanohtml'), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_SMS_SENDMODE", $_POST["MAIN_SMS_SENDMODE"], 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_SMS_SENDMODE", GETPOST("MAIN_SMS_SENDMODE", 'alphahtml'), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_MAIL_SMS_FROM", $_POST["MAIN_MAIL_SMS_FROM"], 'chaine', 0, '', $conf->entity); - //dolibarr_set_const($db, "MAIN_MAIL_AUTOCOPY_TO", $_POST["MAIN_MAIL_AUTOCOPY_TO"], 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_MAIL_SMS_FROM", GETPOST("MAIN_MAIL_SMS_FROM", 'alphanohtml'), 'chaine', 0, '', $conf->entity); header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup"); exit; @@ -68,15 +69,15 @@ if ($action == 'send' && !$_POST['cancel']) $error = 0; $smsfrom = ''; - if (!empty($_POST["fromsms"])) $smsfrom = GETPOST("fromsms"); - if (empty($smsfrom)) $smsfrom = GETPOST("fromname"); - $sendto = GETPOST("sendto"); - $body = GETPOST('message'); - $deliveryreceipt = GETPOST("deliveryreceipt"); - $deferred = GETPOST('deferred'); - $priority = GETPOST('priority'); - $class = GETPOST('class'); - $errors_to = GETPOST("errorstosms"); + if (!empty($_POST["fromsms"])) $smsfrom = GETPOST("fromsms", 'alphanohtml'); + if (empty($smsfrom)) $smsfrom = GETPOST("fromname", 'alphanohtml'); + $sendto = GETPOST("sendto", 'alphanohtml'); + $body = GETPOST('message', 'alphanohtml'); + $deliveryreceipt = GETPOST("deliveryreceipt", 'alphanohtml'); + $deferred = GETPOST('deferred', 'alphanohtml'); + $priority = GETPOST('priority', 'alphanohtml'); + $class = GETPOST('class', 'alphanohtml'); + $errors_to = GETPOST("errorstosms", 'alphanohtml'); // Create form object include_once DOL_DOCUMENT_ROOT.'/core/class/html.formsms.class.php'; diff --git a/htdocs/admin/spip.php b/htdocs/admin/spip.php index 5b5bf692e22..2ed43e97efd 100644 --- a/htdocs/admin/spip.php +++ b/htdocs/admin/spip.php @@ -35,10 +35,10 @@ require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; // Load translation files required by the page $langs->loadLangs(array("admin", "members", "mailmanspip")); -if (! $user->admin) accessforbidden(); +if (!$user->admin) accessforbidden(); -$type=array('yesno','texte','chaine'); +$type = array('yesno', 'texte', 'chaine'); $action = GETPOST('action', 'aZ09'); @@ -50,25 +50,27 @@ $action = GETPOST('action', 'aZ09'); // Action mise a jour ou ajout d'une constante if ($action == 'update' || $action == 'add') { - $constname=GETPOST("constname"); - $constvalue=GETPOST("constvalue"); + $constnamearray = GETPOST("constname", 'array'); + $constvaluearray = GETPOST("constvalue", 'array'); + $consttypearray = GETPOST("consttype", 'array'); + $constnotearray = GETPOST("constnote", 'array'); // Action mise a jour ou ajout d'une constante if ($action == 'update' || $action == 'add') { - foreach($_POST['constname'] as $key => $val) + foreach ($constnamearray as $key => $val) { - $constname=$_POST["constname"][$key]; - $constvalue=$_POST["constvalue"][$key]; - $consttype=$_POST["consttype"][$key]; - $constnote=$_POST["constnote"][$key]; + $constname = dol_escape_htmltag($constnamearray[$key]); + $constvalue = dol_escape_htmltag($constvaluearray[$key]); + $consttype = dol_escape_htmltag($consttypearray[$key]); + $constnote = dol_escape_htmltag($constnotearray[$key]); - $res=dolibarr_set_const($db, $constname, $constvalue, $type[$consttype], 0, $constnote, $conf->entity); + $res = dolibarr_set_const($db, $constname, $constvalue, $type[$consttype], 0, $constnote, $conf->entity); - if (! $res > 0) $error++; + if (!$res > 0) $error++; } - if (! $error) + if (!$error) { setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); } @@ -82,7 +84,7 @@ if ($action == 'update' || $action == 'add') // Action activation d'un sous module du module adherent if ($action == 'set') { - $result=dolibarr_set_const($db, $_GET["name"], $_GET["value"], '', 0, '', $conf->entity); + $result = dolibarr_set_const($db, $_GET["name"], $_GET["value"], '', 0, '', $conf->entity); if ($result < 0) { dol_print_error($db); @@ -92,7 +94,7 @@ if ($action == 'set') // Action desactivation d'un sous module du module adherent if ($action == 'unset') { - $result=dolibarr_del_const($db, $_GET["name"], $conf->entity); + $result = dolibarr_del_const($db, $_GET["name"], $conf->entity); if ($result < 0) { dol_print_error($db); @@ -105,12 +107,12 @@ if ($action == 'unset') * View */ -$help_url=''; +$help_url = ''; llxHeader('', $langs->trans("MailmanSpipSetup"), $help_url); -$linkback=''.$langs->trans("BackToModuleList").''; +$linkback = ''.$langs->trans("BackToModuleList").''; print load_fiche_titre($langs->trans("MailmanSpipSetup"), $linkback, 'title_setup'); @@ -120,7 +122,7 @@ $head = mailmanspip_admin_prepare_head(); /* * Spip */ -if (! empty($conf->global->ADHERENT_USE_SPIP)) +if (!empty($conf->global->ADHERENT_USE_SPIP)) { print ''; print ''; @@ -129,12 +131,12 @@ if (! empty($conf->global->ADHERENT_USE_SPIP)) dol_fiche_head($head, 'spip', $langs->trans("Setup"), -1, 'user'); //$link=img_picto($langs->trans("Active"),'tick').' '; - $link=''; + $link = ''; //$link.=$langs->trans("Disable"); - $link.=img_picto($langs->trans("Activated"), 'switch_on'); - $link.=''; + $link .= img_picto($langs->trans("Activated"), 'switch_on'); + $link .= ''; // Edition des varibales globales - $constantes=array( + $constantes = array( 'ADHERENT_SPIP_SERVEUR', 'ADHERENT_SPIP_DB', 'ADHERENT_SPIP_USER', @@ -156,10 +158,10 @@ else { dol_fiche_head($head, 'spip', $langs->trans("Setup"), 0, 'user'); - $link=''; + $link = ''; //$link.=$langs->trans("Activate"); - $link.=img_picto($langs->trans("Disabled"), 'switch_off'); - $link.=''; + $link .= img_picto($langs->trans("Disabled"), 'switch_off'); + $link .= ''; print load_fiche_titre($langs->trans('SPIPTitle'), $link, ''); dol_fiche_end(); diff --git a/htdocs/admin/supplier_invoice.php b/htdocs/admin/supplier_invoice.php index 9a17916cb49..977b99d0c99 100644 --- a/htdocs/admin/supplier_invoice.php +++ b/htdocs/admin/supplier_invoice.php @@ -171,7 +171,7 @@ if ($action == 'setmod') if ($action == 'addcat') { $fourn = new Fournisseur($db); - $fourn->CreateCategory($user, $_POST["cat"]); + $fourn->CreateCategory($user, GETPOST('cat', 'alphanohtml')); } if ($action == 'set_SUPPLIER_INVOICE_FREE_TEXT') diff --git a/htdocs/admin/supplier_order.php b/htdocs/admin/supplier_order.php index 15e1a452dff..db9b3e257f6 100644 --- a/htdocs/admin/supplier_order.php +++ b/htdocs/admin/supplier_order.php @@ -54,6 +54,8 @@ $specimenthirdparty->initAsSpecimen(); * Actions */ +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; + if ($action == 'updateMask') { $maskconstorder = GETPOST('maskconstorder', 'alpha'); @@ -163,7 +165,7 @@ elseif ($action == 'setmod') elseif ($action == 'addcat') { $fourn = new Fournisseur($db); - $fourn->CreateCategory($user, $_POST["cat"]); + $fourn->CreateCategory($user, GETPOST('cat', 'alphanohtml')); } elseif ($action == 'set_SUPPLIER_ORDER_OTHER') diff --git a/htdocs/admin/ticket.php b/htdocs/admin/ticket.php index dba1f827748..cd982ef0f5c 100644 --- a/htdocs/admin/ticket.php +++ b/htdocs/admin/ticket.php @@ -197,6 +197,7 @@ dol_fiche_end(); print load_fiche_titre($langs->trans("TicketNumberingModules")); +print '
'; print ''; print ''; print ''; @@ -287,7 +288,9 @@ foreach ($dirmodels as $reldir) { } } -print '
'.$langs->trans("Name").'

'; +print ''; +print '
'; +print '
'; if (!$conf->use_javascript_ajax) { print ''; diff --git a/htdocs/admin/ticket_public.php b/htdocs/admin/ticket_public.php index a4098e52247..6b8a23c94fc 100644 --- a/htdocs/admin/ticket_public.php +++ b/htdocs/admin/ticket_public.php @@ -167,7 +167,7 @@ $head = ticketAdminPrepareHead(); dol_fiche_head($head, 'public', $langs->trans("Module56000Name"), -1, "ticket"); -print ''.$langs->trans("TicketPublicAccess").' : '.dol_buildpath('/public/ticket/index.php', 2).''; +print ''.$langs->trans("TicketPublicAccess").' : '.dol_buildpath('/public/ticket/index.php', 2).''; dol_fiche_end(); @@ -176,14 +176,14 @@ $enabledisablehtml = $langs->trans("TicketsActivatePublicInterface").' '; if (empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { // Button off, click to enable - $enabledisablehtml .= ''; + $enabledisablehtml .= ''; $enabledisablehtml .= img_picto($langs->trans("Disabled"), 'switch_off'); $enabledisablehtml .= ''; } else { // Button on, click to disable - $enabledisablehtml .= ''; + $enabledisablehtml .= ''; $enabledisablehtml .= img_picto($langs->trans("Activated"), 'switch_on'); $enabledisablehtml .= ''; } @@ -200,6 +200,7 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) print ''; } + print '
'; print ''; print ''; print ''; } - print '
'.$langs->trans("Parameters").''; @@ -279,7 +280,9 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) print '

'; + print ''; + print '
'; + print '
'; if (!$conf->use_javascript_ajax) { print ''; @@ -288,6 +291,7 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) // Admin var of module print load_fiche_titre($langs->trans("TicketParamMail")); + print '
'; print ''; print ''; @@ -369,13 +373,14 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) $url_interface = $conf->global->TICKET_URL_PUBLIC_INTERFACE; print ''; + print ''; print ''; print ''; print '
'.$langs->trans("TicketUrlPublicInterfaceLabelAdmin").''; print ''; - print ''; print $form->textwithpicto('', $langs->trans("TicketUrlPublicInterfaceHelpAdmin"), 1, 'help'); print '
'; + print '
'; print '
'; diff --git a/htdocs/admin/tools/export_files.php b/htdocs/admin/tools/export_files.php index b6e593d15bf..c1c641b82f2 100644 --- a/htdocs/admin/tools/export_files.php +++ b/htdocs/admin/tools/export_files.php @@ -173,9 +173,6 @@ if ($errormsg) setEventMessages($langs->trans("Error")." : ".$errormsg, null, 'errors'); } -print '
'; - - // Redirect t backup page header("Location: dolibarr_export.php"); diff --git a/htdocs/admin/website.php b/htdocs/admin/website.php index d639b8d2a9b..2d201421f20 100644 --- a/htdocs/admin/website.php +++ b/htdocs/admin/website.php @@ -34,13 +34,13 @@ require_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php'; // Load translation files required by the page $langs->loadlangs(array('errors', 'admin', 'companies', 'website')); -$action=GETPOST('action', 'alpha')?GETPOST('action', 'alpha'):'view'; -$confirm=GETPOST('confirm', 'alpha'); +$action = GETPOST('action', 'alpha') ?GETPOST('action', 'alpha') : 'view'; +$confirm = GETPOST('confirm', 'alpha'); $backtopage = GETPOST('backtopage', 'alpha'); -$rowid=GETPOST('rowid', 'alpha'); +$rowid = GETPOST('rowid', 'alpha'); -$id=1; +$id = 1; if (!$user->admin) accessforbidden(); @@ -52,7 +52,7 @@ $actl[1] = img_picto($langs->trans("Activated"), 'switch_on'); $status = 1; // Load variable for pagination -$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit; +$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST('sortfield', 'alpha'); $sortorder = GETPOST('sortorder', 'alpha'); $page = GETPOST('page', 'int'); @@ -65,55 +65,55 @@ $pagenext = $page + 1; $hookmanager->initHooks(array('website')); // Name of SQL tables of dictionaries -$tabname=array(); +$tabname = array(); $tabname[1] = MAIN_DB_PREFIX."website"; // Dictionary labels -$tablib=array(); +$tablib = array(); $tablib[1] = "Websites"; // Requests to extract data -$tabsql=array(); +$tabsql = array(); $tabsql[1] = "SELECT f.rowid as rowid, f.entity, f.ref, f.description, f.virtualhost, f.status FROM ".MAIN_DB_PREFIX.'website as f WHERE f.entity IN ('.getEntity('website').')'; // Criteria to sort dictionaries -$tabsqlsort=array(); -$tabsqlsort[1] ="ref ASC"; +$tabsqlsort = array(); +$tabsqlsort[1] = "ref ASC"; // Nom des champs en resultat de select pour affichage du dictionnaire -$tabfield=array(); +$tabfield = array(); $tabfield[1] = "ref,description,virtualhost"; // Nom des champs d'edition pour modification d'un enregistrement -$tabfieldvalue=array(); +$tabfieldvalue = array(); $tabfieldvalue[1] = "ref,description,virtualhost"; // Nom des champs dans la table pour insertion d'un enregistrement -$tabfieldinsert=array(); +$tabfieldinsert = array(); $tabfieldinsert[1] = "ref,description,virtualhost,entity"; // Nom du rowid si le champ n'est pas de type autoincrement // Example: "" if id field is "rowid" and has autoincrement on // "nameoffield" if id field is not "rowid" or has not autoincrement on -$tabrowid=array(); +$tabrowid = array(); $tabrowid[1] = ""; // Condition to show dictionary in setup page -$tabcond=array(); -$tabcond[1] = (! empty($conf->website->enabled)); +$tabcond = array(); +$tabcond[1] = (!empty($conf->website->enabled)); // List of help for fields -$tabhelp=array(); -$tabhelp[1] = array('ref'=>$langs->trans("EnterAnyCode"), 'virtualhost'=>$langs->trans("SetHereVirtualHost", DOL_DATA_ROOT.'/website/websiteref')); +$tabhelp = array(); +$tabhelp[1] = array('ref'=>$langs->trans("EnterAnyCode"), 'virtualhost'=>$langs->trans("SetHereVirtualHost", DOL_DATA_ROOT.'/website/websiteref')); // List of check for fields (NOT USED YET) -$tabfieldcheck=array(); -$tabfieldcheck[1] = array(); +$tabfieldcheck = array(); +$tabfieldcheck[1] = array(); // Define elementList and sourceList (used for dictionary type of contacts "llx_c_type_contact") $elementList = array(); -$sourceList=array(); +$sourceList = array(); /* @@ -123,35 +123,35 @@ $sourceList=array(); // Actions add or modify a website if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { - $listfield=explode(',', $tabfield[$id]); - $listfieldinsert=explode(',', $tabfieldinsert[$id]); - $listfieldmodify=explode(',', $tabfieldinsert[$id]); - $listfieldvalue=explode(',', $tabfieldvalue[$id]); + $listfield = explode(',', $tabfield[$id]); + $listfieldinsert = explode(',', $tabfieldinsert[$id]); + $listfieldmodify = explode(',', $tabfieldinsert[$id]); + $listfieldvalue = explode(',', $tabfieldvalue[$id]); // Check that all fields are filled - $ok=1; + $ok = 1; foreach ($listfield as $f => $value) { - if ($value == 'ref' && (! isset($_POST[$value]) || $_POST[$value]=='')) + if ($value == 'ref' && (!GETPOSTISSET($value) || GETPOST($value) == '')) { - $ok=0; - $fieldnamekey=$listfield[$f]; + $ok = 0; + $fieldnamekey = $listfield[$f]; setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors'); break; } - elseif ($value == 'ref' && ! preg_match('/^[a-z0-9_\-\.]+$/i', $_POST[$value])) + elseif ($value == 'ref' && !preg_match('/^[a-z0-9_\-\.]+$/i', $_POST[$value])) { - $ok=0; - $fieldnamekey=$listfield[$f]; + $ok = 0; + $fieldnamekey = $listfield[$f]; setEventMessages($langs->transnoentities("ErrorFieldCanNotContainSpecialCharacters", $langs->transnoentities($fieldnamekey)), null, 'errors'); break; } } // Clean parameters - if (! empty($_POST['ref'])) + if (!empty($_POST['ref'])) { - $websitekey=strtolower($_POST['ref']); + $websitekey = strtolower($_POST['ref']); } // Si verif ok et action add, on ajoute la ligne @@ -160,13 +160,13 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) if ($tabrowid[$id]) { // Recupere id libre pour insertion - $newid=0; + $newid = 0; $sql = "SELECT max(".$tabrowid[$id].") newid from ".$tabname[$id]; $result = $db->query($sql); if ($result) { $obj = $db->fetch_object($result); - $newid=($obj->newid + 1); + $newid = ($obj->newid + 1); } else { dol_print_error($db); } @@ -181,16 +181,16 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) // Add new entry $sql = "INSERT INTO ".$tabname[$id]." ("; // List of fields - if ($tabrowid[$id] && ! in_array($tabrowid[$id], $listfieldinsert)) - $sql.= $tabrowid[$id].","; - $sql.= $tabfieldinsert[$id]; - $sql.=",status)"; - $sql.= " VALUES("; + if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) + $sql .= $tabrowid[$id].","; + $sql .= $tabfieldinsert[$id]; + $sql .= ",status)"; + $sql .= " VALUES("; // List of values - if ($tabrowid[$id] && ! in_array($tabrowid[$id], $listfieldinsert)) - $sql.= $newid.","; - $i=0; + if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) + $sql .= $newid.","; + $i = 0; foreach ($listfieldinsert as $f => $value) { if ($value == 'entity') { @@ -199,19 +199,19 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) if ($value == 'ref') { $_POST[$listfieldvalue[$i]] = strtolower($_POST[$listfieldvalue[$i]]); } - if ($i) $sql.=","; - if ($_POST[$listfieldvalue[$i]] == '') $sql.="null"; - else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + if ($i) $sql .= ","; + if ($_POST[$listfieldvalue[$i]] == '') $sql .= "null"; + else $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; $i++; } - $sql.=",1)"; + $sql .= ",1)"; dol_syslog("actionadd", LOG_DEBUG); $result = $db->query($sql); if ($result) // Add is ok { setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs'); - unset($_POST); // Clean $_POST array, we keep only + unset($_POST); // Clean $_POST array, we keep only } else { @@ -227,22 +227,22 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) // Si verif ok et action modify, on modifie la ligne if ($ok && GETPOST('actionmodify', 'alpha')) { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } + if ($tabrowid[$id]) { $rowidcol = $tabrowid[$id]; } + else { $rowidcol = "rowid"; } $db->begin(); - $website=new Website($db); - $rowid=GETPOST('rowid', 'int'); + $website = new Website($db); + $rowid = GETPOST('rowid', 'int'); $website->fetch($rowid); // Modify entry $sql = "UPDATE ".$tabname[$id]." SET "; // Modifie valeur des champs - if ($tabrowid[$id] && ! in_array($tabrowid[$id], $listfieldmodify)) + if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldmodify)) { - $sql.= $tabrowid[$id]."="; - $sql.= "'".$db->escape($rowid)."', "; + $sql .= $tabrowid[$id]."="; + $sql .= "'".$db->escape($rowid)."', "; } $i = 0; foreach ($listfieldmodify as $field) @@ -250,13 +250,13 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) if ($field == 'entity') { $_POST[$listfieldvalue[$i]] = $conf->entity; } - if ($i) $sql.=","; - $sql.= $field."="; - if ($_POST[$listfieldvalue[$i]] == '') $sql.="null"; - else $sql.="'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + if ($i) $sql .= ","; + $sql .= $field."="; + if ($_POST[$listfieldvalue[$i]] == '') $sql .= "null"; + else $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; $i++; } - $sql.= " WHERE ".$rowidcol." = '".$rowid."'"; + $sql .= " WHERE ".$rowidcol." = '".$rowid."'"; dol_syslog("actionmodify", LOG_DEBUG); //print $sql; @@ -266,8 +266,8 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) $newname = dol_sanitizeFileName(GETPOST('ref', 'aZ09')); if ($newname != $website->ref) { - $srcfile=DOL_DATA_ROOT.'/website/'.$website->ref; - $destfile=DOL_DATA_ROOT.'/website/'.$newname; + $srcfile = DOL_DATA_ROOT.'/website/'.$website->ref; + $destfile = DOL_DATA_ROOT.'/website/'.$newname; if (dol_is_dir($destfile)) { @@ -294,7 +294,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) setEventMessages($db->lasterror(), null, 'errors'); } - if (! $error) + if (!$error) { $db->commit(); } @@ -313,8 +313,8 @@ if (GETPOST('actioncancel', 'alpha')) if ($action == 'confirm_delete' && $confirm == 'yes') // delete { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } + if ($tabrowid[$id]) { $rowidcol = $tabrowid[$id]; } + else { $rowidcol = "rowid"; } $website = new Website($db); $website->fetch($rowid); @@ -332,7 +332,7 @@ if ($action == 'confirm_delete' && $confirm == 'yes') // delete $sql = "DELETE from ".MAIN_DB_PREFIX."website WHERE rowid ='".$rowid."'"; $result = $db->query($sql); - if (! $result) + if (!$result) { if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') { @@ -358,8 +358,8 @@ if ($action == 'confirm_delete' && $confirm == 'yes') // delete // activate if ($action == $acts[0]) { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } + if ($tabrowid[$id]) { $rowidcol = $tabrowid[$id]; } + else { $rowidcol = "rowid"; } if ($rowid) { $sql = "UPDATE ".$tabname[$id]." SET status = 1 WHERE rowid ='".$rowid."'"; @@ -375,8 +375,8 @@ if ($action == $acts[0]) // disable if ($action == $acts[1]) { - if ($tabrowid[$id]) { $rowidcol=$tabrowid[$id]; } - else { $rowidcol="rowid"; } + if ($tabrowid[$id]) { $rowidcol = $tabrowid[$id]; } + else { $rowidcol = "rowid"; } if ($rowid) { $sql = "UPDATE ".$tabname[$id]." SET status = 0 WHERE rowid ='".$rowid."'"; @@ -396,16 +396,16 @@ if ($action == $acts[1]) */ $form = new Form($db); -$formadmin=new FormAdmin($db); +$formadmin = new FormAdmin($db); llxHeader('', $langs->trans("WebsiteSetup")); -$titre=$langs->trans("WebsiteSetup"); -$linkback=''.$langs->trans("BackToModuleList").''; +$titre = $langs->trans("WebsiteSetup"); +$linkback = ''.$langs->trans("BackToModuleList").''; print load_fiche_titre($titre, $linkback, 'title_setup'); // Onglets -$head=array(); +$head = array(); $h = 0; $head[$h][0] = DOL_URL_ROOT."/admin/website.php"; @@ -428,7 +428,7 @@ print "
\n"; // Confirmation de la suppression de la ligne if ($action == 'delete') { - print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.$rowid, $langs->trans('DeleteWebsite'), $langs->trans('ConfirmDeleteWebsite'), 'confirm_delete', '', 0, 1); + print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.$rowid, $langs->trans('DeleteWebsite'), $langs->trans('ConfirmDeleteWebsite'), 'confirm_delete', '', 0, 1); } //var_dump($elementList); @@ -438,12 +438,12 @@ if ($action == 'delete') if ($id) { // Complete requete recherche valeurs avec critere de tri - $sql=$tabsql[$id]; - $sql.=$db->order($sortfield, $sortorder); - $sql.=$db->plimit($limit+1, $offset); + $sql = $tabsql[$id]; + $sql .= $db->order($sortfield, $sortorder); + $sql .= $db->plimit($limit + 1, $offset); //print $sql; - $fieldlist=explode(',', $tabfield[$id]); + $fieldlist = explode(',', $tabfield[$id]); print ''; print ''; @@ -452,10 +452,10 @@ if ($id) // Form to add a new line if ($tabname[$id]) { - $alabelisused=0; - $var=false; + $alabelisused = 0; + $var = false; - $fieldlist=explode(',', $tabfield[$id]); + $fieldlist = explode(',', $tabfield[$id]); // Line for title print ''; @@ -463,15 +463,15 @@ if ($id) { // Determine le nom du champ par rapport aux noms possibles // dans les dictionnaires de donnees - $valuetoshow=ucfirst($fieldlist[$field]); // Par defaut - $valuetoshow=$langs->trans($valuetoshow); // try to translate - $align=''; - if ($fieldlist[$field]=='lang') { $valuetoshow=$langs->trans("Language"); } + $valuetoshow = ucfirst($fieldlist[$field]); // Par defaut + $valuetoshow = $langs->trans($valuetoshow); // try to translate + $align = ''; + if ($fieldlist[$field] == 'lang') { $valuetoshow = $langs->trans("Language"); } if ($valuetoshow != '') { print ''; - if (! empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) print ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; - elseif (! empty($tabhelp[$id][$value])) + if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) print ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; + elseif (!empty($tabhelp[$id][$value])) { if ($value == 'virtualhost') print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value], 1, 'help', '', 0, 2, 'tooltipvirtual'); else print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]); @@ -479,7 +479,7 @@ if ($id) else print $valuetoshow; print ''; } - if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') $alabelisused=1; + if ($fieldlist[$field] == 'libelle' || $fieldlist[$field] == 'label') $alabelisused = 1; } print ''; @@ -496,7 +496,7 @@ if ($id) foreach ($fieldlist as $key=>$val) { if (GETPOST($val, 'alpha')) - $obj->$val=GETPOST($val); + $obj->$val = GETPOST($val); } } @@ -510,7 +510,7 @@ if ($id) print ''; print ""; - $colspan=count($fieldlist)+2; + $colspan = count($fieldlist) + 2; } print ''; @@ -518,7 +518,7 @@ if ($id) // List of websites in database - $resql=$db->query($sql); + $resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); @@ -540,10 +540,10 @@ if ($id) { // Determine le nom du champ par rapport aux noms possibles // dans les dictionnaires de donnees - $showfield=1; // Par defaut - $align="left"; - $sortable=1; - $valuetoshow=''; + $showfield = 1; // Par defaut + $align = "left"; + $sortable = 1; + $valuetoshow = ''; /* $tmparray=getLabelOfField($fieldlist[$field]); $showfield=$tmp['showfield']; @@ -551,20 +551,20 @@ if ($id) $align=$tmp['align']; $sortable=$tmp['sortable']; */ - $valuetoshow=ucfirst($fieldlist[$field]); // Par defaut - $valuetoshow=$langs->trans($valuetoshow); // try to translate - if ($fieldlist[$field]=='lang') { $valuetoshow=$langs->trans("Language"); } - if ($fieldlist[$field]=='type') { $valuetoshow=$langs->trans("Type"); } - if ($fieldlist[$field]=='code') { $valuetoshow=$langs->trans("Code"); } + $valuetoshow = ucfirst($fieldlist[$field]); // Par defaut + $valuetoshow = $langs->trans($valuetoshow); // try to translate + if ($fieldlist[$field] == 'lang') { $valuetoshow = $langs->trans("Language"); } + if ($fieldlist[$field] == 'type') { $valuetoshow = $langs->trans("Type"); } + if ($fieldlist[$field] == 'code') { $valuetoshow = $langs->trans("Code"); } // Affiche nom du champ if ($showfield) { - print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], ($sortable?$fieldlist[$field]:''), ($page?'page='.$page.'&':''), "", "align=".$align, $sortfield, $sortorder); + print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], ($sortable ? $fieldlist[$field] : ''), ($page ? 'page='.$page.'&' : ''), "", "align=".$align, $sortfield, $sortorder); } } - print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], "status", ($page?'page='.$page.'&':''), "", 'align="center"', $sortfield, $sortorder); + print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], "status", ($page ? 'page='.$page.'&' : ''), "", 'align="center"', $sortfield, $sortorder); print getTitleFieldOfList(''); print getTitleFieldOfList(''); print ''; @@ -575,34 +575,34 @@ if ($id) $obj = $db->fetch_object($resql); //print_r($obj); print ''; - if ($action == 'edit' && ($rowid == (! empty($obj->rowid)?$obj->rowid:$obj->code))) + if ($action == 'edit' && ($rowid == (!empty($obj->rowid) ? $obj->rowid : $obj->code))) { - $tmpaction='edit'; - $parameters=array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); - $reshook=$hookmanager->executeHooks('editWebsiteFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks - $error=$hookmanager->error; $errors=$hookmanager->errors; + $tmpaction = 'edit'; + $parameters = array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $reshook = $hookmanager->executeHooks('editWebsiteFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks + $error = $hookmanager->error; $errors = $hookmanager->errors; if (empty($reshook)) fieldListWebsites($fieldlist, $obj, $tabname[$id], 'edit'); - print ' '; + print ' '; print ' '; } else { $tmpaction = 'view'; - $parameters=array('var'=>$var, 'fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); - $reshook=$hookmanager->executeHooks('viewWebsiteFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks + $parameters = array('var'=>$var, 'fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $reshook = $hookmanager->executeHooks('viewWebsiteFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks - $error=$hookmanager->error; $errors=$hookmanager->errors; + $error = $hookmanager->error; $errors = $hookmanager->errors; if (empty($reshook)) { foreach ($fieldlist as $field => $value) { - $showfield=1; - $align="left"; - $fieldname=$fieldlist[$field]; - $valuetoshow=$obj->$fieldname; + $showfield = 1; + $align = "left"; + $fieldname = $fieldlist[$field]; + $valuetoshow = $obj->$fieldname; // Show value for field if ($showfield) print ''.$valuetoshow.''; @@ -610,14 +610,14 @@ if ($id) } // Can an entry be erased or disabled ? - $iserasable=1; $isdisable=1; // true by default - if ($obj->status) $iserasable=0; // We can't delete a website on. Disable it first. + $iserasable = 1; $isdisable = 1; // true by default + if ($obj->status) $iserasable = 0; // We can't delete a website on. Disable it first. - $url = $_SERVER["PHP_SELF"].'?'.($page?'page='.$page.'&':'').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(! empty($obj->rowid)?$obj->rowid:(! empty($obj->code)?$obj->code:'')).'&code='.(! empty($obj->code)?urlencode($obj->code):'').'&'; + $url = $_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')).'&code='.(!empty($obj->code) ?urlencode($obj->code) : '').'&'; // Active print ''; - print ''.$actl[($obj->status?1:0)].''; + print ''.$actl[($obj->status ? 1 : 0)].''; print ""; // Modify link @@ -660,10 +660,10 @@ $db->close(); */ function fieldListWebsites($fieldlist, $obj = '', $tabname = '', $context = '') { - global $conf,$langs,$db; + global $conf, $langs, $db; global $form; global $region_id; - global $elementList,$sourceList,$localtax_typeList; + global $elementList, $sourceList, $localtax_typeList; global $bc; $formadmin = new FormAdmin($db); @@ -678,18 +678,18 @@ function fieldListWebsites($fieldlist, $obj = '', $tabname = '', $context = '') print ''; } elseif ($fieldlist[$field] == 'code' && isset($obj->$fieldname)) { - print ''; + print ''; } else { print ''; - $size=''; - if ($fieldlist[$field]=='code') $size='size="8" '; - if ($fieldlist[$field]=='position') $size='size="4" '; - if ($fieldlist[$field]=='libelle') $size='size="32" '; - if ($fieldlist[$field]=='tracking') $size='size="92" '; - if ($fieldlist[$field]=='sortorder') $size='size="2" '; - print ''; + $size = ''; + if ($fieldlist[$field] == 'code') $size = 'size="8" '; + if ($fieldlist[$field] == 'position') $size = 'size="4" '; + if ($fieldlist[$field] == 'libelle') $size = 'size="32" '; + if ($fieldlist[$field] == 'tracking') $size = 'size="92" '; + if ($fieldlist[$field] == 'sortorder') $size = 'size="2" '; + print ''; print ''; } } diff --git a/htdocs/api/admin/explorer.php b/htdocs/api/admin/explorer.php index ac267d29bc3..22263b8b9ba 100644 --- a/htdocs/api/admin/explorer.php +++ b/htdocs/api/admin/explorer.php @@ -25,6 +25,8 @@ * \file htdocs/api/admin/explorer.php */ +use Luracast\Restler\Routes; + require_once '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/api/class/api.class.php'; diff --git a/htdocs/api/admin/index.php b/htdocs/api/admin/index.php index 90bc9acd2fd..73041f6c386 100644 --- a/htdocs/api/admin/index.php +++ b/htdocs/api/admin/index.php @@ -96,7 +96,7 @@ llxHeader(); $linkback = ''.$langs->trans("BackToModuleList").''; print load_fiche_titre($langs->trans("ApiSetup"), $linkback, 'title_setup'); -print $langs->trans("ApiDesc")."
\n"; +print ''.$langs->trans("ApiDesc")."
\n"; print "
\n"; print ''; @@ -130,7 +130,9 @@ print ' '; print ''; print ''; -print ''.$langs->trans("RESTRICT_API_ON_IP").''; +print ''.$langs->trans("RESTRICT_ON_IP"); +print ' '.$langs->trans("Example").': '.$langs->trans("IPListExample"); +print ''; print ''; print ''; print ''; diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index 4785ab78174..e58ebf7d280 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -60,10 +60,9 @@ class Documents extends DolibarrApi * @param string $original_file Relative path with filename, relative to modulepart (for example: IN201701-999/IN201701-999.pdf) * @return array List of documents * - * @throws 400 - * @throws 401 - * @throws 404 - * @throws 200 + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 * * @url GET /download */ @@ -81,7 +80,18 @@ class Documents extends DolibarrApi //--- Finds and returns the document $entity = $conf->entity; - $check_access = dol_check_secure_access_document($modulepart, $original_file, $entity, DolibarrApiAccess::$user, '', 'read'); + // Special cases that need to use get_exdir to get real dir of object + // If future, all object should use this to define path of documents. + /* + $tmpreldir = ''; + if ($modulepart == 'supplier_invoice') { + $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier'); + } + + $relativefile = $tmpreldir.dol_sanitizeFileName($object->ref); */ + $relativefile = $original_file; + + $check_access = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'read'); $accessallowed = $check_access['accessallowed']; $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals']; $original_file = $check_access['original_file']; @@ -118,12 +128,11 @@ class Documents extends DolibarrApi * @param string $langcode Language code like 'en_US', 'fr_FR', 'es_ES', ... (If not set, use the default language). * @return array List of documents * - * @throws 500 - * @throws 501 - * @throws 400 - * @throws 401 - * @throws 404 - * @throws 200 + * @throws RestException 500 + * @throws RestException 501 + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 * * @url PUT /builddoc */ @@ -148,7 +157,18 @@ class Documents extends DolibarrApi //--- Finds and returns the document $entity = $conf->entity; - $check_access = dol_check_secure_access_document($modulepart, $original_file, $entity, DolibarrApiAccess::$user, '', 'write'); + // Special cases that need to use get_exdir to get real dir of object + // If future, all object should use this to define path of documents. + /* + $tmpreldir = ''; + if ($modulepart == 'supplier_invoice') { + $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier'); + } + + $relativefile = $tmpreldir.dol_sanitizeFileName($object->ref); */ + $relativefile = $original_file; + + $check_access = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'write'); $accessallowed = $check_access['accessallowed']; $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals']; $original_file = $check_access['original_file']; @@ -230,18 +250,17 @@ class Documents extends DolibarrApi /** * Return the list of documents of a dedicated element (from its ID or Ref) * - * @param string $modulepart Name of module or area concerned ('thirdparty', 'member', 'proposal', 'order', 'invoice', 'shipment', 'project', ...) + * @param string $modulepart Name of module or area concerned ('thirdparty', 'member', 'proposal', 'order', 'invoice', 'supplier_invoice', 'shipment', 'project', ...) * @param int $id ID of element * @param string $ref Ref of element * @param string $sortfield Sort criteria ('','fullname','relativename','name','date','size') * @param string $sortorder Sort order ('asc' or 'desc') * @return array Array of documents with path * - * @throws 200 - * @throws 400 - * @throws 401 - * @throws 404 - * @throws 500 + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 * * @url GET / */ @@ -275,6 +294,23 @@ class Documents extends DolibarrApi $upload_dir = $conf->societe->multidir_output[$object->entity]."/".$object->id; } + elseif ($modulepart == 'user') + { + require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; + + // Can get doc if has permission to read all user or if it is user itself + if (!DolibarrApiAccess::$user->rights->user->user->lire && DolibarrApiAccess::$user->id != $id) { + throw new RestException(401); + } + + $object = new User($this->db); + $result = $object->fetch($id, $ref); + if (!$result) { + throw new RestException(404, 'User not found'); + } + + $upload_dir = $conf->user->dir_output.'/'.get_exdir(0, 0, 0, 0, $object, 'user').'/'.$object->id; + } elseif ($modulepart == 'adherent' || $modulepart == 'member') { require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; @@ -355,6 +391,24 @@ class Documents extends DolibarrApi $upload_dir = $conf->facture->dir_output."/".get_exdir(0, 0, 0, 1, $object, 'invoice'); } + elseif ($modulepart == 'facture_fournisseur' || $modulepart == 'supplier_invoice') + { + $modulepart = 'supplier_invoice'; + + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; + + if (!DolibarrApiAccess::$user->rights->fournisseur->facture->lire) { + throw new RestException(401); + } + + $object = new FactureFournisseur($this->db); + $result = $object->fetch($id, $ref); + if (!$result) { + throw new RestException(404, 'Invoice not found'); + } + + $upload_dir = $conf->fournisseur->dir_output."/facture/".get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').dol_sanitizeFileName($object->ref); + } elseif ($modulepart == 'produit' || $modulepart == 'product') { require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; @@ -387,6 +441,22 @@ class Documents extends DolibarrApi $upload_dir = $conf->agenda->dir_output.'/'.dol_sanitizeFileName($object->ref); } + elseif ($modulepart == 'expensereport') + { + require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; + + if (!DolibarrApiAccess::$user->rights->expensereport->read && !DolibarrApiAccess::$user->rights->expensereport->read) { + throw new RestException(401); + } + + $object = new ExpenseReport($this->db); + $result = $object->fetch($id, $ref); + if (!$result) { + throw new RestException(404, 'Expense report not found'); + } + + $upload_dir = $conf->expensereport->dir_output.'/'.dol_sanitizeFileName($object->ref); + } else { throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.'); @@ -418,8 +488,9 @@ class Documents extends DolibarrApi /** * Upload a file. * - * Test sample 1: { "filename": "mynewfile.txt", "modulepart": "facture", "ref": "FA1701-001", "subdir": "", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }. - * Test sample 2: { "filename": "mynewfile.txt", "modulepart": "medias", "ref": "", "subdir": "image/mywebsite", "filecontent": "Y29udGVudCB0ZXh0Cg==", "fileencoding": "base64", "overwriteifexists": "0" }. + * Test sample for invoice: { "filename": "mynewfile.txt", "modulepart": "invoice", "ref": "FA1701-001", "subdir": "", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }. + * Test sample for supplier invoice: { "filename": "mynewfile.txt", "modulepart": "supplier_invoice", "ref": "FA1701-001", "subdir": "", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }. + * Test sample for medias file: { "filename": "mynewfile.txt", "modulepart": "medias", "ref": "", "subdir": "image/mywebsite", "filecontent": "Y29udGVudCB0ZXh0Cg==", "fileencoding": "base64", "overwriteifexists": "0" }. * * @param string $filename Name of file to create ('FA1705-0123.txt') * @param string $modulepart Name of module or area concerned by file upload ('facture', 'project', 'project_task', ...) @@ -430,11 +501,10 @@ class Documents extends DolibarrApi * @param int $overwriteifexists Overwrite file if exists (1 by default) * @return string * - * @throws 200 - * @throws 400 - * @throws 401 - * @throws 404 - * @throws 500 + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 * * @url POST /upload */ @@ -476,6 +546,13 @@ class Documents extends DolibarrApi require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; $object = new Facture($this->db); } + elseif ($modulepart == 'facture_fournisseur' || $modulepart == 'supplier_invoice') + { + $modulepart = 'supplier_invoice'; + + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; + $object = new FactureFournisseur($this->db); + } elseif ($modulepart == 'project') { require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; @@ -510,6 +587,11 @@ class Documents extends DolibarrApi require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; $object = new Product($this->db); } + elseif ($modulepart == 'expensereport') + { + require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; + $object = new ExpenseReport($this->db); + } // TODO Implement additional moduleparts else { @@ -535,6 +617,12 @@ class Documents extends DolibarrApi throw new RestException(404, 'The object '.$modulepart." with ref '".$ref."' was not found."); } + // Special cases that need to use get_exdir to get real dir of object + // If future, all object should use this to define path of documents. + if ($modulepart == 'supplier_invoice') { + $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier'); + } + $relativefile = $tmpreldir.dol_sanitizeFileName($object->ref); $tmp = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, $ref, 'write'); @@ -610,10 +698,9 @@ class Documents extends DolibarrApi * @param string $original_file Relative path with filename, relative to modulepart (for example: PRODUCT-REF-999/IMAGE-999.jpg) * @return array List of documents * - * @throws 400 - * @throws 401 - * @throws 404 - * @throws 200 + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 * * @url DELETE / */ @@ -631,7 +718,18 @@ class Documents extends DolibarrApi //--- Finds and returns the document $entity = $conf->entity; - $check_access = dol_check_secure_access_document($modulepart, $original_file, $entity, DolibarrApiAccess::$user, '', 'read'); + // Special cases that need to use get_exdir to get real dir of object + // If future, all object should use this to define path of documents. + /* + $tmpreldir = ''; + if ($modulepart == 'supplier_invoice') { + $tmpreldir = get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier'); + } + + $relativefile = $tmpreldir.dol_sanitizeFileName($object->ref); */ + $relativefile = $original_file; + + $check_access = dol_check_secure_access_document($modulepart, $relativefile, $entity, DolibarrApiAccess::$user, '', 'read'); $accessallowed = $check_access['accessallowed']; $sqlprotectagainstexternals = $check_access['sqlprotectagainstexternals']; $original_file = $check_access['original_file']; diff --git a/htdocs/api/class/api_login.class.php b/htdocs/api/class/api_login.class.php index 59a527d251c..748d1f2ac31 100644 --- a/htdocs/api/class/api_login.class.php +++ b/htdocs/api/class/api_login.class.php @@ -48,9 +48,8 @@ class Login * @param int $reset Reset token (0=get current token, 1=ask a new token and canceled old token. This means access using current existing API token of user will fails: new token will be required for new access) * @return array Response status and user token * - * @throws 200 - * @throws 403 - * @throws 500 + * @throws RestException 403 + * @throws RestException 500 * * @url GET / * @url POST / diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php index 66c4c1358cb..d3543683db2 100644 --- a/htdocs/api/class/api_setup.class.php +++ b/htdocs/api/class/api_setup.class.php @@ -59,8 +59,7 @@ class Setup extends DolibarrApi * * @return array [List of ordering methods] * - * @throws 400 RestException - * @throws 200 OK + * @throws RestException 400 */ public function getOrderingMethods($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '') { @@ -121,8 +120,7 @@ class Setup extends DolibarrApi * * @return array [List of payment types] * - * @throws 400 RestException - * @throws 200 OK + * @throws RestException 400 */ public function getPaymentTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '') { @@ -339,8 +337,7 @@ class Setup extends DolibarrApi * * @return array [List of availability] * - * @throws 400 RestException - * @throws 200 OK + * @throws RestException 400 */ public function getAvailability($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '') { @@ -557,6 +554,70 @@ class Setup extends DolibarrApi return $list; } + + /** + * Get the list of Expense Report types. + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Number of items per page + * @param int $page Page number (starting from zero) + * @param string $module To filter on module + * @param int $active Event's type is active or not {@min 0} {@max 1} + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" + * @return array List of expense report types + * + * @url GET dictionary/expensereport_types + * + * @throws RestException + */ + public function getListOfExpenseReportsTypes($sortfield = "code", $sortorder = 'ASC', $limit = 100, $page = 0, $module = '', $active = 1, $sqlfilters = '') + { + $list = array(); + + $sql = "SELECT id, code, label, accountancy_code, active, module, position"; + $sql .= " FROM ".MAIN_DB_PREFIX."c_type_fees as t"; + $sql .= " WHERE t.active = ".$active; + if ($module) $sql .= " AND t.module LIKE '%".$this->db->escape($module)."%'"; + // Add sql filters + if ($sqlfilters) + { + if (!DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + + $sql .= $this->db->order($sortfield, $sortorder); + + if ($limit) { + if ($page < 0) { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $this->db->plimit($limit, $offset); + } + + $result = $this->db->query($sql); + + if ($result) { + $num = $this->db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + for ($i = 0; $i < $min; $i++) { + $list[] = $this->db->fetch_object($result); + } + } else { + throw new RestException(503, 'Error when retrieving list of expense report types : '.$this->db->lasterror()); + } + + return $list; + } + + /** * Get the list of contacts types. * @@ -908,8 +969,7 @@ class Setup extends DolibarrApi * * @return array List of payment terms * - * @throws 400 RestException - * @throws 200 OK + * @throws RestException 400 */ public function getPaymentTerms($sortfield = "sortorder", $sortorder = 'ASC', $limit = 100, $page = 0, $active = 1, $sqlfilters = '') { @@ -969,8 +1029,7 @@ class Setup extends DolibarrApi * * @return array List of shipping methods * - * @throws 400 RestException - * @throws 200 OK + * @throws RestException 400 */ public function getShippingModes($limit = 100, $page = 0, $active = 1, $sqlfilters = '') { diff --git a/htdocs/asset/class/asset_type.class.php b/htdocs/asset/class/asset_type.class.php index 23c1bd630fa..edb6fdf90c9 100644 --- a/htdocs/asset/class/asset_type.class.php +++ b/htdocs/asset/class/asset_type.class.php @@ -68,9 +68,9 @@ class AssetType extends CommonObject public $note; /** @var array Array of asset */ - public $asset=array(); + public $asset = array(); - public $fields=array( + public $fields = array( 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>15, 'index'=>1), 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>20), @@ -104,9 +104,9 @@ class AssetType extends CommonObject { global $conf; - $error=0; + $error = 0; - $this->label=trim($this->label); + $this->label = trim($this->label); $this->accountancy_code_asset = trim($this->accountancy_code_asset); $this->accountancy_code_depreciation_asset = trim($this->accountancy_code_depreciation_asset); $this->accountancy_code_depreciation_expense = trim($this->accountancy_code_depreciation_expense); @@ -114,20 +114,20 @@ class AssetType extends CommonObject $this->db->begin(); $sql = "INSERT INTO ".MAIN_DB_PREFIX."asset_type ("; - $sql.= "label"; - $sql.= ", accountancy_code_asset"; - $sql.= ", accountancy_code_depreciation_asset"; - $sql.= ", accountancy_code_depreciation_expense"; - $sql.= ", note"; - $sql.= ", entity"; - $sql.= ") VALUES ("; - $sql.= "'".$this->db->escape($this->label)."'"; - $sql.= ", '".$this->db->escape($this->accountancy_code_asset)."'"; - $sql.= ", '".$this->db->escape($this->accountancy_code_depreciation_asset)."'"; - $sql.= ", '".$this->db->escape($this->accountancy_code_depreciation_expense)."'"; - $sql.= ", '".$this->db->escape($this->note)."'"; - $sql.= ", ".$conf->entity; - $sql.= ")"; + $sql .= "label"; + $sql .= ", accountancy_code_asset"; + $sql .= ", accountancy_code_depreciation_asset"; + $sql .= ", accountancy_code_depreciation_expense"; + $sql .= ", note"; + $sql .= ", entity"; + $sql .= ") VALUES ("; + $sql .= "'".$this->db->escape($this->label)."'"; + $sql .= ", '".$this->db->escape($this->accountancy_code_asset)."'"; + $sql .= ", '".$this->db->escape($this->accountancy_code_depreciation_asset)."'"; + $sql .= ", '".$this->db->escape($this->accountancy_code_depreciation_expense)."'"; + $sql .= ", '".$this->db->escape($this->note)."'"; + $sql .= ", ".$conf->entity; + $sql .= ")"; dol_syslog("Asset_type::create", LOG_DEBUG); $result = $this->db->query($sql); @@ -142,15 +142,15 @@ class AssetType extends CommonObject return -3; } - if (! $notrigger) + if (!$notrigger) { // Call trigger - $result=$this->call_trigger('ASSET_TYPE_CREATE', $user); + $result = $this->call_trigger('ASSET_TYPE_CREATE', $user); if ($result < 0) { $error++; } // End call triggers } - if (! $error) + if (!$error) { $this->db->commit(); return $this->id; @@ -164,7 +164,7 @@ class AssetType extends CommonObject } else { - $this->error=$this->db->lasterror(); + $this->error = $this->db->lasterror(); $this->db->rollback(); return -1; } @@ -181,45 +181,45 @@ class AssetType extends CommonObject { global $conf, $hookmanager; - $error=0; + $error = 0; - $this->label=trim($this->label); + $this->label = trim($this->label); $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."asset_type "; - $sql.= "SET "; - $sql.= "label = '".$this->db->escape($this->label) ."',"; - $sql.= "accountancy_code_asset = '".$this->db->escape($this->accountancy_code_asset)."',"; - $sql.= "accountancy_code_depreciation_asset = '".$this->db->escape($this->accountancy_code_depreciation_asset)."',"; - $sql.= "accountancy_code_depreciation_expense = '".$this->db->escape($this->accountancy_code_depreciation_expense)."',"; - $sql.= "note = '".$this->db->escape($this->note) ."'"; - $sql.= " WHERE rowid =".$this->id; + $sql .= "SET "; + $sql .= "label = '".$this->db->escape($this->label)."',"; + $sql .= "accountancy_code_asset = '".$this->db->escape($this->accountancy_code_asset)."',"; + $sql .= "accountancy_code_depreciation_asset = '".$this->db->escape($this->accountancy_code_depreciation_asset)."',"; + $sql .= "accountancy_code_depreciation_expense = '".$this->db->escape($this->accountancy_code_depreciation_expense)."',"; + $sql .= "note = '".$this->db->escape($this->note)."'"; + $sql .= " WHERE rowid =".$this->id; $result = $this->db->query($sql); if ($result) { - $action='update'; + $action = 'update'; // Actions on extra fields if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used { - $result=$this->insertExtraFields(); + $result = $this->insertExtraFields(); if ($result < 0) { $error++; } } - if (! $error && ! $notrigger) + if (!$error && !$notrigger) { // Call trigger - $result=$this->call_trigger('ASSET_TYPE_MODIFY', $user); + $result = $this->call_trigger('ASSET_TYPE_MODIFY', $user); if ($result < 0) { $error++; } // End call triggers } - if (! $error) + if (!$error) { $this->db->commit(); return 1; @@ -233,7 +233,7 @@ class AssetType extends CommonObject } else { - $this->error=$this->db->lasterror(); + $this->error = $this->db->lasterror(); $this->db->rollback(); return -1; } @@ -251,13 +251,13 @@ class AssetType extends CommonObject $error = 0; $sql = "DELETE FROM ".MAIN_DB_PREFIX."asset_type"; - $sql.= " WHERE rowid = ".$this->id; + $sql .= " WHERE rowid = ".$this->id; - $resql=$this->db->query($sql); + $resql = $this->db->query($sql); if ($resql) { // Call trigger - $result=$this->call_trigger('ASSET_TYPE_DELETE', $user); + $result = $this->call_trigger('ASSET_TYPE_DELETE', $user); if ($result < 0) { $error++; $this->db->rollback(); return -2; } // End call triggers @@ -267,7 +267,7 @@ class AssetType extends CommonObject else { $this->db->rollback(); - $this->error=$this->db->lasterror(); + $this->error = $this->db->lasterror(); return -1; } } @@ -286,7 +286,7 @@ class AssetType extends CommonObject dol_syslog("Asset_type::fetch", LOG_DEBUG); - $resql=$this->db->query($sql); + $resql = $this->db->query($sql); if ($resql) { if ($this->db->num_rows($resql)) @@ -306,7 +306,7 @@ class AssetType extends CommonObject } else { - $this->error=$this->db->lasterror(); + $this->error = $this->db->lasterror(); return -1; } } @@ -320,15 +320,15 @@ class AssetType extends CommonObject public function liste_array() { // phpcs:enable - global $conf,$langs; + global $conf, $langs; $assettypes = array(); $sql = "SELECT rowid, label as label"; - $sql.= " FROM ".MAIN_DB_PREFIX."asset_type"; - $sql.= " WHERE entity IN (".getEntity('asset_type').")"; + $sql .= " FROM ".MAIN_DB_PREFIX."asset_type"; + $sql .= " WHERE entity IN (".getEntity('asset_type').")"; - $resql=$this->db->query($sql); + $resql = $this->db->query($sql); if ($resql) { $nump = $this->db->num_rows($resql); @@ -365,13 +365,13 @@ class AssetType extends CommonObject { global $conf, $user; - $ret=array(); + $ret = array(); $sql = "SELECT a.rowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."asset as a"; - $sql.= " WHERE a.entity IN (".getEntity('asset').")"; - $sql.= " AND a.fk_asset_type = ".$this->id; - if (! empty($excludefilter)) $sql.=' AND ('.$excludefilter.')'; + $sql .= " FROM ".MAIN_DB_PREFIX."asset as a"; + $sql .= " WHERE a.entity IN (".getEntity('asset').")"; + $sql .= " AND a.fk_asset_type = ".$this->id; + if (!empty($excludefilter)) $sql .= ' AND ('.$excludefilter.')'; dol_syslog(get_class($this)."::listAssetsForGroup", LOG_DEBUG); $resql = $this->db->query($sql); @@ -379,31 +379,31 @@ class AssetType extends CommonObject { while ($obj = $this->db->fetch_object($resql)) { - if (! array_key_exists($obj->rowid, $ret)) + if (!array_key_exists($obj->rowid, $ret)) { if ($mode < 2) { - $assetstatic=new Asset($this->db); + $assetstatic = new Asset($this->db); if ($mode == 1) { $assetstatic->fetch($obj->rowid, '', '', '', false, false); } else { $assetstatic->fetch($obj->rowid); } - $ret[$obj->rowid]=$assetstatic; + $ret[$obj->rowid] = $assetstatic; } - else $ret[$obj->rowid]=$obj->rowid; + else $ret[$obj->rowid] = $obj->rowid; } } $this->db->free($resql); - $this->asset=$ret; + $this->asset = $ret; return $ret; } else { - $this->error=$this->db->lasterror(); + $this->error = $this->db->lasterror(); return -1; } } @@ -420,15 +420,15 @@ class AssetType extends CommonObject { global $langs; - $result=''; - $label=$langs->trans("ShowTypeCard", $this->label); + $result = ''; + $label = $langs->trans("ShowTypeCard", $this->label); $linkstart = ''; - $linkend=''; + $linkend = ''; $result .= $linkstart; - if ($withpicto) $result.=img_object(($notooltip?'':$label), ($this->picto?$this->picto:'generic'), ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1); - if ($withpicto != 2) $result.= ($maxlen?dol_trunc($this->label, $maxlen):$this->label); + if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + if ($withpicto != 2) $result .= ($maxlen ?dol_trunc($this->label, $maxlen) : $this->label); $result .= $linkend; return $result; @@ -448,13 +448,13 @@ class AssetType extends CommonObject // Initialize parameters $this->id = 0; $this->ref = 'ATSPEC'; - $this->specimen=1; + $this->specimen = 1; - $this->label='ASSET TYPE SPECIMEN'; - $this->note='This is a note'; + $this->label = 'ASSET TYPE SPECIMEN'; + $this->note = 'This is a note'; // Assets of this asset type is just me - $this->asset=array( + $this->asset = array( $user->id => $user ); } diff --git a/htdocs/asset/list.php b/htdocs/asset/list.php index be681ac5c13..2a9657baf90 100644 --- a/htdocs/asset/list.php +++ b/htdocs/asset/list.php @@ -412,7 +412,7 @@ print ''."\n"; // Fields title label // -------------------------------------------------------------------- print ''; -foreach($object->fields as $key => $val) +foreach ($object->fields as $key => $val) { $cssforfield = (empty($val['css']) ? '' : $val['css']); if ($key == 'status') $cssforfield .= ($cssforfield ? ' ' : '').'center'; @@ -427,8 +427,8 @@ foreach($object->fields as $key => $val) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields -$parameters=array('arrayfields'=>$arrayfields,'param'=>$param,'sortfield'=>$sortfield,'sortorder'=>$sortorder); -$reshook=$hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook +$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); +$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', 'align="center"', $sortfield, $sortorder, 'maxwidthsearch ')."\n"; @@ -436,7 +436,7 @@ print ''."\n"; // Detect if we need a fetch on each output line -$needToFetchEachLine=0; +$needToFetchEachLine = 0; if (is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) { foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) @@ -448,19 +448,19 @@ if (is_array($extrafields->attributes[$object->table_element]['computed']) && co // Loop on record // -------------------------------------------------------------------- -$i=0; -$totalarray=array(); +$i = 0; +$totalarray = array(); while ($i < ($limit ? min($num, $limit) : $num)) { $obj = $db->fetch_object($resql); - if (empty($obj)) break; // Should not happen + if (empty($obj)) break; // Should not happen // Store properties in $object $object->setVarsFromFetchObj($obj); // Show here line of result print ''; - foreach($object->fields as $key => $val) + foreach ($object->fields as $key => $val) { $cssforfield = (empty($val['css']) ? '' : $val['css']); if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) $cssforfield .= ($cssforfield ? ' ' : '').'center'; diff --git a/htdocs/asset/type.php b/htdocs/asset/type.php index 9f5f8597663..542dbc8e23d 100644 --- a/htdocs/asset/type.php +++ b/htdocs/asset/type.php @@ -609,37 +609,15 @@ if ($rowid > 0) print $object->showOptionals($extrafields, 'edit', $parameters); } - print ''; + // Other attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; - // Extra field - if (empty($reshook)) - { - print '

'; - foreach ($extrafields->attributes[$object->element]['label'] as $key=>$label) - { - if (isset($_POST["options_".$key])) { - if (is_array($_POST["options_".$key])) { - // $_POST["options"] is an array but following code expects a comma separated string - $value = implode(",", $_POST["options_".$key]); - } else { - $value = $_POST["options_".$key]; - } - } else { - $value = $adht->array_options["options_".$key]; - } - print '\n"; - } - print '
'.$label.''; - print $extrafields->showInputField($key, $value); - print "


'; - } + print ''; dol_fiche_end(); - print '
'; - print ''; - print '     '; - print ''; + print '
'; + print '   '; print '
'; print ""; diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php index 828d2ecff50..5cd988a5bed 100644 --- a/htdocs/barcode/printsheet.php +++ b/htdocs/barcode/printsheet.php @@ -278,6 +278,7 @@ dol_htmloutput_errors($mesg); print '
'; print ''; print ''; +print ''; print '
'; diff --git a/htdocs/blockedlog/admin/blockedlog.php b/htdocs/blockedlog/admin/blockedlog.php index 065dd4cda9e..1ef35942d1e 100644 --- a/htdocs/blockedlog/admin/blockedlog.php +++ b/htdocs/blockedlog/admin/blockedlog.php @@ -28,9 +28,9 @@ require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; // Load translation files required by the page -$langs->loadLangs(array("admin","other","blockedlog")); +$langs->loadLangs(array("admin", "other", "blockedlog")); -if (! $user->admin || empty($conf->blockedlog->enabled)) accessforbidden(); +if (!$user->admin || empty($conf->blockedlog->enabled)) accessforbidden(); $action = GETPOST('action', 'alpha'); $backtopage = GETPOST('backtopage', 'alpha'); @@ -40,11 +40,12 @@ $backtopage = GETPOST('backtopage', 'alpha'); * Actions */ +$reg = array(); if (preg_match('/set_(.*)/', $action, $reg)) { - $code=$reg[1]; + $code = $reg[1]; $values = GETPOST($code); - if(is_array($values))$values = implode(',', $values); + if (is_array($values)) $values = implode(',', $values); if (dolibarr_set_const($db, $code, $values, 'chaine', 0, '', $conf->entity) > 0) { @@ -59,7 +60,7 @@ if (preg_match('/set_(.*)/', $action, $reg)) if (preg_match('/del_(.*)/', $action, $reg)) { - $code=$reg[1]; + $code = $reg[1]; if (dolibarr_del_const($db, $code, 0) > 0) { Header("Location: ".$_SERVER["PHP_SELF"]); @@ -76,22 +77,22 @@ if (preg_match('/del_(.*)/', $action, $reg)) * View */ -$form=new Form($db); +$form = new Form($db); $block_static = new BlockedLog($db); llxHeader('', $langs->trans("BlockedLogSetup")); -$linkback=''; +$linkback = ''; if (GETPOST('withtab', 'alpha')) { - $linkback=''.$langs->trans("BackToModuleList").''; + $linkback = ''.$langs->trans("BackToModuleList").''; } print load_fiche_titre($langs->trans("ModuleSetup").' '.$langs->trans('BlockedLog'), $linkback); if (GETPOST('withtab', 'alpha')) { - $head=blockedlogadmin_prepare_head(); + $head = blockedlogadmin_prepare_head(); dol_fiche_head($head, 'blockedlog', '', -1); } @@ -134,16 +135,16 @@ print ''; print ''; $sql = "SELECT rowid, code as code_iso, code_iso as code_iso3, label, favorite"; -$sql.= " FROM ".MAIN_DB_PREFIX."c_country"; -$sql.= " WHERE active > 0"; +$sql .= " FROM ".MAIN_DB_PREFIX."c_country"; +$sql .= " WHERE active > 0"; -$countryArray=array(); -$resql=$db->query($sql); +$countryArray = array(); +$resql = $db->query($sql); if ($resql) { while ($obj = $db->fetch_object($resql)) { - $countryArray[$obj->code_iso] = ($obj->code_iso && $langs->transnoentitiesnoconv("Country".$obj->code_iso)!="Country".$obj->code_iso?$langs->transnoentitiesnoconv("Country".$obj->code_iso):($obj->label!='-'?$obj->label:'')); + $countryArray[$obj->code_iso] = ($obj->code_iso && $langs->transnoentitiesnoconv("Country".$obj->code_iso) != "Country".$obj->code_iso ? $langs->transnoentitiesnoconv("Country".$obj->code_iso) : ($obj->label != '-' ? $obj->label : '')); } } @@ -159,8 +160,8 @@ print ''; print ''; print ''; print $langs->trans("ListOfTrackedEvents").''; -$arrayoftrackedevents=$block_static->trackedevents; -foreach($arrayoftrackedevents as $key => $val) +$arrayoftrackedevents = $block_static->trackedevents; +foreach ($arrayoftrackedevents as $key => $val) { print $key.' - '.$langs->trans($val).'
'; } diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index 3f1be6c7e4c..81b5f858c9b 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -520,7 +520,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''."\n"; // Common attributes - $keyforbreak = 'efficiency'; + $keyforbreak = 'duration'; include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; // Other attributes diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index ddfb5e78d17..b53e2a7bc88 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -95,7 +95,7 @@ class BOM extends CommonObject 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'notnull'=>-1,), 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php:1:(finished IS NULL or finished <> 0)', 'label'=>'Product', 'enabled'=>1, 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'help'=>'ProductBOMHelp'), 'qty' => array('type'=>'real', 'label'=>'Quantity', 'enabled'=>1, 'visible'=>1, 'default'=>1, 'position'=>55, 'notnull'=>1, 'isameasure'=>'1', 'css'=>'maxwidth75imp'), - 'efficiency' => array('type'=>'real', 'label'=>'ManufacturingEfficiency', 'enabled'=>1, 'visible'=>-1, 'default'=>1, 'position'=>100, 'notnull'=>0, 'css'=>'maxwidth50imp', 'help'=>'ValueOfMeansLoss'), + //'efficiency' => array('type'=>'real', 'label'=>'ManufacturingEfficiency', 'enabled'=>1, 'visible'=>-1, 'default'=>1, 'position'=>100, 'notnull'=>0, 'css'=>'maxwidth50imp', 'help'=>'ValueOfMeansLossForProductProduced'), 'duration' => array('type'=>'duration', 'label'=>'EstimatedDuration', 'enabled'=>1, 'visible'=>-1, 'position'=>101, 'notnull'=>-1, 'css'=>'maxwidth50imp', 'help'=>'EstimatedDurationDesc'), 'fk_warehouse' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php:0', 'label'=>'WarehouseForProduction', 'enabled'=>1, 'visible'=>-1, 'position'=>102), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>-2, 'position'=>161, 'notnull'=>-1,), @@ -561,7 +561,7 @@ class BOM extends CommonObject { $num = $this->ref; } - $this->newref = $num; + $this->newref = dol_sanitizeFileName($num); // Validate $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; @@ -1056,7 +1056,7 @@ class BOMLine extends CommonObjectLine 'qty' => array('type'=>'double(24,8)', 'label'=>'Quantity', 'enabled'=>1, 'visible'=>1, 'position'=>100, 'notnull'=>1, 'isameasure'=>'1',), 'qty_frozen' => array('type'=>'smallint', 'label'=>'QuantityFrozen', 'enabled'=>1, 'visible'=>1, 'default'=>0, 'position'=>105, 'css'=>'maxwidth50imp', 'help'=>'QuantityConsumedInvariable'), 'disable_stock_change' => array('type'=>'smallint', 'label'=>'DisableStockChange', 'enabled'=>1, 'visible'=>1, 'default'=>0, 'position'=>108, 'css'=>'maxwidth50imp', 'help'=>'DisableStockChangeHelp'), - //'efficiency' => array('type'=>'double(24,8)', 'label'=>'ManufacturingEfficiency', 'enabled'=>1, 'visible'=>0, 'default'=>1, 'position'=>110, 'notnull'=>1, 'css'=>'maxwidth50imp', 'help'=>'ValueOfEfficiencyConsumedMeans'), + 'efficiency' => array('type'=>'double(24,8)', 'label'=>'ManufacturingEfficiency', 'enabled'=>1, 'visible'=>0, 'default'=>1, 'position'=>110, 'notnull'=>1, 'css'=>'maxwidth50imp', 'help'=>'ValueOfEfficiencyConsumedMeans'), 'position' => array('type'=>'integer', 'label'=>'Rank', 'enabled'=>1, 'visible'=>0, 'default'=>0, 'position'=>200, 'notnull'=>1,), 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>1000, 'notnull'=>-1,), ); diff --git a/htdocs/bom/tpl/objectline_create.tpl.php b/htdocs/bom/tpl/objectline_create.tpl.php index 7f3072d8051..445466a27a1 100644 --- a/htdocs/bom/tpl/objectline_create.tpl.php +++ b/htdocs/bom/tpl/objectline_create.tpl.php @@ -98,18 +98,18 @@ if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) if (!empty($conf->global->ENTREPOT_EXTRA_STATUS)) { // hide products in closed warehouse, but show products for internal transfer - $form->select_produits(GETPOST('idprod'), 'idprod', $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, 'warehouseopen,warehouseinternal', GETPOST('combinations', 'array')); + $form->select_produits(GETPOST('idprod', 'int'), 'idprod', $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, 'warehouseopen,warehouseinternal', GETPOST('combinations', 'array')); } else { - $form->select_produits(GETPOST('idprod'), 'idprod', $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, '', GETPOST('combinations', 'array')); + $form->select_produits(GETPOST('idprod', 'int'), 'idprod', $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, '', GETPOST('combinations', 'array')); } echo ''; } $coldisplay++; -print ''; if ($conf->global->PRODUCT_USE_UNITS) @@ -128,11 +128,10 @@ $coldisplay++; print ''; -//$coldisplay++; -//print ''; - +$coldisplay++; +print ''; $coldisplay += $colspan; print ''; print ''; if (is_object($objectline)) { - print $objectline->showOptionals($extrafields, 'edit', array('style'=>$bcnd[$var], 'colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1); + print $objectline->showOptionals($extrafields, 'edit', array('style'=>$bcnd[$var], 'colspan'=>$coldisplay), '', '', 1); } ?> diff --git a/htdocs/bom/tpl/objectline_edit.tpl.php b/htdocs/bom/tpl/objectline_edit.tpl.php index 17d01e07fd9..04c84f9c1b0 100644 --- a/htdocs/bom/tpl/objectline_edit.tpl.php +++ b/htdocs/bom/tpl/objectline_edit.tpl.php @@ -124,9 +124,9 @@ $coldisplay++; print ''; -//$coldisplay++; -//print ''; +$coldisplay++; +print ''; $coldisplay+=$colspan; print ''; print ''; if (is_object($objectline)) { - print $objectline->showOptionals($extrafields, 'edit', array('style'=>$bcnd[$var], 'colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1); + print $objectline->showOptionals($extrafields, 'edit', array('style'=>$bcnd[$var], 'colspan'=>$coldisplay), '', '', 1); } print "\n"; diff --git a/htdocs/bom/tpl/objectline_title.tpl.php b/htdocs/bom/tpl/objectline_title.tpl.php index 706f71af7ec..138a0b9aa58 100644 --- a/htdocs/bom/tpl/objectline_title.tpl.php +++ b/htdocs/bom/tpl/objectline_title.tpl.php @@ -66,7 +66,7 @@ print ''; // Efficiency -//print ''; +print ''; print ''; // No width to allow autodim diff --git a/htdocs/bom/tpl/objectline_view.tpl.php b/htdocs/bom/tpl/objectline_view.tpl.php index 16d7d427c75..16aa5382f53 100644 --- a/htdocs/bom/tpl/objectline_view.tpl.php +++ b/htdocs/bom/tpl/objectline_view.tpl.php @@ -98,10 +98,10 @@ $coldisplay++; echo $line->disable_stock_change ? yn($line->disable_stock_change) : ''; // Yes, it is a quantity, not a price, but we just want the formating role of function price print ''; -//print ''; +print ''; if ($this->status == 0 && ($object_rights->write) && $action != 'selectlines' ) { print ''; //Line extrafield if (!empty($extrafields)) { - print $line->showOptionals($extrafields, 'view', array('style'=>'class="drag drop oddeven"', 'colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1); + print $line->showOptionals($extrafields, 'view', array('style'=>'class="drag drop oddeven"', 'colspan'=>$coldisplay), '', '', 1); } print "\n"; diff --git a/htdocs/bookmarks/bookmarks.lib.php b/htdocs/bookmarks/bookmarks.lib.php index 8d772bf5b33..9e69eda2cd3 100644 --- a/htdocs/bookmarks/bookmarks.lib.php +++ b/htdocs/bookmarks/bookmarks.lib.php @@ -21,132 +21,6 @@ * \brief File with library for bookmark module */ -/** - * Add area with bookmarks in menu - * - * @return string - */ -function printBookmarksList() -{ - global $conf, $user, $db, $langs; - - $ret = ''."\n"; - - if (! empty($conf->use_javascript_ajax)) { // Bookmark autosubmit can't work when javascript is off. - require_once DOL_DOCUMENT_ROOT.'/bookmarks/class/bookmark.class.php'; - if (! isset($conf->global->BOOKMARKS_SHOW_IN_MENU)) $conf->global->BOOKMARKS_SHOW_IN_MENU=5; - - $langs->load("bookmarks"); - - $url= $_SERVER["PHP_SELF"]; - - if (! empty($_SERVER["QUERY_STRING"])) - { - $url.=(dol_escape_htmltag($_SERVER["QUERY_STRING"])?'?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]):''); - } - else - { - global $sortfield,$sortorder; - $tmpurl=''; - // No urlencode, all param $url will be urlencoded later - if ($sortfield) $tmpurl.=($tmpurl?'&':'').'sortfield='.$sortfield; - if ($sortorder) $tmpurl.=($tmpurl?'&':'').'sortorder='.$sortorder; - if (is_array($_POST)) - { - foreach($_POST as $key => $val) - { - if (preg_match('/^search_/', $key) && $val != '') $tmpurl.=($tmpurl?'&':'').$key.'='.$val; - } - } - $url.=($tmpurl?'?'.$tmpurl:''); - } - - // Menu bookmark - $ret = ''."\n"; - - $ret.= ''."\n"; - $ret.= ''; - $ret.= ''; - $ret.= ''; - $ret.= ''; - - $ret.=ajax_combobox('boxbookmark'); - - $ret.=''; - } - - $ret.= ''."\n"; - - return $ret; -} - - /** * Add area with bookmarks in top menu @@ -158,97 +32,91 @@ function printDropdownBookmarksList() global $conf, $user, $db, $langs; require_once DOL_DOCUMENT_ROOT.'/bookmarks/class/bookmark.class.php'; - if (! isset($conf->global->BOOKMARKS_SHOW_IN_MENU)) $conf->global->BOOKMARKS_SHOW_IN_MENU=5; + require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; $langs->load("bookmarks"); - $url= $_SERVER["PHP_SELF"]; + $url = $_SERVER["PHP_SELF"]; - if (! empty($_SERVER["QUERY_STRING"])) + if (!empty($_SERVER["QUERY_STRING"])) { - $url.=(dol_escape_htmltag($_SERVER["QUERY_STRING"])?'?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]):''); + $url .= (dol_escape_htmltag($_SERVER["QUERY_STRING"]) ? '?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]) : ''); } else { - global $sortfield,$sortorder; - $tmpurl=''; + global $sortfield, $sortorder; + $tmpurl = ''; // No urlencode, all param $url will be urlencoded later - if ($sortfield) $tmpurl.=($tmpurl?'&':'').'sortfield='.$sortfield; - if ($sortorder) $tmpurl.=($tmpurl?'&':'').'sortorder='.$sortorder; + if ($sortfield) $tmpurl .= ($tmpurl ? '&' : '').'sortfield='.$sortfield; + if ($sortorder) $tmpurl .= ($tmpurl ? '&' : '').'sortorder='.$sortorder; if (is_array($_POST)) { - foreach($_POST as $key => $val) + foreach ($_POST as $key => $val) { - if (preg_match('/^search_/', $key) && $val != '') $tmpurl.=($tmpurl?'&':'').$key.'='.$val; + if (preg_match('/^search_/', $key) && $val != '') $tmpurl .= ($tmpurl ? '&' : '').$key.'='.$val; } } - $url.=($tmpurl?'?'.$tmpurl:''); + $url .= ($tmpurl ? '?'.$tmpurl : ''); } $searchForm = ''."\n"; - $searchForm.= ''; - $searchForm.= ''; - $searchForm.= ''; + $searchForm .= ''; + $searchForm .= ''; + $searchForm .= ''; + $searchForm .= ''; // Url to list bookmark $listbtn = ''; - $listbtn.= ' '.$langs->trans('Bookmarks').''; + $listbtn .= ''.$langs->trans('Bookmarks').''; // Url to go on create new bookmark page $newbtn = ''; - if (! empty($user->rights->bookmark->creer)) + if (!empty($user->rights->bookmark->creer)) { //$urltoadd=DOL_URL_ROOT.'/bookmarks/card.php?action=create&urlsource='.urlencode($url).'&url='.urlencode($url); - $urltoadd=DOL_URL_ROOT.'/bookmarks/card.php?action=create&url='.urlencode($url); - $newbtn.= ''; - $newbtn.= img_picto('', 'bookmark').' '.dol_escape_htmltag($langs->trans('AddThisPageToBookmarks')).''; + $urltoadd = DOL_URL_ROOT.'/bookmarks/card.php?action=create&url='.urlencode($url); + $newbtn .= ''; + $newbtn .= img_picto('', 'bookmark', '', false, 0, 0, '', 'paddingright').dol_escape_htmltag($langs->trans('AddThisPageToBookmarks')).''; } - - $bookmarkList=''; - $html= ''; - if (! empty($conf->global->BOOKMARKS_SHOW_IN_MENU)) { - $html.= ' + $html = ' '; - } - $html.= ' + $html .= ' '; - $html.= ' + $html .= ' '; - if (! empty($conf->global->BOOKMARKS_SHOW_IN_MENU)) { - $html .= ''; - } return $html; } diff --git a/htdocs/cashdesk/tpl/facturation1.tpl.php b/htdocs/cashdesk/tpl/facturation1.tpl.php index f3b76cbaed6..f1e19b4df20 100644 --- a/htdocs/cashdesk/tpl/facturation1.tpl.php +++ b/htdocs/cashdesk/tpl/facturation1.tpl.php @@ -21,14 +21,14 @@ */ // Protection to avoid direct call of template -if (empty($langs) || ! is_object($langs)) +if (empty($langs) || !is_object($langs)) { print "Error, template page can't be called as URL"; exit; } // Load translation files required by the page -$langs->loadLangs(array("main","bills","cashdesk")); +$langs->loadLangs(array("main", "bills", "cashdesk")); // Object $form must de defined @@ -64,7 +64,7 @@ $id = $obj_facturation->id(); // Si trop d'articles ont ete trouves, on n'affiche que les X premiers (defini dans le fichier de configuration) ... $nbtoshow = $nbr_enreg; -if (! empty($conf_taille_listes) && $nbtoshow > $conf_taille_listes) $nbtoshow = $conf_taille_listes; +if (!empty($conf_taille_listes) && $nbtoshow > $conf_taille_listes) $nbtoshow = $conf_taille_listes; for ($i = 0; $i < $nbtoshow; $i++) { @@ -77,8 +77,8 @@ for ($i = 0; $i < $nbtoshow; $i++) $label = $tab_designations[$i]['label']; print ''."\n"; } @@ -101,23 +101,23 @@ for ($i = 0; $i < $nbtoshow; $i++) @@ -152,7 +152,7 @@ for ($i = 0; $i < $nbtoshow; $i++) diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 39f94db02eb..ac4e5b030c1 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -167,8 +167,9 @@ class Categorie extends CommonObject 'member' => 'adherent', 'contact' => 'socpeople', 'user' => 'user', - 'account' => 'bank_account', - 'project' => 'projet', + 'account' => 'bank_account', // old for bank account + 'bank_account' => 'bank_account', + 'project' => 'projet', 'warehouse'=> 'entrepot', 'actioncomm' => 'actioncomm', ); @@ -774,7 +775,7 @@ class Categorie extends CommonObject /** * Return list of fetched instance of elements having this category * - * @param string $type Type of category ('customer', 'supplier', 'contact', 'product', 'member') + * @param string $type Type of category ('customer', 'supplier', 'contact', 'product', 'member', ...) * @param int $onlyids Return only ids of objects (consume less memory) * @param int $limit Limit * @param int $offset Offset @@ -1957,4 +1958,56 @@ class Categorie extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables, 1); } + + /** + * Return the addtional SQL JOIN query for filtering a list by a category + * + * @param string $type The category type (e.g Categorie::TYPE_WAREHOUSE) + * @param string $rowIdName The name of the row id inside the whole sql query (e.g. "e.rowid") + * @return string A additional SQL JOIN query + */ + public static function getFilterJoinQuery($type, $rowIdName) + { + return " LEFT JOIN ".MAIN_DB_PREFIX."categorie_".$type." as cp" + . " ON ".$rowIdName." = cp.fk_".$type; + } + + /** + * Return the addtional SQL SELECT query for filtering a list by a category + * + * @param string $type The category type (e.g Categorie::TYPE_WAREHOUSE) + * @param string $rowIdName The name of the row id inside the whole sql query (e.g. "e.rowid") + * @param Array $searchList A list with the selected categories + * @return string A additional SQL SELECT query + */ + public static function getFilterSelectQuery($type, $rowIdName, $searchList) + { + if (empty($searchList) && !is_array($searchList)) + { + return ""; + } + + foreach ($searchList as $searchCategory) + { + if (intval($searchCategory) == -2) + { + $searchCategorySqlList[] = " cp.fk_categorie IS NULL"; + } + elseif (intval($searchCategory) > 0) + { + $searchCategorySqlList[] = " ".$rowIdName + ." IN (SELECT fk_".$type." FROM ".MAIN_DB_PREFIX."categorie_".$type + ." WHERE fk_categorie = ".$searchCategory.")"; + } + } + + if (!empty($searchCategorySqlList)) + { + return " AND (".implode(' AND ', $searchCategorySqlList).")"; + } + else + { + return ""; + } + } } diff --git a/htdocs/categories/index.php b/htdocs/categories/index.php index bb876cb0533..d96fddca150 100644 --- a/htdocs/categories/index.php +++ b/htdocs/categories/index.php @@ -161,6 +161,15 @@ $cate_arbo = $categstatic->get_full_arbo($typetext); // Define fulltree array $fulltree = $cate_arbo; +// Load possible missing includes +if($conf->global->CATEGORY_SHOW_COUNTS) +{ + if ($type == Categorie::TYPE_MEMBER) require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; + if ($type == Categorie::TYPE_ACCOUNT) require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; + if ($type == Categorie::TYPE_PROJECT) require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + if ($type == Categorie::TYPE_USER) require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; +} + // Define data (format for treeview) $data = array(); $data[] = array('rowid'=>0, 'fk_menu'=>-1, 'title'=>"racine", 'mainmenu'=>'', 'leftmenu'=>'', 'fk_mainmenu'=>'', 'fk_leftmenu'=>''); @@ -173,10 +182,19 @@ foreach ($fulltree as $key => $val) $li = $categstatic->getNomUrl(1, '', 60); $desc = dol_htmlcleanlastbr($val['description']); + $counter = ''; + + if($conf->global->CATEGORY_SHOW_COUNTS) + { + // we need only a count of the elements, so it is enough to consume only the id's from the database + $elements = $categstatic->getObjectsInCateg($type, 1); + $counter = ""; + } + $data[] = array( 'rowid'=>$val['rowid'], 'fk_menu'=>$val['fk_parent'], - 'entry'=>'
'; +print ''; print ''; print ''; -//print ''; -//print ''; +print ''; +print ''; @@ -141,7 +140,7 @@ print '
disable_stock_change?' checked="checked"':'')).'">'; print ''; -//print ''; +print ''; @@ -138,7 +138,7 @@ print '
'.$form->textwithpicto($langs->trans('QtyFro print ''.$form->textwithpicto($langs->trans('DisableStockChange'), $langs->trans('DisableStockChangeHelp')).''.$form->textwithpicto($langs->trans('ManufacturingEfficiency'), $langs->trans('XXX')).''.$form->textwithpicto($langs->trans('ManufacturingEfficiency'), $langs->trans('ValueOfMeansLoss')).''; -//$coldisplay++; -//echo $line->efficiency; -//print ''; +$coldisplay++; +echo $line->efficiency; +print ''; @@ -156,7 +156,7 @@ print '
- + - + vatrate; // To get vat rate we just have selected + $vatrate = $obj_facturation->vatrate; // To get vat rate we just have selected $buyer = new Societe($db); if ($_SESSION["CASHDESK_ID_THIRDPARTY"] > 0) $buyer->fetch($_SESSION["CASHDESK_ID_THIRDPARTY"]); - echo $form->load_tva('selTva', (isset($_POST["selTva"])?GETPOST("selTva", 'alpha', 2):$vatrate), $mysoc, $buyer, 0, 0, '', false, -1); + echo $form->load_tva('selTva', (GETPOSTISSET("selTva") ? GETPOST("selTva", 'alpha', 2) : $vatrate), $mysoc, $buyer, 0, 0, '', false, -1); ?> - + ".(is_countable($elements) ? count($elements) : '0')."
'. + 'entry'=>'
color ? ' style="background: #'.$categstatic->color.';"' : ' style="background: #aaa"').'>'.$li.'
'.$counter. //''. ''. '
color ? ' style="background: #'.$categstatic->color.';"' : ' style="background: #aaa"').'>'.$li.''.dolGetFirstLineOfText($desc).''.img_view().'
' diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php index 7f4156a6d15..5d81ccd7d63 100644 --- a/htdocs/categories/viewcat.php +++ b/htdocs/categories/viewcat.php @@ -144,6 +144,13 @@ if ($id > 0 && $removeelem > 0) $result = $tmpobject->fetch($removeelem); $elementtype = 'project'; } + elseif ($type == Categorie::TYPE_USER && $user->rights->user->user->creer) + { + require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; + $tmpobject = new User($db); + $result = $tmpobject->fetch($removeelem); + $elementtype = 'user'; + } $result = $object->del_type($tmpobject, $elementtype); if ($result < 0) dol_print_error('', $object->error); @@ -207,7 +214,7 @@ elseif ($type == Categorie::TYPE_MEMBER) $title = $langs->trans("MembersCateg elseif ($type == Categorie::TYPE_CONTACT) $title = $langs->trans("ContactCategoriesShort"); elseif ($type == Categorie::TYPE_ACCOUNT) $title = $langs->trans("AccountsCategoriesShort"); elseif ($type == Categorie::TYPE_PROJECT) $title = $langs->trans("ProjectsCategoriesShort"); -elseif ($type == Categorie::TYPE_USER) $title = $langs->trans("ProjectsCategoriesShort"); +elseif ($type == Categorie::TYPE_USER) $title = $langs->trans("UsersCategoriesShort"); else $title = $langs->trans("Category"); $head = categories_prepare_head($object, $type); @@ -834,6 +841,53 @@ if ($type == Categorie::TYPE_PROJECT) } } +// List of users +if ($type == Categorie::TYPE_USER) +{ + require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; + + $users = $object->getObjectsInCateg("user"); + if ($users < 0) + { + dol_print_error($db, $object->error, $object->errors); + } + else + { + print "
"; + print "\n"; + print ''."\n"; + + if (count($users) > 0) + { + // Use "$userentry" here, because "$user" is the current user + foreach ($users as $key => $userentry) + { + print "\t".''."\n"; + print '\n"; + print '\n"; + + // Link to delete from category + print '\n"; + } + } + else + { + print ''; + } + print "
'.$langs->trans("Users").' '.count($users).'
'; + print $userentry->getNomUrl(1); + print "'.$userentry->job."'; + if ($user->rights->user->user->creer) + { + print ""; + print $langs->trans("DeleteFromCat"); + print img_picto($langs->trans("DeleteFromCat"), 'unlink'); + print ""; + } + print "
'.$langs->trans("ThisCategoryHasNoUsers").'
\n"; + } +} + // End of page llxFooter(); $db->close(); diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index c17f9cc9c1b..07cd885698e 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -840,7 +840,7 @@ if ($action == 'create') print ''; print ''; print ''; - if ($backtopage) print ''; + if ($backtopage) print ''; if (empty($conf->global->AGENDA_USE_EVENT_TYPE)) print ''; if (GETPOST("actioncode", 'aZ09') == 'AC_RDV') print load_fiche_titre($langs->trans("AddActionRendezVous"), '', 'title_agenda'); @@ -1070,7 +1070,7 @@ if ($action == 'create') $numproject = $formproject->select_projects((!empty($societe->id) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1); print ' '; - $urloption = '?action=create'; + $urloption = '?action=create&donotclearsession=1'; $url = dol_buildpath('comm/action/card.php', 2).$urloption; // update task list @@ -1249,7 +1249,7 @@ if ($id > 0) print ''; print ''; print ''; - if ($backtopage) print ''; + if ($backtopage) print ''; if (empty($conf->global->AGENDA_USE_EVENT_TYPE)) print ''; dol_fiche_head($head, 'card', $langs->trans("Action"), 0, 'action'); @@ -1479,10 +1479,10 @@ if ($id > 0) $langs->load("projects"); print ''.$langs->trans("Project").''; - $numprojet = $formproject->select_projects(($object->socid > 0 ? $object->socid : -1), $object->fk_project, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0); + $numprojet = $formproject->select_projects(($object->socid > 0 ? $object->socid : -1), $object->fk_project, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, 'maxwidth500'); if ($numprojet == 0) { - print '   '.$langs->trans("AddProject").''; + print '   '; } print ''; } @@ -1503,7 +1503,7 @@ if ($id > 0) { print ''; - $urloption = '?action=create'; // we use create not edit for more flexibility + $urloption = '?action=create&donotclearsession=1'; // we use create not edit for more flexibility $url = DOL_URL_ROOT.'/comm/action/card.php'.$urloption; // update task list @@ -1825,7 +1825,7 @@ if ($id > 0) // Description print ''.$langs->trans("Description").''; - print dol_htmlentitiesbr($object->note); + print dol_string_onlythesehtmltags(dol_htmlentitiesbr($object->note_private)); print ''; // Other attributes diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index f75244dcf7d..5a9c5277ccd 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -455,6 +455,7 @@ class ActionComm extends CommonObject $sql .= "durationp,"; // deprecated $sql .= "fk_action,"; $sql .= "code,"; + $sql .= "ref_ext,"; $sql .= "fk_soc,"; $sql .= "fk_project,"; $sql .= "note,"; @@ -484,6 +485,7 @@ class ActionComm extends CommonObject $sql .= ((isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '') ? "'".$this->db->escape($this->durationp)."'" : "null").", "; // deprecated $sql .= (isset($this->type_id) ? $this->type_id : "null").","; $sql .= ($code ? ("'".$code."'") : "null").", "; + $sql .= ($this->ref_ext ? ("'".$this->db->idate($this->ref_ext)."'") : "null").", "; $sql .= ((isset($this->socid) && $this->socid > 0) ? $this->socid : "null").", "; $sql .= ((isset($this->fk_project) && $this->fk_project > 0) ? $this->fk_project : "null").", "; $sql .= " '".$this->db->escape($this->note_private ? $this->note_private : $this->note)."', "; diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php index 3ac82178810..895136f82f0 100644 --- a/htdocs/comm/action/list.php +++ b/htdocs/comm/action/list.php @@ -43,7 +43,7 @@ $action = GETPOST('action', 'alpha'); $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'actioncommlist'; // To manage different context of search $resourceid = GETPOST("search_resourceid", "int") ?GETPOST("search_resourceid", "int") : GETPOST("resourceid", "int"); $pid = GETPOST("search_projectid", 'int', 3) ?GETPOST("search_projectid", 'int', 3) : GETPOST("projectid", 'int', 3); -$status = (GETPOST("search_status", 'alpha') != '') ?GETPOST("search_status", 'alpha') : GETPOST("status", 'alpha'); +$search_status = (GETPOST("search_status", 'alpha') != '') ?GETPOST("search_status", 'alpha') : GETPOST("status", 'alpha'); $type = GETPOST('search_type', 'alphanohtml') ?GETPOST('search_type', 'alphanohtml') : GETPOST('type', 'alphanohtml'); $optioncss = GETPOST('optioncss', 'alpha'); $year = GETPOST("year", 'int'); @@ -67,8 +67,8 @@ $search_note = GETPOST('search_note', 'alpha'); $dateselect = dol_mktime(0, 0, 0, GETPOST('dateselectmonth', 'int'), GETPOST('dateselectday', 'int'), GETPOST('dateselectyear', 'int')); $datestart = dol_mktime(0, 0, 0, GETPOST('datestartmonth', 'int'), GETPOST('datestartday', 'int'), GETPOST('datestartyear', 'int')); $dateend = dol_mktime(0, 0, 0, GETPOST('dateendmonth', 'int'), GETPOST('dateendday', 'int'), GETPOST('dateendyear', 'int')); -if ($status == '' && !isset($_GET['status']) && !isset($_POST['status'])) $status = (empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); -if (empty($action) && !isset($_GET['action']) && !isset($_POST['action'])) $action = (empty($conf->global->AGENDA_DEFAULT_VIEW) ? 'show_month' : $conf->global->AGENDA_DEFAULT_VIEW); +if ($search_status == '' && !GETPOSTISSET('search_status')) $search_status = (empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); +if (empty($action) && !GETPOSTISSET('action')) $action = (empty($conf->global->AGENDA_DEFAULT_VIEW) ? 'show_month' : $conf->global->AGENDA_DEFAULT_VIEW); $filter = GETPOST("search_filter", 'alpha', 3) ?GETPOST("search_filter", 'alpha', 3) : GETPOST("filter", 'alpha', 3); $filtert = GETPOST("search_filtert", "int", 3) ?GETPOST("search_filtert", "int", 3) : GETPOST("filtert", "int", 3); @@ -100,12 +100,12 @@ $offset = $limit * $page; if (!$sortorder) { $sortorder = "DESC,DESC"; - if ($status == 'todo') $sortorder = "DESC,DESC"; + if ($search_status == 'todo') $sortorder = "DESC,DESC"; } if (!$sortfield) { $sortfield = "a.datep,a.id"; - if ($status == 'todo') $sortfield = "a.datep,a.id"; + if ($search_status == 'todo') $sortfield = "a.datep,a.id"; } // Security check @@ -184,7 +184,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_note = ''; $datestart = ''; $dateend = ''; - $status = ''; + $search_status = ''; $search_array_options = array(); } @@ -218,7 +218,7 @@ if ($actioncode != '') { } else $param .= "&search_actioncode=".urlencode($actioncode); } if ($resourceid > 0) $param .= "&search_resourceid=".urlencode($resourceid); -if ($status != '' && $status > -1) $param .= "&search_status=".urlencode($status); +if ($search_status != '' && $search_status > -1) $param .= "&search_status=".urlencode($search_status); if ($filter) $param .= "&search_filter=".urlencode($filter); if ($filtert) $param .= "&search_filtert=".urlencode($filtert); if ($socid) $param .= "&search_socid=".urlencode($socid); @@ -309,12 +309,12 @@ if ($socid > 0) $sql .= " AND s.rowid = ".$socid; // We must filter on assignement table if ($filtert > 0 || $usergroup > 0) $sql .= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'"; if ($type) $sql .= " AND c.id = ".(int) $type; -if ($status == '0') { $sql .= " AND a.percent = 0"; } -if ($status == '-1') { $sql .= " AND a.percent = -1"; } // Not applicable -if ($status == '50') { $sql .= " AND (a.percent > 0 AND a.percent < 100)"; } // Running already started -if ($status == '100') { $sql .= " AND a.percent = 100"; } -if ($status == 'done') { $sql .= " AND (a.percent = 100)"; } -if ($status == 'todo') { $sql .= " AND (a.percent >= 0 AND a.percent < 100)"; } +if ($search_status == '0') { $sql .= " AND a.percent = 0"; } +if ($search_status == '-1') { $sql .= " AND a.percent = -1"; } // Not applicable +if ($search_status == '50') { $sql .= " AND (a.percent > 0 AND a.percent < 100)"; } // Running already started +if ($search_status == '100') { $sql .= " AND a.percent = 100"; } +if ($search_status == 'done') { $sql .= " AND (a.percent = 100)"; } +if ($search_status == 'todo') { $sql .= " AND (a.percent >= 0 AND a.percent < 100)"; } if ($search_id) $sql .= natural_search("a.id", $search_id, 1); if ($search_title) $sql .= natural_search("a.label", $search_title); if ($search_note) $sql .= natural_search('a.note', $search_note); @@ -397,7 +397,7 @@ if ($resql) print $nav; dol_fiche_head($head, $tabactive, $langs->trans('Agenda'), 0, 'action'); - print_actions_filter($form, $canedit, $status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid); + print_actions_filter($form, $canedit, $search_status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid); dol_fiche_end(); // Add link to show birthdays @@ -488,8 +488,8 @@ if ($resql) if (!empty($arrayfields['a.tms']['checked'])) print ''; if (!empty($arrayfields['a.percent']['checked'])) { print ''; - $formactions->form_select_status_action('formaction', $status, 1, 'status', 1, 2, 'minwidth100imp maxwidth125'); - print ajax_combobox('selectstatus'); + $formactions->form_select_status_action('formaction', $search_status, 1, 'search_status', 1, 2, 'minwidth100imp maxwidth125'); + print ajax_combobox('selectsearch_status'); print ''; } // Action column diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index 947d0a9d2f8..f906c4cab45 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -49,10 +49,10 @@ $usergroup = GETPOST("search_usergroup", "int", 3) ?GETPOST("search_usergroup", $showbirthday = 0; // If not choice done on calendar owner, we filter on user. -if (empty($filtert) && empty($conf->global->AGENDA_ALL_CALENDARS)) +/*if (empty($filtert) && empty($conf->global->AGENDA_ALL_CALENDARS)) { $filtert = $user->id; -} +}*/ $sortfield = GETPOST("sortfield", 'alpha'); $sortorder = GETPOST("sortorder", 'alpha'); diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index b5164d6078c..14929faf2ba 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -666,7 +666,7 @@ if ($object->id > 0) $now = dol_now(); /* - * Last proposals + * Latest proposals */ if (!empty($conf->propal->enabled) && $user->rights->propal->lire) { @@ -738,7 +738,7 @@ if ($object->id > 0) } /* - * Last orders + * Latest orders */ if (!empty($conf->commande->enabled) && $user->rights->commande->lire) { @@ -824,7 +824,7 @@ if ($object->id > 0) } /* - * Last shipments + * Latest shipments */ if (!empty($conf->expedition->enabled) && $user->rights->expedition->lire) { @@ -897,7 +897,7 @@ if ($object->id > 0) } /* - * Last linked contracts + * Latest linked contracts */ if (!empty($conf->contrat->enabled) && $user->rights->contrat->lire) { @@ -967,7 +967,7 @@ if ($object->id > 0) } /* - * Last interventions + * Latest interventions */ if (!empty($conf->ficheinter->enabled) && $user->rights->ficheinter->lire) { @@ -1028,7 +1028,7 @@ if ($object->id > 0) } /* - * Last invoices templates + * Latest invoices templates */ if (!empty($conf->facture->enabled) && $user->rights->facture->lire) { @@ -1063,7 +1063,7 @@ if ($object->id > 0) print ''; print ''; - print ''; + print '
'.$link.'
'; - print ''; + print ''; - print ''; + print ''; // For year $prevyear = $year - 1; $nextyear = $year + 1; $link = "".img_previous('', 'class="valignbottom"')." ".$langs->trans("Year")." ".img_next('', 'class="valignbottom"').""; - print ''; - print ''; + print ''; - print ''; + print ''; } if ($mode == 'showalltime') { - print ''; + print ''; } -print '
'; + print ''; print ''; } diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php index 111b411549e..0bb38aeaa38 100644 --- a/htdocs/comm/index.php +++ b/htdocs/comm/index.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2019 Nicolas ZABOURI + * Copyright (C) 2020 Pierre Ardoin * * 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 @@ -149,6 +150,9 @@ if (!empty($conf->propal->enabled) && $user->rights->propal->lire) $sql = "SELECT p.rowid, p.ref, p.ref_client, p.total_ht, p.tva as total_tva, p.total as total_ttc, s.rowid as socid, s.nom as name, s.client, s.canvas"; $sql .= ", s.code_client"; + $sql .= ", s.email"; + $sql .= ", s.entity"; + $sql .= ", s.code_compta"; $sql .= " FROM ".MAIN_DB_PREFIX."propal as p"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; @@ -193,6 +197,9 @@ if (!empty($conf->propal->enabled) && $user->rights->propal->lire) $companystatic->code_client = $obj->code_client; $companystatic->code_fournisseur = $obj->code_fournisseur; $companystatic->canvas = $obj->canvas; + $companystatic->entity = $obj->entity; + $companystatic->email = $obj->email; + $companystatic->code_compta = $obj->code_compta; print $companystatic->getNomUrl(1, 'customer', 16); print ''; print ''; @@ -233,6 +240,9 @@ if (!empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposa $sql = "SELECT p.rowid, p.ref, p.total_ht, p.tva as total_tva, p.total as total_ttc, s.rowid as socid, s.nom as name, s.client, s.canvas"; $sql .= ", s.code_client"; + $sql .= ", s.code_fournisseur"; + $sql .= ", s.entity"; + $sql .= ", s.email"; $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal as p"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; @@ -276,6 +286,8 @@ if (!empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposa $companystatic->code_client = $obj->code_client; $companystatic->code_fournisseur = $obj->code_fournisseur; $companystatic->canvas = $obj->canvas; + $companystatic->entity = $obj->entity; + $companystatic->email = $obj->email; print $companystatic->getNomUrl(1, 'supplier', 16); print ''; print ''; @@ -315,6 +327,9 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire) $sql = "SELECT c.rowid, c.ref, c.ref_client, c.total_ht, c.tva as total_tva, c.total_ttc, s.rowid as socid, s.nom as name, s.client, s.canvas"; $sql .= ", s.code_client"; + $sql .= ", s.email"; + $sql .= ", s.entity"; + $sql .= ", s.code_compta"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; @@ -358,6 +373,8 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire) $companystatic->code_client = $obj->code_client; $companystatic->code_fournisseur = $obj->code_fournisseur; $companystatic->canvas = $obj->canvas; + $companystatic->email = $obj->email; + $companystatic->entity = $obj->entity; print $companystatic->getNomUrl(1, 'customer', 16); print ''; if (!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT)) { @@ -404,6 +421,8 @@ if (!empty($conf->fournisseur->enabled) && $user->rights->fournisseur->commande- $sql = "SELECT cf.rowid, cf.ref, cf.ref_supplier, cf.total_ttc, s.rowid as socid, s.nom as name, s.client, s.canvas"; $sql .= ", s.code_client"; $sql .= ", s.code_fournisseur"; + $sql .= ", s.entity"; + $sql .= ", s.email"; $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as cf"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; @@ -447,6 +466,8 @@ if (!empty($conf->fournisseur->enabled) && $user->rights->fournisseur->commande- $companystatic->code_client = $obj->code_client; $companystatic->code_fournisseur = $obj->code_fournisseur; $companystatic->canvas = $obj->canvas; + $companystatic->entity = $obj->entity; + $companystatic->email = $obj->email; print $companystatic->getNomUrl(1, 'supplier', 16); print ''; if (!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT)) { @@ -496,6 +517,9 @@ if (!empty($conf->societe->enabled) && $user->rights->societe->lire) $sql = "SELECT s.rowid, s.nom as name, s.client, s.datec, s.tms, s.canvas"; $sql .= ", s.code_client"; + $sql .= ", s.code_compta"; + $sql .= ", s.entity"; + $sql .= ", s.email"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql .= " WHERE s.client IN (1, 2, 3)"; @@ -532,6 +556,9 @@ if (!empty($conf->societe->enabled) && $user->rights->societe->lire) $companystatic->code_client = $objp->code_client; $companystatic->code_fournisseur = $objp->code_fournisseur; $companystatic->canvas = $objp->canvas; + $companystatic->code_compta = $objp->code_compta; + $companystatic->entity = $objp->entity; + $companystatic->email = $objp->email; print ''; print ''; print ''; print ''; print ''; @@ -628,7 +659,7 @@ if ($user->rights->agenda->myactions->read) /* - * Last contracts + * Latest contracts */ if (!empty($conf->contrat->enabled) && $user->rights->contrat->lire && 0) // TODO A REFAIRE DEPUIS NOUVEAU CONTRAT { @@ -636,7 +667,9 @@ if (!empty($conf->contrat->enabled) && $user->rights->contrat->lire && 0) // TOD $sql = "SELECT s.nom as name, s.rowid, s.canvas, "; $sql .= ", s.code_client"; - $sql .= " c.statut, c.rowid as contratid, p.ref, c.mise_en_service as datemes, c.fin_validite as datefin, c.date_cloture as dateclo"; + $sql .= ", s.entity"; + $sql .= ", s.email"; + $sql .= ", c.statut, c.rowid as contratid, p.ref, c.fin_validite as datefin, c.date_cloture as dateclo"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."contrat as c"; $sql .= ", ".MAIN_DB_PREFIX."product as p"; @@ -673,6 +706,8 @@ if (!empty($conf->contrat->enabled) && $user->rights->contrat->lire && 0) // TOD $companystatic->code_client = $objp->code_client; $companystatic->code_fournisseur = $objp->code_fournisseur; $companystatic->canvas = $objp->canvas; + $companystatic->entity = $objp->entity; + $companystatic->email = $objp->email; print $companystatic->getNomUrl(1, 'customer', 44); print ''."\n"; print "\n"; @@ -697,6 +732,8 @@ if (!empty($conf->propal->enabled) && $user->rights->propal->lire) $langs->load("propal"); $sql = "SELECT s.nom as name, s.rowid, s.code_client"; + $sql .= ", s.entity"; + $sql .= ", s.email"; $sql .= ", p.rowid as propalid, p.entity, p.total as total_ttc, p.total_ht, p.tva as total_tva, p.ref, p.ref_client, p.fk_statut, p.datep as dp, p.fin_validite as dfv"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."propal as p"; @@ -760,6 +797,8 @@ if (!empty($conf->propal->enabled) && $user->rights->propal->lire) $companystatic->code_client = $obj->code_client; $companystatic->code_fournisseur = $obj->code_fournisseur; $companystatic->canvas = $obj->canvas; + $companystatic->entity = $obj->entity; + $companystatic->email = $obj->email; print $companystatic->getNomUrl(1, 'customer', 44); print ''; print ''; print ''; + print ''; print ''; - print ''; + print ''; - print ''; + print ''; // Errors to - print ''; // Status - print ''; + print ''; // Nb of distinct emails - print ''; - print ''; } else diff --git a/htdocs/comm/mailing/class/advtargetemailing.class.php b/htdocs/comm/mailing/class/advtargetemailing.class.php index 0b47d8c4aa5..da1775955b7 100644 --- a/htdocs/comm/mailing/class/advtargetemailing.class.php +++ b/htdocs/comm/mailing/class/advtargetemailing.class.php @@ -141,7 +141,7 @@ class AdvanceTargetingMailing extends CommonObject $sql .= " ".(!isset($this->filtervalue) ? 'NULL' : "'".$this->db->escape($this->filtervalue)."'").","; $sql .= " ".$user->id.","; $sql .= " '".$this->db->idate(dol_now())."',"; - $sql .= " null"; + $sql.= " ".$user->id; $sql .= ")"; $this->db->begin(); diff --git a/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php b/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php index 08736a3d268..b9782515735 100644 --- a/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php +++ b/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php @@ -65,7 +65,7 @@ class FormAdvTargetEmailing extends Form $sql .= " FROM ".MAIN_DB_PREFIX."c_prospectlevel"; $sql .= " WHERE active > 0"; $sql .= " ORDER BY sortorder"; - dol_syslog(get_class($this).'::multiselectProspectionStatus sql='.$sql, LOG_DEBUG); + $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -111,7 +111,6 @@ class FormAdvTargetEmailing extends Form $sql .= " WHERE active = 1 AND code<>''"; $sql .= " ORDER BY code ASC"; - dol_syslog(get_class($this)."::select_country sql=".$sql); $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -260,7 +259,6 @@ class FormAdvTargetEmailing extends Form } // $sql.= ' WHERE entity = '.$conf->entity; - dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -297,7 +295,7 @@ class FormAdvTargetEmailing extends Form $sql = "SELECT rowid, code, label as civilite, active FROM ".MAIN_DB_PREFIX."c_civility"; $sql .= " WHERE active = 1"; - dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG); + dol_syslog(__METHOD__, LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { @@ -385,7 +383,7 @@ class FormAdvTargetEmailing extends Form $sql = "SELECT rowid, label FROM ".MAIN_DB_PREFIX."categorie"; $sql .= " WHERE type=".$type; - dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG); + dol_syslog(__METHOD__, LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { @@ -418,9 +416,10 @@ class FormAdvTargetEmailing extends Form * @param integer $selected defaut selected * @param integer $showempty empty lines * @param string $type_element Type element. Example: 'mailing' + * @param string $morecss More CSS * @return string HTML combo */ - public function selectAdvtargetemailingTemplate($htmlname = 'template_id', $selected = 0, $showempty = 0, $type_element = 'mailing') + public function selectAdvtargetemailingTemplate($htmlname = 'template_id', $selected = 0, $showempty = 0, $type_element = 'mailing', $morecss = '') { global $conf, $user, $langs; @@ -431,10 +430,10 @@ class FormAdvTargetEmailing extends Form $sql .= " WHERE type_element='$type_element'"; $sql .= " ORDER BY c.name"; - dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG); + dol_syslog(__METHOD__, LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { - $out .= ''; if ($showempty) $out .= ''; $num = $this->db->num_rows($resql); diff --git a/htdocs/comm/mailing/class/mailing.class.php b/htdocs/comm/mailing/class/mailing.class.php index 32637096910..553c5e79c15 100644 --- a/htdocs/comm/mailing/class/mailing.class.php +++ b/htdocs/comm/mailing/class/mailing.class.php @@ -662,10 +662,12 @@ class Mailing extends CommonObject $labelStatusShort = array(); $labelStatus[-1] = $langs->trans('MailingStatusError'); + $labelStatus[0] = $langs->trans('MailingStatusNotSent'); $labelStatus[1] = $langs->trans('MailingStatusSent'); $labelStatus[2] = $langs->trans('MailingStatusRead'); $labelStatus[3] = $langs->trans('MailingStatusNotContact'); $labelStatusShort[-1] = $langs->trans('MailingStatusError'); + $labelStatusShort[0] = $langs->trans('MailingStatusNotSent'); $labelStatusShort[1] = $langs->trans('MailingStatusSent'); $labelStatusShort[2] = $langs->trans('MailingStatusRead'); $labelStatusShort[3] = $langs->trans('MailingStatusNotContact'); diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index 1337c62da94..9326082b193 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -1,6 +1,7 @@ * Copyright (C) 2016 Laurent Destailleur + * Copyright (C) 2020 Thibault FOUCART * * 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 @@ -64,11 +65,65 @@ class Proposals extends DolibarrApi */ public function get($id, $contact_list = 1) { + return $this->_fetch($id, '', '', $contact_list); + } + + /** + * Get properties of an proposal object by ref + * + * Return an array with proposal informations + * + * @param string $ref Ref of object + * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id + * @return array|mixed data without useless information + * + * @url GET ref/{ref} + * + * @throws RestException + */ + public function getByRef($ref, $contact_list = 1) + { + return $this->_fetch('', $ref, '', $contact_list); + } + + /** + * Get properties of an proposal object by ref_ext + * + * Return an array with proposal informations + * + * @param string $ref_ext External reference of object + * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id + * @return array|mixed data without useless information + * + * @url GET ref_ext/{ref_ext} + * + * @throws RestException + */ + public function getByRefExt($ref_ext, $contact_list = 1) + { + return $this->_fetch('', '', $ref_ext, $contact_list); + } + + /** + * Get properties of an proposal object + * + * Return an array with proposal informations + * + * @param int $id ID of order + * @param string $ref Ref of object + * @param string $ref_ext External reference of object + * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id + * @return array|mixed data without useless information + * + * @throws RestException + */ + private function _fetch($id, $ref = '', $ref_ext = '', $contact_list = 1) + { if(! DolibarrApiAccess::$user->rights->propal->lire) { throw new RestException(401); } - $result = $this->propal->fetch($id); + $result = $this->propal->fetch($id, $ref, $ref_ext); if( ! $result ) { throw new RestException(404, 'Commercial Proposal not found'); } @@ -377,8 +432,9 @@ class Proposals extends DolibarrApi * @url DELETE {id}/lines/{lineid} * * @return int - * @throws 401 - * @throws 404 + * + * @throws RestException 401 + * @throws RestException 404 */ public function deleteLine($id, $lineid) { @@ -417,8 +473,9 @@ class Proposals extends DolibarrApi * @url POST {id}/contact/{contactid}/{type} * * @return int - * @throws 401 - * @throws 404 + * + * @throws RestException 401 + * @throws RestException 404 */ public function postContact($id, $contactid, $type) { @@ -458,9 +515,10 @@ class Proposals extends DolibarrApi * @url DELETE {id}/contact/{rowid} * * @return int - * @throws 401 - * @throws 404 - * @throws 500 + * + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 */ public function deleteContact($id, $rowid) { @@ -629,10 +687,10 @@ class Proposals extends DolibarrApi * * @url POST {id}/validate * - * @throws 304 - * @throws 401 - * @throws 404 - * @throws 500 + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 * * @return array */ diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 32c3d67a18b..bea546eeae8 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -223,6 +223,90 @@ class Propal extends CommonObject public $oldcopy; + + /** + * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * 'enabled' is a condition when the field must be managed. + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). + * 'css' is the CSS style to use on field. For example: 'maxwidth200' + * 'help' is a string visible as a tooltip on field + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // BEGIN MODULEBUILDER PROPERTIES + /** + * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields=array( + 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), + 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>15, 'index'=>1), + 'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>20), + 'ref_client' =>array('type'=>'varchar(255)', 'label'=>'RefCustomer', 'enabled'=>1, 'visible'=>-1, 'position'=>22), + 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'RefExt', 'enabled'=>1, 'visible'=>0, 'position'=>40), + 'ref_int' =>array('type'=>'varchar(255)', 'label'=>'RefInt', 'enabled'=>1, 'visible'=>0, 'position'=>45), // deprecated + 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'position'=>23), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>24), + 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>25), + 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>55), + 'datep' =>array('type'=>'date', 'label'=>'Date', 'enabled'=>1, 'visible'=>-1, 'position'=>60), + 'fin_validite' =>array('type'=>'datetime', 'label'=>'DateEnd', 'enabled'=>1, 'visible'=>-1, 'position'=>65), + 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>70), + 'date_cloture' =>array('type'=>'datetime', 'label'=>'DateClosing', 'enabled'=>1, 'visible'=>-1, 'position'=>75), + 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>80), + 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>85), + 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>90), + 'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user cloture', 'enabled'=>1, 'visible'=>-1, 'position'=>95), + 'price' =>array('type'=>'double', 'label'=>'Price', 'enabled'=>1, 'visible'=>-1, 'position'=>105), + 'remise_percent' =>array('type'=>'double', 'label'=>'RelativeDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>110), + 'remise_absolue' =>array('type'=>'double', 'label'=>'CustomerRelativeDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>115), + //'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>120), + 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>125, 'isameasure'=>1), + 'tva' =>array('type'=>'double(24,8)', 'label'=>'VAT', 'enabled'=>1, 'visible'=>-1, 'position'=>130, 'isameasure'=>1), + 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'LocalTax1', 'enabled'=>1, 'visible'=>-1, 'position'=>135, 'isameasure'=>1), + 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'LocalTax2', 'enabled'=>1, 'visible'=>-1, 'position'=>140, 'isameasure'=>1), + 'total' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>145, 'isameasure'=>1), + 'fk_account' =>array('type'=>'integer', 'label'=>'BankAccount', 'enabled'=>1, 'visible'=>-1, 'position'=>150), + 'fk_currency' =>array('type'=>'varchar(3)', 'label'=>'Currency', 'enabled'=>1, 'visible'=>-1, 'position'=>155), + 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'position'=>160), + 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>-1, 'position'=>165), + 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>170), + 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>175), + 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'PDFTemplate', 'enabled'=>1, 'visible'=>0, 'position'=>180), + 'date_livraison' =>array('type'=>'date', 'label'=>'DateDeliveryPlanned', 'enabled'=>1, 'visible'=>-1, 'position'=>185), + 'fk_shipping_method' =>array('type'=>'integer', 'label'=>'ShippingMethod', 'enabled'=>1, 'visible'=>-1, 'position'=>190), + 'fk_availability' =>array('type'=>'integer', 'label'=>'Availability', 'enabled'=>1, 'visible'=>-1, 'position'=>195), + 'fk_delivery_address' =>array('type'=>'integer', 'label'=>'DeliveryAddress', 'enabled'=>1, 'visible'=>0, 'position'=>200), // deprecated + 'fk_input_reason' =>array('type'=>'integer', 'label'=>'InputReason', 'enabled'=>1, 'visible'=>-1, 'position'=>205), + 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>215), + 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>220), + 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermLabel', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>225), + 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'MulticurrencyID', 'enabled'=>1, 'visible'=>-1, 'position'=>230), + 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCurrency', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>235), + 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>240, 'isameasure'=>1), + 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountHT', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>245, 'isameasure'=>1), + 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountVAT', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>250, 'isameasure'=>1), + 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountTTC', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>255, 'isameasure'=>1), + 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>-1, 'position'=>260), + 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), + 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900), + ); + // END MODULEBUILDER PROPERTIES + /** * Draft status */ @@ -1365,15 +1449,15 @@ class Propal extends CommonObject } /** - * Load a proposal from database and its ligne array + * Load a proposal from database. Get also lines. * * @param int $rowid id of object to load * @param string $ref Ref of proposal + * @param string $ref_ext Ref ext of proposal * @return int >0 if OK, <0 if KO */ - public function fetch($rowid, $ref = '') + public function fetch($rowid, $ref = '', $ref_ext = '') { - $sql = "SELECT p.rowid, p.ref, p.entity, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc"; $sql .= ", p.total, p.tva, p.localtax1, p.localtax2, p.total_ht"; $sql .= ", p.datec"; @@ -1437,8 +1521,13 @@ class Propal extends CommonObject $this->total_localtax1 = $obj->localtax1; $this->total_localtax2 = $obj->localtax2; $this->total_ttc = $obj->total; - $this->socid = $obj->fk_soc; - $this->fk_project = $obj->fk_project; + + $this->socid = $obj->fk_soc; + $this->thirdparty = null; // Clear if another value was already set by fetch_thirdparty + + $this->fk_project = $obj->fk_project; + $this->project = null; // Clear if another value was already set by fetch_projet + $this->modelpdf = $obj->model_pdf; $this->last_main_doc = $obj->last_main_doc; $this->note = $obj->note_private; // TODO deprecated @@ -1506,9 +1595,7 @@ class Propal extends CommonObject $this->lines = array(); - /* - * Lines - */ + // Lines $result = $this->fetch_lines(); if ($result < 0) { @@ -1801,7 +1888,7 @@ class Propal extends CommonObject { $num = $this->ref; } - $this->newref = $num; + $this->newref = dol_sanitizeFileName($num); $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; $sql .= " SET ref = '".$this->db->escape($num)."',"; @@ -3549,10 +3636,10 @@ class Propal extends CommonObject * @param string $get_params Parametres added to url * @param int $notooltip 1=Disable tooltip * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking - * @param int $addlinktonotes Add linkt to notes + * @param int $addlinktonotes -1=Disable, 0=Just add label show notes, 1=Add private note (only internal user), 2=Add public note (internal or external user), 3=Add private (internal user) and public note (internal and external user) * @return string String with URL */ - public function getNomUrl($withpicto = 0, $option = '', $get_params = '', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0) + public function getNomUrl($withpicto = 0, $option = '', $get_params = '', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1) { global $langs, $conf, $user; @@ -3618,21 +3705,45 @@ class Propal extends CommonObject if ($withpicto != 2) $result .= $this->ref; $result .= $linkend; - if ($addlinktonotes) - { - $txttoshow = ($user->socid > 0 ? $this->note_public : $this->note_private); - if ($txttoshow) - { - $notetoshow = $langs->trans("ViewPrivateNote").':
'.dol_string_nohtmltag($txttoshow, 1); - $result .= ' '; - $result .= ''; - $result .= img_picto('', 'note'); - $result .= ''; - //$result.=img_picto($langs->trans("ViewNote"),'object_generic'); - //$result.=''; - $result .= ''; - } - } + if ($addlinktonotes >= 0) { + $txttoshow = ''; + + if ($addlinktonotes == 0) { + if (!empty($this->note_private) || !empty($this->note_public)) { + $txttoshow = $langs->trans('ViewPrivateNote'); + } + } elseif ($addlinktonotes == 1) { + if (!empty($this->note_private)) { + $txttoshow .= ($user->socid > 0 ? '' : dol_string_nohtmltag($this->note_private, 1)); + } + } elseif ($addlinktonotes == 2) { + if (!empty($this->note_public)) { + $txttoshow .= dol_string_nohtmltag($this->note_public, 1); + } + } elseif ($addlinktonotes == 3) { + if ($user->socid > 0) { + if (!empty($this->note_public)) { + $txttoshow .= dol_string_nohtmltag($this->note_public, 1); + } + } else { + if (!empty($this->note_public)) { + $txttoshow .= dol_string_nohtmltag($this->note_public, 1); + } + if (!empty($this->note_private)) { + if (!empty($txttoshow)) $txttoshow .= '

'; + $txttoshow .= dol_string_nohtmltag($this->note_private, 1); + } + } + } + + if ($txttoshow) { + $result .= ' '; + $result .= ''; + $result .= img_picto('', 'note'); + $result .= ''; + $result .= ''; + } + } return $result; } diff --git a/htdocs/comm/propal/class/propalestats.class.php b/htdocs/comm/propal/class/propalestats.class.php index 0859bdb7974..ee42ca26471 100644 --- a/htdocs/comm/propal/class/propalestats.class.php +++ b/htdocs/comm/propal/class/propalestats.class.php @@ -210,10 +210,11 @@ class PropaleStats extends Stats /** * Return nb, amount of predefined product for year * - * @param int $year Year to scan - * @return array Array of values + * @param int $year Year to scan + * @param int $limit Limit + * @return array Array of values */ - public function getAllByProduct($year) + public function getAllByProduct($year, $limit = 10) { global $user; @@ -227,6 +228,6 @@ class PropaleStats extends Stats $sql.= $this->db->order('nb', 'DESC'); //$sql.= $this->db->plimit(20); - return $this->_getAllByProduct($sql); + return $this->_getAllByProduct($sql, $limit); } } diff --git a/htdocs/comm/propal/contact.php b/htdocs/comm/propal/contact.php index c052c234eab..e396a5f8b92 100644 --- a/htdocs/comm/propal/contact.php +++ b/htdocs/comm/propal/contact.php @@ -21,7 +21,7 @@ /** * \file htdocs/comm/propal/contact.php * \ingroup propal - * \brief Onglet de gestion des contacts de propal + * \brief Tab to manage contacts/adresses of proposal */ require '../../main.inc.php'; diff --git a/htdocs/comm/propal/index.php b/htdocs/comm/propal/index.php index 11bb4292036..11a9fa8eff6 100644 --- a/htdocs/comm/propal/index.php +++ b/htdocs/comm/propal/index.php @@ -141,10 +141,10 @@ if ($resql) include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; $dolgraph = new DolGraph(); $dolgraph->SetData($dataseries); - $dolgraph->setShowLegend(1); + $dolgraph->setShowLegend(2); $dolgraph->setShowPercent(1); $dolgraph->SetType(array('pie')); - $dolgraph->setWidth('100%'); + $dolgraph->setHeight('200'); $dolgraph->draw('idgraphthirdparties'); print $dolgraph->show($total ? 0 : 1); diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 13ab3a1ae17..365308a224b 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -69,6 +69,11 @@ $search_societe = GETPOST('search_societe', 'alpha'); $search_montant_ht = GETPOST('search_montant_ht', 'alpha'); $search_montant_vat = GETPOST('search_montant_vat', 'alpha'); $search_montant_ttc = GETPOST('search_montant_ttc', 'alpha'); +$search_multicurrency_code = GETPOST('search_multicurrency_code', 'alpha'); +$search_multicurrency_tx = GETPOST('search_multicurrency_tx', 'alpha'); +$search_multicurrency_montant_ht = GETPOST('search_multicurrency_montant_ht', 'alpha'); +$search_multicurrency_montant_vat = GETPOST('search_multicurrency_montant_vat', 'alpha'); +$search_multicurrency_montant_ttc = GETPOST('search_multicurrency_montant_ttc', 'alpha'); $search_login = GETPOST('search_login', 'alpha'); $search_product_category = GETPOST('search_product_category', 'int'); $search_town = GETPOST('search_town', 'alpha'); @@ -162,8 +167,15 @@ $arrayfields = array( 'p.total_ht'=>array('label'=>"AmountHT", 'checked'=>1), 'p.total_vat'=>array('label'=>"AmountVAT", 'checked'=>0), 'p.total_ttc'=>array('label'=>"AmountTTC", 'checked'=>0), - 'p.total_ht_invoiced'=>array('label'=>$langs->trans("AmountInvoicedHT"), 'checked'=>0, 'enabled'=>$conf->global->PROPOSAL_SHOW_INVOICED_AMOUNT), - 'p.total_invoiced'=>array('label'=>$langs->trans("AmountInvoicedTTC"), 'checked'=>0, 'enabled'=>$conf->global->PROPOSAL_SHOW_INVOICED_AMOUNT), + 'p.total_ht_invoiced'=>array('label'=>"AmountInvoicedHT", 'checked'=>0, 'enabled'=>! empty($conf->global->PROPOSAL_SHOW_INVOICED_AMOUNT)), + 'p.total_invoiced'=>array('label'=>"AmountInvoicedTTC", 'checked'=>0, 'enabled'=>! empty($conf->global->PROPOSAL_SHOW_INVOICED_AMOUNT)), + 'p.multicurrency_code'=>array('label'=>'Currency', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'p.multicurrency_tx'=>array('label'=>'CurrencyRate', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'p.multicurrency_total_ht'=>array('label'=>'MulticurrencyAmountHT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'p.multicurrency_total_vat'=>array('label'=>'MulticurrencyAmountVAT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'p.multicurrency_total_ttc'=>array('label'=>'MulticurrencyAmountTTC', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'p.multicurrency_total_ht_invoiced'=>array('label'=>'MulticurrencyAmountInvoicedHT', 'checked'=>0, 'enabled'=>! empty($conf->multicurrency->enabled) && ! empty($conf->global->PROPOSAL_SHOW_INVOICED_AMOUNT)), + 'p.multicurrency_total_invoiced'=>array('label'=>'MulticurrencyAmountInvoicedTTC', 'checked'=>0, 'enabled'=>! empty($conf->multicurrency->enabled) && ! empty($conf->global->PROPOSAL_SHOW_INVOICED_AMOUNT)), 'u.login'=>array('label'=>"Author", 'checked'=>1, 'position'=>10), 'sale_representative'=>array('label'=>"SaleRepresentativesOfThirdParty", 'checked'=>1), 'p.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500), @@ -209,6 +221,11 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_montant_ht = ''; $search_montant_vat = ''; $search_montant_ttc = ''; + $search_multicurrency_code = ''; + $search_multicurrency_tx = ''; + $search_multicurrency_montant_ht = ''; + $search_multicurrency_montant_vat = ''; + $search_multicurrency_montant_ttc = ''; $search_login = ''; $search_product_category = ''; $search_town = ''; @@ -269,6 +286,7 @@ $sql .= " typent.code as typent_code,"; $sql .= " ava.rowid as availability,"; $sql .= " state.code_departement as state_code, state.nom as state_name,"; $sql .= ' p.rowid, p.entity, p.note_private, p.total_ht, p.tva as total_vat, p.total as total_ttc, p.localtax1, p.localtax2, p.ref, p.ref_client, p.fk_statut, p.fk_user_author, p.datep as dp, p.fin_validite as dfv,p.date_livraison as ddelivery,'; +$sql .= ' p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva as multicurrency_total_vat, p.multicurrency_total_ttc,'; $sql .= ' p.datec as date_creation, p.tms as date_update, p.date_cloture as date_cloture,'; $sql .= ' p.note_public, p.note_private,'; $sql .= " pr.rowid as project_id, pr.ref as project_ref, pr.title as project_label,"; @@ -326,6 +344,11 @@ if ($search_login) $sql .= natural_search("u.login", $search_login); if ($search_montant_ht != '') $sql .= natural_search("p.total_ht", $search_montant_ht, 1); if ($search_montant_vat != '') $sql .= natural_search("p.tva", $search_montant_vat, 1); if ($search_montant_ttc != '') $sql .= natural_search("p.total", $search_montant_ttc, 1); +if ($search_multicurrency_code != '') $sql .= ' AND p.multicurrency_code = "' . $db->escape($search_multicurrency_code) . '"'; +if ($search_multicurrency_tx != '') $sql .= natural_search('p.multicurrency_tx', $search_multicurrency_tx, 1); +if ($search_multicurrency_montant_ht != '') $sql .= natural_search('p.multicurrency_total_ht', $search_multicurrency_montant_ht, 1); +if ($search_multicurrency_montant_vat != '') $sql .= natural_search('p.multicurrency_total_tva', $search_multicurrency_montant_vat, 1); +if ($search_multicurrency_montant_ttc != '') $sql .= natural_search('p.multicurrency_total_ttc', $search_multicurrency_montant_ttc, 1); if ($sall) { $sql .= natural_search(array_keys($fieldstosearchall), $sall); } @@ -428,6 +451,11 @@ if ($resql) if ($search_user > 0) $param .= '&search_user='.urlencode($search_user); if ($search_sale > 0) $param .= '&search_sale='.urlencode($search_sale); if ($search_montant_ht) $param .= '&search_montant_ht='.urlencode($search_montant_ht); + if ($search_multicurrency_code != '') $param .= '&search_multicurrency_code='.urlencode($search_multicurrency_code); + if ($search_multicurrency_tx != '') $param .= '&search_multicurrency_tx='.urlencode($search_multicurrency_tx); + if ($search_multicurrency_montant_ht != '') $param .= '&search_multicurrency_montant_ht='.urlencode($search_multicurrency_montant_ht); + if ($search_multicurrency_montant_vat != '') $param .= '&search_multicurrency_montant_vat='.urlencode($search_multicurrency_montant_vat); + if ($search_multicurrency_montant_ttc != '') $param .= '&search_multicurrency_montant_ttc='.urlencode($search_multicurrency_montant_ttc); if ($search_login) $param .= '&search_login='.urlencode($search_login); if ($search_town) $param .= '&search_town='.urlencode($search_town); if ($search_zip) $param .= '&search_zip='.urlencode($search_zip); @@ -677,6 +705,53 @@ if ($resql) print '
'; } + if (!empty($arrayfields['p.multicurrency_code']['checked'])) + { + // Currency + print ''; + } + if (!empty($arrayfields['p.multicurrency_tx']['checked'])) + { + // Currency rate + print ''; + } + if (!empty($arrayfields['p.multicurrency_total_ht']['checked'])) + { + // Amount + print ''; + } + if (!empty($arrayfields['p.multicurrency_total_vat']['checked'])) + { + // Amount + print ''; + } + if (!empty($arrayfields['p.multicurrency_total_ttc']['checked'])) + { + // Amount + print ''; + } + if (!empty($arrayfields['p.multicurrency_total_ht_invoiced']['checked'])) + { + // Amount invoiced + print ''; + } + if (!empty($arrayfields['p.multicurrency_total_invoiced']['checked'])) + { + // Amount invoiced + print ''; + } if (!empty($arrayfields['u.login']['checked'])) { // Author @@ -750,6 +825,13 @@ if ($resql) if (!empty($arrayfields['p.total_ttc']['checked'])) print_liste_field_titre($arrayfields['p.total_ttc']['label'], $_SERVER["PHP_SELF"], 'p.total', '', $param, 'class="right"', $sortfield, $sortorder); if (!empty($arrayfields['p.total_ht_invoiced']['checked'])) print_liste_field_titre($arrayfields['p.total_ht_invoiced']['label'], $_SERVER["PHP_SELF"], '', '', $param, 'class="right"', $sortfield, $sortorder); if (!empty($arrayfields['p.total_invoiced']['checked'])) print_liste_field_titre($arrayfields['p.total_invoiced']['label'], $_SERVER["PHP_SELF"], '', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['p.multicurrency_code']['checked'])) print_liste_field_titre($arrayfields['p.multicurrency_code']['label'], $_SERVER['PHP_SELF'], 'p.multicurrency_code', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['p.multicurrency_tx']['checked'])) print_liste_field_titre($arrayfields['p.multicurrency_tx']['label'], $_SERVER['PHP_SELF'], 'p.multicurrency_tx', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['p.multicurrency_total_ht']['checked'])) print_liste_field_titre($arrayfields['p.multicurrency_total_ht']['label'], $_SERVER['PHP_SELF'], 'p.multicurrency_total_ht', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['p.multicurrency_total_vat']['checked'])) print_liste_field_titre($arrayfields['p.multicurrency_total_vat']['label'], $_SERVER['PHP_SELF'], 'p.multicurrency_total_tva', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['p.multicurrency_total_ttc']['checked'])) print_liste_field_titre($arrayfields['p.multicurrency_total_ttc']['label'], $_SERVER['PHP_SELF'], 'p.multicurrency_total_ttc', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['p.multicurrency_total_ht_invoiced']['checked'])) print_liste_field_titre($arrayfields['p.multicurrency_total_ht_invoiced']['label'], $_SERVER["PHP_SELF"], '', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['p.multicurrency_total_invoiced']['checked'])) print_liste_field_titre($arrayfields['p.multicurrency_total_invoiced']['label'], $_SERVER["PHP_SELF"], '', '', $param, 'class="right"', $sortfield, $sortorder); if (!empty($arrayfields['u.login']['checked'])) print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER["PHP_SELF"], 'u.login', '', $param, 'align="center"', $sortfield, $sortorder); if (!empty($arrayfields['sale_representative']['checked'])) print_liste_field_titre($arrayfields['sale_representative']['label'], $_SERVER["PHP_SELF"], "", "", "$param", '', $sortfield, $sortorder); // Extra fields @@ -776,6 +858,7 @@ if ($resql) $objectstatic->id = $obj->rowid; $objectstatic->ref = $obj->ref; + $objectstatic->ref_client = $obj->ref_client; $objectstatic->note_public = $obj->note_public; $objectstatic->note_private = $obj->note_private; @@ -789,6 +872,29 @@ if ($resql) $projectstatic->ref = $obj->project_ref; $projectstatic->title = $obj->project_label; + $totalInvoicedHT = 0; + $totalInvoicedTTC = 0; + $multicurrency_totalInvoicedHT = 0; + $multicurrency_totalInvoicedTTC = 0; + + $TInvoiceData = $objectstatic->InvoiceArrayList($obj->rowid); + + if (!empty($TInvoiceData)) + { + foreach ($TInvoiceData as $invoiceData) + { + $invoice = new Facture($db); + $invoice->fetch($invoiceData->facid); + + if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS) && $invoice->type == Facture::TYPE_DEPOSIT) continue; + + $totalInvoicedHT += $invoice->total_ht; + $totalInvoicedTTC += $invoice->total_ttc; + $multicurrency_totalInvoicedHT += $invoice->multicurrency_total_ht; + $multicurrency_totalInvoicedTTC += $invoice->multicurrency_total_ttc; + } + } + print ''; if (!empty($arrayfields['p.ref']['checked'])) @@ -798,7 +904,7 @@ if ($resql) print '
'.$langs->trans("LatestCustomerTemplateInvoices", ($num <= $MAXLIST ? "" : $MAXLIST)).''.$langs->trans("AllCustomerTemplateInvoices").''.$num.''; print '
'.$langs->trans("LatestCustomerTemplateInvoices", ($num <= $MAXLIST ? "" : $MAXLIST)).''.$langs->trans("AllCustomerTemplateInvoices").''.$num.'
'.price($obj->total_ht).'
'.price($obj->total_ht).'
'.$companystatic->getNomUrl(1, 'customer', 48).''; @@ -560,6 +587,8 @@ if (!empty($conf->fournisseur->enabled) && $user->rights->societe->lire) $sql = "SELECT s.nom as name, s.rowid, s.datec as dc, s.canvas, s.tms as dm"; $sql .= ", s.code_fournisseur"; + $sql .= ", s.entity"; + $sql .= ", s.email"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql .= " WHERE s.fournisseur = 1"; @@ -591,6 +620,8 @@ if (!empty($conf->fournisseur->enabled) && $user->rights->societe->lire) $companystatic->code_client = $objp->code_client; $companystatic->code_fournisseur = $objp->code_fournisseur; $companystatic->canvas = $objp->canvas; + $companystatic->entity = $objp->entity; + $companystatic->email = $objp->email; print '
'.$companystatic->getNomUrl(1, 'supplier', 44).''.dol_print_date($db->jdate($objp->dm), 'day').'".$staticcontrat->LibStatut($obj->statut, 3)."
'; @@ -802,6 +841,8 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire) $sql = "SELECT s.nom as name, s.rowid, c.rowid as commandeid, c.total_ttc, c.total_ht, c.tva as total_tva, c.ref, c.ref_client, c.fk_statut, c.date_valid as dv, c.facture as billed"; $sql .= ", s.code_client"; + $sql .= ", s.entity"; + $sql .= ", s.email"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."commande as c"; if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; @@ -864,6 +905,8 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire) $companystatic->code_client = $obj->code_client; $companystatic->code_fournisseur = $obj->code_fournisseur; $companystatic->canvas = $obj->canvas; + $companystatic->entity = $obj->entity; + $companystatic->email = $obj->email; print $companystatic->getNomUrl(1, 'customer', 44); print ''; diff --git a/htdocs/comm/mailing/advtargetemailing.php b/htdocs/comm/mailing/advtargetemailing.php index 94e885d53dc..b85826339e5 100644 --- a/htdocs/comm/mailing/advtargetemailing.php +++ b/htdocs/comm/mailing/advtargetemailing.php @@ -423,24 +423,24 @@ if ($object->fetch($id) >= 0) { $linkback = ''.$langs->trans("BackToList").''; - print '
'.$langs->trans("Ref").'
'.$langs->trans("Ref").''; print $form->showrefnav($object, 'id', $linkback); print '
'.$langs->trans("MailTitle").''.$object->titre.'
'.$langs->trans("MailTitle").''.$object->titre.'
'.$langs->trans("MailFrom").''.dol_print_email($object->email_from, 0, 0, 0, 0, 1).'
'.$langs->trans("MailFrom").''.dol_print_email($object->email_from, 0, 0, 0, 0, 1).'
'.$langs->trans("MailErrorsTo").''.dol_print_email($object->email_errorsto, 0, 0, 0, 0, 1); + print '
'.$langs->trans("MailErrorsTo").''.dol_print_email($object->email_errorsto, 0, 0, 0, 0, 1); print '
'.$langs->trans("Status").''.$object->getLibStatut(4).'
'.$langs->trans("Status").''.$object->getLibStatut(4).'
'; + print '
'; print $langs->trans("TotalNbOfDistinctRecipients"); print ''; $nbemail = ($object->nbemail ? $object->nbemail : '0'); diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php index 3dcfdf9e451..41e49ed09b3 100644 --- a/htdocs/comm/mailing/cibles.php +++ b/htdocs/comm/mailing/cibles.php @@ -673,7 +673,8 @@ if ($object->fetch($id) >= 0) // Date sent print ' '.$langs->trans("MailingStatusNotSent"); + print ''; + print $object::libStatutDest($obj->statut, 2, ''); print ''; print ''; + print $form->selectMultiCurrency($search_multicurrency_code, 'search_multicurrency_code', 1); + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
'; // Picto + Ref print ''; // Warning $warnornote = ''; @@ -824,7 +930,7 @@ if ($resql) if (!empty($arrayfields['p.ref_client']['checked'])) { // Customer ref - print ''; if (!$i) $totalarray['nbfield']++; @@ -974,46 +1080,66 @@ if ($resql) $totalarray['val']['p.total_ttc'] += $obj->total_ttc; } // Amount invoiced - if (!empty($arrayfields['p.total_ht_invoiced']['checked'])) { - $totalInvoiced = 0; - $p = new Propal($db); - $TInvoiceData = $p->InvoiceArrayList($obj->rowid); - - if (!empty($TInvoiceData)) { - foreach ($TInvoiceData as $invoiceData) { - $invoice = new Facture($db); - $invoice->fetch($invoiceData->facid); - - if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS) && $invoice->type == Facture::TYPE_DEPOSIT) continue; - $totalInvoiced += $invoice->total_ht; - } - } - - print '\n"; + if (!empty($arrayfields['p.total_ht_invoiced']['checked'])) + { + print '\n"; if (!$i) $totalarray['nbfield']++; if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'p.total_ht_invoiced'; - $totalarray['val']['p.total_ht_invoiced'] += $obj->total_ht_invoiced; + $totalarray['val']['p.total_ht_invoiced'] += $totalInvoicedHT; } // Amount invoiced - if (!empty($arrayfields['p.total_invoiced']['checked'])) { - $totalInvoiced = 0; - $p = new Propal($db); - $TInvoiceData = $p->InvoiceArrayList($obj->rowid); - - if (!empty($TInvoiceData)) { - foreach ($TInvoiceData as $invoiceData) { - $invoice = new Facture($db); - $invoice->fetch($invoiceData->facid); - - if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS) && $invoice->type == Facture::TYPE_DEPOSIT) continue; - $totalInvoiced += $invoice->total_ttc; - } - } - - print '\n"; + if (!empty($arrayfields['p.total_invoiced']['checked'])) + { + print '\n"; if (!$i) $totalarray['nbfield']++; if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'p.total_invoiced'; - $totalarray['val']['p.total_invoiced'] += $obj->total_invoiced; + $totalarray['val']['p.total_invoiced'] += $totalInvoicedTTC; + } + + // Currency + if (!empty($arrayfields['p.multicurrency_code']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + + // Currency rate + if (!empty($arrayfields['p.multicurrency_tx']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount HT + if (!empty($arrayfields['p.multicurrency_total_ht']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount VAT + if (!empty($arrayfields['p.multicurrency_total_vat']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount TTC + if (!empty($arrayfields['p.multicurrency_total_ttc']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount invoiced + if (!empty($arrayfields['p.multicurrency_total_ht_invoiced']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount invoiced + if (!empty($arrayfields['p.multicurrency_total_invoiced']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; } $userstatic->id = $obj->fk_user_author; @@ -1039,9 +1165,7 @@ if ($resql) $nbofsalesrepresentative = count($listsalesrepresentatives); if ($nbofsalesrepresentative > 3) // We print only number { - print ''; print $nbofsalesrepresentative; - print ''; } elseif ($nbofsalesrepresentative > 0) { diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 902b773735a..651fa556e8a 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -111,6 +111,7 @@ if ($action == 'confirm_split' && GETPOST("confirm") == 'yes') $newdiscount1->description = $discount->description.' (1)'; $newdiscount2->description = $discount->description.' (2)'; } + $newdiscount1->fk_user = $discount->fk_user; $newdiscount2->fk_user = $discount->fk_user; $newdiscount1->fk_soc = $discount->fk_soc; @@ -121,7 +122,7 @@ if ($action == 'confirm_split' && GETPOST("confirm") == 'yes') $newdiscount2->datec = $discount->datec; $newdiscount1->tva_tx = $discount->tva_tx; $newdiscount2->tva_tx = $discount->tva_tx; - $newdiscount1->amount_ttc = $_POST["amount_ttc_1"]; + $newdiscount1->amount_ttc = $amount_ttc_1; $newdiscount2->amount_ttc = price2num($discount->amount_ttc - $newdiscount1->amount_ttc); $newdiscount1->amount_ht = price2num($newdiscount1->amount_ttc / (1 + $newdiscount1->tva_tx / 100), 'MT'); $newdiscount2->amount_ht = price2num($newdiscount2->amount_ttc / (1 + $newdiscount2->tva_tx / 100), 'MT'); diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 3c1bf672c0f..7db4d3c9767 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -93,25 +93,29 @@ $extrafields = new ExtraFields($db); $extrafields->fetch_name_optionals_label($object->table_element); // Load object -include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$hookmanager->initHooks(array('ordercard','globalcard')); +$hookmanager->initHooks(array('ordercard', 'globalcard')); $usercanread = $user->rights->commande->lire; $usercancreate = $user->rights->commande->creer; $usercanclose = $user->rights->commande->cloturer; $usercandelete = $user->rights->commande->supprimer; -$usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->order_advance->validate))); -$usercancancel = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->commande->order_advance->annuler))); +$usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->commande->order_advance->validate))); +$usercancancel = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->commande->order_advance->annuler))); $usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->commande->order_advance->send); $usercancreatepurchaseorder = $user->rights->fournisseur->commande->creer; -$permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php -$permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php -$permissiontoadd = $usercancreate; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php +$permissionnote = $usercancreate; // Used by the include of actions_setnotes.inc.php +$permissiondellink = $usercancreate; // Used by the include of actions_dellink.inc.php +$permissiontoadd = $usercancreate; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php +if (!empty($conf->expedition->enabled) && $conf->global->WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER = 1){ + if (empty($object->warehouse_id) && !empty($conf->global->MAIN_DEFAULT_WAREHOUSE)) $object->warehouse_id = $conf->global->MAIN_DEFAULT_WAREHOUSE; + if (empty($object->warehouse_id) && !empty($conf->global->MAIN_DEFAULT_WAREHOUSE_USER)) $object->warehouse_id = $user->fk_warehouse; +} /* * Actions @@ -1594,25 +1598,25 @@ if ($action == 'create' && $usercancreate) $note_public = $object->getDefaultCreateValueFor('note_public'); } - print ''; - print ''; + print ''; + print ''; print ''; - print '' . "\n"; - print ''; - print ''; - print ''; - if (!empty($currency_tx)) print ''; + print ''."\n"; + print ''; + print ''; + print ''; + if (!empty($currency_tx)) print ''; dol_fiche_head(''); print '
'; - print $objectstatic->getNomUrl(1, '', '', 0, 1, 1); + print $objectstatic->getNomUrl(1, '', '', 0, 1, (isset($conf->global->PROPAL_LIST_SHOW_NOTES) ? $conf->global->PROPAL_LIST_SHOW_NOTES : 1)); print ''; + print ''; print $obj->ref_client; print ''.price($totalInvoiced)."'.price($totalInvoicedHT)."'.price($totalInvoiced)."'.price($totalInvoicedTTC)."'.$obj->multicurrency_code . ' - ' . $langs->trans('Currency' . $obj->multicurrency_code)."'; + $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $obj->rowid, $obj->multicurrency_tx, 'none', $obj->multicurrency_code); + print "'.price($obj->multicurrency_total_ht)."'.price($obj->multicurrency_total_vat)."'.price($obj->multicurrency_total_ttc)."'.price($multicurrency_totalInvoicedHT)."'.price($multicurrency_totalInvoicedTTC)."
'; // Reference - print ''; + print ''; // Reference client - print ''; else print ''; @@ -2556,7 +2560,7 @@ if ($action == 'create' && $usercancreate) } // Valid - if ($object->statut == Commande::STATUS_DRAFT && $object->total_ttc >= 0 && $numlines > 0 && $usercanvalidate) + if ($object->statut == Commande::STATUS_DRAFT && ($object->total_ttc >= 0 || !empty($conf->global->ORDER_ENABLE_NEGATIVE)) && $numlines > 0 && $usercanvalidate) { print ''.$langs->trans('Validate').''; } @@ -2631,7 +2635,7 @@ if ($action == 'create' && $usercancreate) // Create bill and Classify billed // Note: Even if module invoice is not enabled, we should be able to use button "Classified billed" - if ($object->statut > Commande::STATUS_DRAFT && !$object->billed) { + if ($object->statut > Commande::STATUS_DRAFT && !$object->billed && $object->total_ttc >= 0) { if (!empty($conf->facture->enabled) && $user->rights->facture->creer && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) { print ''; } diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 5069135dd88..03cdf990071 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -64,7 +64,7 @@ class Orders extends DolibarrApi */ public function get($id, $contact_list = 1) { - return $this->_fetch($id, '', '', '', $contact_list); + return $this->_fetch($id, '', '', $contact_list); } /** @@ -82,7 +82,7 @@ class Orders extends DolibarrApi */ public function getByRef($ref, $contact_list = 1) { - return $this->_fetch('', $ref, '', '', $contact_list); + return $this->_fetch('', $ref, '', $contact_list); } /** @@ -100,7 +100,7 @@ class Orders extends DolibarrApi */ public function getByRefExt($ref_ext, $contact_list = 1) { - return $this->_fetch('', '', $ref_ext, '', $contact_list); + return $this->_fetch('', '', $ref_ext, $contact_list); } /** @@ -111,19 +111,18 @@ class Orders extends DolibarrApi * @param int $id ID of order * @param string $ref Ref of object * @param string $ref_ext External reference of object - * @param string $ref_int Internal reference of other objec * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id * @return array|mixed data without useless information * * @throws RestException */ - private function _fetch($id, $ref = '', $ref_ext = '', $ref_int = '', $contact_list = 1) + private function _fetch($id, $ref = '', $ref_ext = '', $contact_list = 1) { if(! DolibarrApiAccess::$user->rights->commande->lire) { throw new RestException(401); } - $result = $this->commande->fetch($id, $ref, $ref_ext, $ref_int); + $result = $this->commande->fetch($id, $ref, $ref_ext); if( ! $result ) { throw new RestException(404, 'Order not found'); } @@ -425,8 +424,9 @@ class Orders extends DolibarrApi * @url DELETE {id}/lines/{lineid} * * @return int - * @throws 401 - * @throws 404 + * + * @throws RestException 401 + * @throws RestException 404 */ public function deleteLine($id, $lineid) { @@ -463,8 +463,9 @@ class Orders extends DolibarrApi * @url POST {id}/contact/{contactid}/{type} * * @return int - * @throws 401 - * @throws 404 + * + * @throws RestException 401 + * @throws RestException 404 */ public function postContact($id, $contactid, $type) { @@ -499,9 +500,10 @@ class Orders extends DolibarrApi * @url DELETE {id}/contact/{rowid} * * @return int - * @throws 401 - * @throws 404 - * @throws 500 + * + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 */ public function deleteContact($id, $rowid) { @@ -617,10 +619,10 @@ class Orders extends DolibarrApi * * @url POST {id}/validate * - * @throws 304 - * @throws 401 - * @throws 404 - * @throws 500 + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 * * @return array */ @@ -670,11 +672,11 @@ class Orders extends DolibarrApi * * @return int * - * @throws 304 - * @throws 400 - * @throws 401 - * @throws 404 - * @throws 405 + * @throws RestException 304 + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 */ public function reopen($id) { @@ -709,10 +711,10 @@ class Orders extends DolibarrApi * * @return int * - * @throws 400 - * @throws 401 - * @throws 404 - * @throws 405 + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 */ public function setinvoiced($id) { @@ -849,10 +851,10 @@ class Orders extends DolibarrApi * @url POST /createfromproposal/{proposalid} * * @return int - * @throws 400 - * @throws 401 - * @throws 404 - * @throws 405 + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 */ public function createOrderFromProposal($proposalid) { diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 21b8c983d8e..ddd6d7723d5 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -101,6 +101,7 @@ class Commande extends CommonOrder /** * @var string Internal ref for order + * @deprecated */ public $ref_int; @@ -232,6 +233,94 @@ class Commande extends CommonOrder //! key of pos source ('0', '1', ...) public $pos_source; + + /** + * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * 'enabled' is a condition when the field must be managed. + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). + * 'css' is the CSS style to use on field. For example: 'maxwidth200' + * 'help' is a string visible as a tooltip on field + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // BEGIN MODULEBUILDER PROPERTIES + /** + * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields=array( + 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), + 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>20, 'index'=>1), + 'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>25), + 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'RefExt', 'enabled'=>1, 'visible'=>0, 'position'=>26), + 'ref_int' =>array('type'=>'varchar(255)', 'label'=>'RefInt', 'enabled'=>1, 'visible'=>0, 'position'=>27), // deprecated + 'ref_client' =>array('type'=>'varchar(255)', 'label'=>'RefCustomer', 'enabled'=>1, 'visible'=>-1, 'position'=>28), + 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>20), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>1, 'visible'=>-1, 'position'=>25), + 'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>55), + 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>56), + 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>60), + 'date_cloture' =>array('type'=>'datetime', 'label'=>'DateClosing', 'enabled'=>1, 'visible'=>-1, 'position'=>65), + 'date_commande' =>array('type'=>'date', 'label'=>'Date', 'enabled'=>1, 'visible'=>-1, 'position'=>70), + 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>75), + 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>80), + 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>85), + 'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserClosing', 'enabled'=>1, 'visible'=>-1, 'position'=>90), + 'source' =>array('type'=>'smallint(6)', 'label'=>'Source', 'enabled'=>1, 'visible'=>-1, 'position'=>95), + //'amount_ht' =>array('type'=>'double(24,8)', 'label'=>'AmountHT', 'enabled'=>1, 'visible'=>-1, 'position'=>105), + 'remise_percent' =>array('type'=>'double', 'label'=>'RelativeDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>110), + 'remise_absolue' =>array('type'=>'double', 'label'=>'CustomerRelativeDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>115), + //'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>120), + 'tva' =>array('type'=>'double(24,8)', 'label'=>'VAT', 'enabled'=>1, 'visible'=>-1, 'position'=>125, 'isameasure'=>1), + 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'LocalTax1', 'enabled'=>1, 'visible'=>-1, 'position'=>130, 'isameasure'=>1), + 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'LocalTax2', 'enabled'=>1, 'visible'=>-1, 'position'=>135, 'isameasure'=>1), + 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>140, 'isameasure'=>1), + 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>145, 'isameasure'=>1), + 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>150), + 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>155), + 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'PDFTemplate', 'enabled'=>1, 'visible'=>0, 'position'=>160), + //'facture' =>array('type'=>'tinyint(4)', 'label'=>'ParentInvoice', 'enabled'=>1, 'visible'=>-1, 'position'=>165), + 'fk_account' =>array('type'=>'integer', 'label'=>'BankAccount', 'enabled'=>1, 'visible'=>-1, 'position'=>170), + 'fk_currency' =>array('type'=>'varchar(3)', 'label'=>'MulticurrencyID', 'enabled'=>1, 'visible'=>-1, 'position'=>175), + 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'position'=>180), + 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>-1, 'position'=>185), + 'date_livraison' =>array('type'=>'date', 'label'=>'DateDeliveryPlanned', 'enabled'=>1, 'visible'=>-1, 'position'=>190), + 'fk_shipping_method' =>array('type'=>'integer', 'label'=>'ShippingMethod', 'enabled'=>1, 'visible'=>-1, 'position'=>195), + 'fk_warehouse' =>array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Fk warehouse', 'enabled'=>1, 'visible'=>-1, 'position'=>200), + 'fk_availability' =>array('type'=>'integer', 'label'=>'Availability', 'enabled'=>1, 'visible'=>-1, 'position'=>205), + 'fk_input_reason' =>array('type'=>'integer', 'label'=>'InputReason', 'enabled'=>1, 'visible'=>-1, 'position'=>210), + //'fk_delivery_address' =>array('type'=>'integer', 'label'=>'DeliveryAddress', 'enabled'=>1, 'visible'=>-1, 'position'=>215), + 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>225), + 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>230), + 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermLabel', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>235), + 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'Fk multicurrency', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>240), + 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCurrency', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>245), + 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>250, 'isameasure'=>1), + 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountHT', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>255, 'isameasure'=>1), + 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountVAT', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>260, 'isameasure'=>1), + 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountTTC', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>265, 'isameasure'=>1), + 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>-1, 'position'=>270), + 'module_source' =>array('type'=>'varchar(32)', 'label'=>'POSModule', 'enabled'=>1, 'visible'=>-1, 'position'=>275), + 'pos_source' =>array('type'=>'varchar(32)', 'label'=>'POSTerminal', 'enabled'=>1, 'visible'=>-1, 'position'=>280), + 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'position'=>500), + 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900), + ); + // END MODULEBUILDER PROPERTIES + /** * ERR Not enough stock */ @@ -384,7 +473,7 @@ class Commande extends CommonOrder { $num = $this->ref; } - $this->newref = $num; + $this->newref = dol_sanitizeFileName($num); // Validate $sql = "UPDATE ".MAIN_DB_PREFIX."commande"; @@ -1680,19 +1769,18 @@ class Commande extends CommonOrder /** - * Get object and lines from database + * Get object from database. Get also lines. * * @param int $id Id of object to load * @param string $ref Ref of object * @param string $ref_ext External reference of object - * @param string $ref_int Internal reference of other object + * @param string $notused Internal reference of other object * @return int >0 if OK, <0 if KO, 0 if not found */ - public function fetch($id, $ref = '', $ref_ext = '', $ref_int = '') + public function fetch($id, $ref = '', $ref_ext = '', $notused = '') { - // Check parameters - if (empty($id) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1; + if (empty($id) && empty($ref) && empty($ref_ext)) return -1; $sql = 'SELECT c.rowid, c.entity, c.date_creation, c.ref, c.fk_soc, c.fk_user_author, c.fk_user_valid, c.fk_statut'; $sql .= ', c.amount_ht, c.total_ht, c.total_ttc, c.tva as total_tva, c.localtax1 as total_localtax1, c.localtax2 as total_localtax2, c.fk_cond_reglement, c.fk_mode_reglement, c.fk_availability, c.fk_input_reason'; @@ -1723,7 +1811,7 @@ class Commande extends CommonOrder if ($ref) $sql .= " AND c.ref='".$this->db->escape($ref)."'"; if ($ref_ext) $sql .= " AND c.ref_ext='".$this->db->escape($ref_ext)."'"; - if ($ref_int) $sql .= " AND c.ref_int='".$this->db->escape($ref_int)."'"; + if ($notused) $sql .= " AND c.ref_int='".$this->db->escape($notused)."'"; dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $result = $this->db->query($sql); @@ -1740,7 +1828,13 @@ class Commande extends CommonOrder $this->ref_customer = $obj->ref_client; $this->ref_ext = $obj->ref_ext; $this->ref_int = $obj->ref_int; + $this->socid = $obj->fk_soc; + $this->thirdparty = null; // Clear if another value was already set by fetch_thirdparty + + $this->fk_project = $obj->fk_project; + $this->project = null; // Clear if another value was already set by fetch_projet + $this->statut = $obj->fk_statut; $this->user_author_id = $obj->fk_user_author; $this->user_valid = $obj->fk_user_valid; @@ -1762,7 +1856,6 @@ class Commande extends CommonOrder $this->note = $obj->note_private; // deprecated $this->note_private = $obj->note_private; $this->note_public = $obj->note_public; - $this->fk_project = $obj->fk_project; $this->modelpdf = $obj->model_pdf; $this->last_main_doc = $obj->last_main_doc; $this->mode_reglement_id = $obj->fk_mode_reglement; @@ -1810,9 +1903,7 @@ class Commande extends CommonOrder $this->db->free($result); - /* - * Lines - */ + // Lines $result = $this->fetch_lines(); if ($result < 0) { @@ -3566,7 +3657,7 @@ class Commande extends CommonOrder * @param int $short ??? * @param int $notooltip 1=Disable tooltip * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking - * @param int $addlinktonotes Add linkt to notes + * @param int $addlinktonotes Add link to notes * @return string String with URL */ public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0) diff --git a/htdocs/commande/class/commandestats.class.php b/htdocs/commande/class/commandestats.class.php index 0311f4c49ed..522bd7b2e31 100644 --- a/htdocs/commande/class/commandestats.class.php +++ b/htdocs/commande/class/commandestats.class.php @@ -203,10 +203,11 @@ class CommandeStats extends Stats /** * Return nb, amount of predefined product for year * - * @param int $year Year to scan - * @return array Array of values + * @param int $year Year to scan + * @param int $limit Limit + * @return array Array of values */ - public function getAllByProduct($year) + public function getAllByProduct($year, $limit = 10) { global $user; @@ -220,6 +221,6 @@ class CommandeStats extends Stats $sql.= $this->db->order('nb', 'DESC'); //$sql.= $this->db->plimit(20); - return $this->_getAllByProduct($sql); + return $this->_getAllByProduct($sql, $limit); } } diff --git a/htdocs/commande/index.php b/htdocs/commande/index.php index b8866a7c487..072abe9625b 100644 --- a/htdocs/commande/index.php +++ b/htdocs/commande/index.php @@ -140,10 +140,10 @@ if ($resql) include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; $dolgraph = new DolGraph(); $dolgraph->SetData($dataseries); - $dolgraph->setShowLegend(1); + $dolgraph->setShowLegend(2); $dolgraph->setShowPercent(1); $dolgraph->SetType(array('pie')); - $dolgraph->setWidth('100%'); + $dolgraph->setHeight('200'); $dolgraph->draw('idgraphstatus'); print $dolgraph->show($total ? 0 : 1); diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 0fa53f6c314..5e2353110e7 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -74,7 +74,13 @@ $socid = GETPOST('socid', 'int'); $search_user = GETPOST('search_user', 'int'); $search_sale = GETPOST('search_sale', 'int'); $search_total_ht = GETPOST('search_total_ht', 'alpha'); +$search_total_vat = GETPOST('search_total_vat', 'alpha'); $search_total_ttc = GETPOST('search_total_ttc', 'alpha'); +$search_multicurrency_code = GETPOST('search_multicurrency_code', 'alpha'); +$search_multicurrency_tx = GETPOST('search_multicurrency_tx', 'alpha'); +$search_multicurrency_montant_ht = GETPOST('search_multicurrency_montant_ht', 'alpha'); +$search_multicurrency_montant_vat = GETPOST('search_multicurrency_montant_vat', 'alpha'); +$search_multicurrency_montant_ttc = GETPOST('search_multicurrency_montant_ttc', 'alpha'); $search_login = GETPOST('search_login', 'alpha'); $search_categ_cus = trim(GETPOST("search_categ_cus", 'int')); $optioncss = GETPOST('optioncss', 'alpha'); @@ -141,6 +147,11 @@ $arrayfields = array( 'c.total_ht'=>array('label'=>"AmountHT", 'checked'=>1), 'c.total_vat'=>array('label'=>"AmountVAT", 'checked'=>0), 'c.total_ttc'=>array('label'=>"AmountTTC", 'checked'=>0), + 'c.multicurrency_code'=>array('label'=>'Currency', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'c.multicurrency_tx'=>array('label'=>'CurrencyRate', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'c.multicurrency_total_ht'=>array('label'=>'MulticurrencyAmountHT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'c.multicurrency_total_vat'=>array('label'=>'MulticurrencyAmountVAT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'c.multicurrency_total_ttc'=>array('label'=>'MulticurrencyAmountTTC', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), 'u.login'=>array('label'=>"Author", 'checked'=>1, 'position'=>10), 'c.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500), 'c.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500), @@ -197,6 +208,11 @@ if (empty($reshook)) $search_total_ht = ''; $search_total_vat = ''; $search_total_ttc = ''; + $search_multicurrency_code = ''; + $search_multicurrency_tx = ''; + $search_multicurrency_montant_ht = ''; + $search_multicurrency_montant_vat = ''; + $search_multicurrency_montant_ttc = ''; $search_login = ''; $search_dateorder_start = ''; $search_dateorder_end = ''; @@ -250,6 +266,7 @@ $sql .= ' s.rowid as socid, s.nom as name, s.email, s.town, s.zip, s.fk_pays, s. $sql .= " typent.code as typent_code,"; $sql .= " state.code_departement as state_code, state.nom as state_name,"; $sql .= ' c.rowid, c.ref, c.total_ht, c.tva as total_tva, c.total_ttc, c.ref_client, c.fk_user_author,'; +$sql .= ' c.fk_multicurrency, c.multicurrency_code, c.multicurrency_tx, c.multicurrency_total_ht, c.multicurrency_total_tva as multicurrency_total_vat, c.multicurrency_total_ttc,'; $sql .= ' c.date_valid, c.date_commande, c.note_private, c.date_livraison as date_delivery, c.fk_statut, c.facture as billed,'; $sql .= ' c.date_creation as date_creation, c.tms as date_update, c.date_cloture as date_cloture,'; $sql .= " p.rowid as project_id, p.ref as project_ref, p.title as project_label,"; @@ -314,25 +331,31 @@ if ($viewstatut <> '') } } -if ($search_dateorder_start) $sql .= " AND c.date_commande >= '".$db->idate($search_dateorder_start)."'"; -if ($search_dateorder_end) $sql .= " AND c.date_commande <= '".$db->idate($search_dateorder_end)."'"; -if ($search_datedelivery_start) $sql .= " AND c.date_livraison >= '".$db->idate($search_datedelivery_start)."'"; -if ($search_datedelivery_end) $sql .= " AND c.date_livraison <= '".$db->idate($search_datedelivery_end)."'"; -if ($search_town) $sql .= natural_search('s.town', $search_town); -if ($search_zip) $sql .= natural_search("s.zip", $search_zip); -if ($search_state) $sql .= natural_search("state.nom", $search_state); -if ($search_country) $sql .= " AND s.fk_pays IN (".$search_country.')'; -if ($search_type_thirdparty) $sql .= " AND s.fk_typent IN (".$search_type_thirdparty.')'; -if ($search_company) $sql .= natural_search('s.nom', $search_company); -if ($search_sale > 0) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$search_sale; -if ($search_user > 0) $sql .= " AND ec.fk_c_type_contact = tc.rowid AND tc.element='commande' AND tc.source='internal' AND ec.element_id = c.rowid AND ec.fk_socpeople = ".$search_user; -if ($search_total_ht != '') $sql .= natural_search('c.total_ht', $search_total_ht, 1); -if ($search_total_ttc != '') $sql .= natural_search('c.total_ttc', $search_total_ttc, 1); -if ($search_login) $sql .= natural_search("u.login", $search_login); -if ($search_project_ref != '') $sql .= natural_search("p.ref", $search_project_ref); -if ($search_project != '') $sql .= natural_search("p.title", $search_project); -if ($search_categ_cus > 0) $sql .= " AND cc.fk_categorie = ".$db->escape($search_categ_cus); -if ($search_categ_cus == -2) $sql .= " AND cc.fk_categorie IS NULL"; +if ($search_dateorder_start) $sql .= " AND c.date_commande >= '".$db->idate($search_dateorder_start)."'"; +if ($search_dateorder_end) $sql .= " AND c.date_commande <= '".$db->idate($search_dateorder_end)."'"; +if ($search_datedelivery_start) $sql .= " AND c.date_livraison >= '".$db->idate($search_datedelivery_start)."'"; +if ($search_datedelivery_end) $sql .= " AND c.date_livraison <= '".$db->idate($search_datedelivery_end)."'"; +if ($search_town) $sql .= natural_search('s.town', $search_town); +if ($search_zip) $sql .= natural_search("s.zip", $search_zip); +if ($search_state) $sql .= natural_search("state.nom", $search_state); +if ($search_country) $sql .= " AND s.fk_pays IN (".$search_country.')'; +if ($search_type_thirdparty) $sql .= " AND s.fk_typent IN (".$search_type_thirdparty.')'; +if ($search_company) $sql .= natural_search('s.nom', $search_company); +if ($search_sale > 0) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$search_sale; +if ($search_user > 0) $sql .= " AND ec.fk_c_type_contact = tc.rowid AND tc.element='commande' AND tc.source='internal' AND ec.element_id = c.rowid AND ec.fk_socpeople = ".$search_user; +if ($search_total_ht != '') $sql .= natural_search('c.total_ht', $search_total_ht, 1); +if ($search_total_vat != '') $sql .= natural_search('c.tva', $search_total_vat, 1); +if ($search_total_ttc != '') $sql .= natural_search('c.total_ttc', $search_total_ttc, 1); +if ($search_multicurrency_code != '') $sql .= ' AND c.multicurrency_code = "' . $db->escape($search_multicurrency_code) . '"'; +if ($search_multicurrency_tx != '') $sql .= natural_search('c.multicurrency_tx', $search_multicurrency_tx, 1); +if ($search_multicurrency_montant_ht != '') $sql .= natural_search('c.multicurrency_total_ht', $search_multicurrency_montant_ht, 1); +if ($search_multicurrency_montant_vat != '') $sql .= natural_search('c.multicurrency_total_tva', $search_multicurrency_montant_vat, 1); +if ($search_multicurrency_montant_ttc != '') $sql .= natural_search('c.multicurrency_total_ttc', $search_multicurrency_montant_ttc, 1); +if ($search_login) $sql .= natural_search("u.login", $search_login); +if ($search_project_ref != '') $sql .= natural_search("p.ref", $search_project_ref); +if ($search_project != '') $sql .= natural_search("p.title", $search_project); +if ($search_categ_cus > 0) $sql .= " AND cc.fk_categorie = ".$db->escape($search_categ_cus); +if ($search_categ_cus == -2) $sql .= " AND cc.fk_categorie IS NULL"; // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; @@ -424,6 +447,11 @@ if ($resql) if ($search_total_ht != '') $param .= '&search_total_ht='.urlencode($search_total_ht); if ($search_total_vat != '') $param .= '&search_total_vat='.urlencode($search_total_vat); if ($search_total_ttc != '') $param .= '&search_total_ttc='.urlencode($search_total_ttc); + if ($search_multicurrency_code != '') $param .= '&search_multicurrency_code='.urlencode($search_multicurrency_code); + if ($search_multicurrency_tx != '') $param .= '&search_multicurrency_tx='.urlencode($search_multicurrency_tx); + if ($search_multicurrency_montant_ht != '') $param .= '&search_multicurrency_montant_ht='.urlencode($search_multicurrency_montant_ht); + if ($search_multicurrency_montant_vat != '') $param .= '&search_multicurrency_montant_vat='.urlencode($search_multicurrency_montant_vat); + if ($search_multicurrency_montant_ttc != '') $param .= '&search_multicurrency_montant_ttc='.urlencode($search_multicurrency_montant_ttc); if ($search_login) $param .= '&search_login='.urlencode($search_login); if ($search_project_ref >= 0) $param .= "&search_project_ref=".urlencode($search_project_ref); if ($search_town != '') $param .= '&search_town='.urlencode($search_town); @@ -697,6 +725,41 @@ if ($resql) print ''; print ''; } + if (!empty($arrayfields['c.multicurrency_code']['checked'])) + { + // Currency + print ''; + } + if (!empty($arrayfields['c.multicurrency_tx']['checked'])) + { + // Currency rate + print ''; + } + if (!empty($arrayfields['c.multicurrency_total_ht']['checked'])) + { + // Amount + print ''; + } + if (!empty($arrayfields['c.multicurrency_total_vat']['checked'])) + { + // Amount + print ''; + } + if (!empty($arrayfields['c.multicurrency_total_ttc']['checked'])) + { + // Amount + print ''; + } if (!empty($arrayfields['u.login']['checked'])) { // Author @@ -775,6 +838,11 @@ if ($resql) if (!empty($arrayfields['c.total_ht']['checked'])) print_liste_field_titre($arrayfields['c.total_ht']['label'], $_SERVER["PHP_SELF"], 'c.total_ht', '', $param, '', $sortfield, $sortorder, 'right '); if (!empty($arrayfields['c.total_vat']['checked'])) print_liste_field_titre($arrayfields['c.total_vat']['label'], $_SERVER["PHP_SELF"], 'c.tva', '', $param, '', $sortfield, $sortorder, 'right '); if (!empty($arrayfields['c.total_ttc']['checked'])) print_liste_field_titre($arrayfields['c.total_ttc']['label'], $_SERVER["PHP_SELF"], 'c.total_ttc', '', $param, '', $sortfield, $sortorder, 'right '); + if (!empty($arrayfields['c.multicurrency_code']['checked'])) print_liste_field_titre($arrayfields['c.multicurrency_code']['label'], $_SERVER['PHP_SELF'], 'c.multicurrency_code', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['c.multicurrency_tx']['checked'])) print_liste_field_titre($arrayfields['c.multicurrency_tx']['label'], $_SERVER['PHP_SELF'], 'c.multicurrency_tx', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['c.multicurrency_total_ht']['checked'])) print_liste_field_titre($arrayfields['c.multicurrency_total_ht']['label'], $_SERVER['PHP_SELF'], 'c.multicurrency_total_ht', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['c.multicurrency_total_vat']['checked'])) print_liste_field_titre($arrayfields['c.multicurrency_total_vat']['label'], $_SERVER['PHP_SELF'], 'c.multicurrency_total_tva', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['c.multicurrency_total_ttc']['checked'])) print_liste_field_titre($arrayfields['c.multicurrency_total_ttc']['label'], $_SERVER['PHP_SELF'], 'c.multicurrency_total_ttc', '', $param, 'class="right"', $sortfield, $sortorder); if (!empty($arrayfields['u.login']['checked'])) print_liste_field_titre($arrayfields['u.login']['label'], $_SERVER["PHP_SELF"], 'u.login', '', $param, 'align="center"', $sortfield, $sortorder); // Extra fields @@ -966,7 +1034,7 @@ if ($resql) // Ref customer if (!empty($arrayfields['c.ref_client']['checked'])) { - print ''; + print ''; if (!$i) $totalarray['nbfield']++; } @@ -1097,6 +1165,40 @@ if ($resql) $totalarray['val']['c.total_ttc'] += $obj->total_ttc; } + // Currency + if (!empty($arrayfields['c.multicurrency_code']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + + // Currency rate + if (!empty($arrayfields['c.multicurrency_tx']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount HT + if (!empty($arrayfields['c.multicurrency_total_ht']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount VAT + if (!empty($arrayfields['c.multicurrency_total_vat']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount TTC + if (!empty($arrayfields['c.multicurrency_total_ttc']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + $userstatic->id = $obj->fk_user_author; $userstatic->login = $obj->login; diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index ac019de8088..7a8832be2b5 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -32,7 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php'; require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; -$langs->loadLangs(array("accountancy", "bills", "companies", "salaries", "compta")); +$langs->loadLangs(array("accountancy", "bills", "companies", "salaries", "compta", "trips")); $date_start = GETPOST('date_start', 'alpha'); $date_startDay = GETPOST('date_startday', 'int'); @@ -66,7 +66,14 @@ if (!$sortorder) $sortorder = "DESC"; $arrayfields = array( 'type'=>array('label'=>"Type", 'checked'=>1), 'date'=>array('label'=>"Date", 'checked'=>1), - //... + 'date_due'=>array('label'=>"DateDue", 'checked'=>1), + 'ref'=>array('label'=>"Ref", 'checked'=>1), + 'documents'=>array('label'=>"Documents", 'checked'=>1), + 'paid'=>array('label'=>"Paid", 'checked'=>1), + 'total_ht'=>array('label'=>"TotalHT", 'checked'=>1), + 'total_ttc'=>array('label'=>"TotalTTC", 'checked'=>1), + 'total_vat'=>array('label'=>"TotalVAT", 'checked'=>1), + //... ); // Security check @@ -77,7 +84,22 @@ if ($user->socid > 0) { accessforbidden(); } -$entity = GETPOST('entity', 'int') ?GETPOST('entity', 'int') : $conf->entity; +// Define $arrayofentities if multientity is set. +$arrayofentities = array(); +if (!empty($conf->multicompany->enabled) && is_object($mc)) { + $arrayofentities = $mc->getEntitiesList(); +} + +$entity = (GETPOSTISSET('entity') ? GETPOST('entity', 'int') : (GETPOSTISSET('search_entity') ? GETPOST('search_entity', 'int') : $conf->entity)); +if (!empty($conf->multicompany->enabled) && is_object($mc)) { + if (empty($entity) && !empty($conf->global->MULTICOMPANY_ALLOW_EXPORT_ACCOUNTING_DOC_FOR_ALL_ENTITIES)) { + $entity = '0,'.join(',', array_keys($arrayofentities)); + } +} +if (empty($entity)) $entity = $conf->entity; + +$error = 0; + /* @@ -105,188 +127,213 @@ if (($action == "searchfiles" || $action == "dl")) { if (!$error) { + $sql = ''; + $wheretail = " '".$db->idate($date_start)."' AND '".$db->idate($date_stop)."'"; // Customer invoices - $sql = "SELECT t.rowid as id, t.ref, t.paye as paid, total as total_ht, total_ttc, tva as total_vat, fk_soc, t.datef as date, 'Invoice' as item, s.nom as thirdparty_name, s.code_client as thirdparty_code, c.code as country_code, s.tva_intra as vatnum"; - $sql .= " FROM ".MAIN_DB_PREFIX."facture as t LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = t.fk_soc LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = s.fk_pays"; - $sql .= " WHERE datef between ".$wheretail; - $sql .= " AND t.entity IN (".($entity == 1 ? '0,1' : $entity).')'; - $sql .= " AND t.fk_statut <> ".Facture::STATUS_DRAFT; - $sql .= " UNION ALL"; + if (GETPOST('selectinvoices')) { + if (! empty($sql)) $sql .= " UNION ALL"; + $sql .= "SELECT t.rowid as id, t.entity, t.ref, t.paye as paid, t.total as total_ht, t.total_ttc, t.tva as total_vat, t.fk_soc, t.datef as date, t.date_lim_reglement as date_due, 'Invoice' as item, s.nom as thirdparty_name, s.code_client as thirdparty_code, c.code as country_code, s.tva_intra as vatnum"; + $sql .= " FROM ".MAIN_DB_PREFIX."facture as t LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = t.fk_soc LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = s.fk_pays"; + $sql .= " WHERE datef between ".$wheretail; + $sql .= " AND t.entity IN (".($entity == 1 ? '0,1' : $entity).')'; + $sql .= " AND t.fk_statut <> ".Facture::STATUS_DRAFT; + } // Vendor invoices - $sql .= " SELECT t.rowid as id, t.ref, paye as paid, total_ht, total_ttc, total_tva as total_vat, fk_soc, datef as date, 'SupplierInvoice' as item, s.nom as thirdparty_name, s.code_fournisseur as thirdparty_code, c.code as country_code, s.tva_intra as vatnum"; - $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as t LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = t.fk_soc LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = s.fk_pays"; - $sql .= " WHERE datef between ".$wheretail; - $sql .= " AND t.entity IN (".($entity == 1 ? '0,1' : $entity).')'; - $sql .= " AND t.fk_statut <> ".FactureFournisseur::STATUS_DRAFT; - $sql .= " UNION ALL"; + if (GETPOST('selectsupplierinvoices')) { + if (! empty($sql)) $sql .= " UNION ALL"; + $sql .= " SELECT t.rowid as id, t.entity, t.ref, t.paye as paid, t.total_ht, t.total_ttc, t.total_tva as total_vat, t.fk_soc, t.datef as date, t.date_lim_reglement as date_due, 'SupplierInvoice' as item, s.nom as thirdparty_name, s.code_fournisseur as thirdparty_code, c.code as country_code, s.tva_intra as vatnum"; + $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as t LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = t.fk_soc LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = s.fk_pays"; + $sql .= " WHERE datef between ".$wheretail; + $sql .= " AND t.entity IN (".($entity == 1 ? '0,1' : $entity).')'; + $sql .= " AND t.fk_statut <> ".FactureFournisseur::STATUS_DRAFT; + } // Expense reports - $sql .= " SELECT t.rowid as id, t.ref, paid, total_ht, total_ttc, total_tva as total_vat, fk_user_author as fk_soc, date_fin as date, 'ExpenseReport' as item, CONCAT(CONCAT(u.lastname, ' '), u.firstname) as thirdparty_name, '' as thirdparty_code, c.code as country_code, '' as vatnum"; - $sql .= " FROM ".MAIN_DB_PREFIX."expensereport as t LEFT JOIN ".MAIN_DB_PREFIX."user as u ON u.rowid = t.fk_user_author LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = u.fk_country"; - $sql .= " WHERE date_fin between ".$wheretail; - $sql .= " AND t.entity IN (".($entity == 1 ? '0,1' : $entity).')'; - $sql .= " AND t.fk_statut <> ".ExpenseReport::STATUS_DRAFT; - $sql .= " UNION ALL"; + if (GETPOST('selectexpensereports')) { + if (! empty($sql)) $sql .= " UNION ALL"; + $sql .= " SELECT t.rowid as id, t.entity, t.ref, t.paid, t.total_ht, t.total_ttc, t.total_tva as total_vat, t.fk_user_author as fk_soc, t.date_fin as date, t.date_fin as date_due, 'ExpenseReport' as item, CONCAT(CONCAT(u.lastname, ' '), u.firstname) as thirdparty_name, '' as thirdparty_code, c.code as country_code, '' as vatnum"; + $sql .= " FROM ".MAIN_DB_PREFIX."expensereport as t LEFT JOIN ".MAIN_DB_PREFIX."user as u ON u.rowid = t.fk_user_author LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = u.fk_country"; + $sql .= " WHERE date_fin between ".$wheretail; + $sql .= " AND t.entity IN (".($entity == 1 ? '0,1' : $entity).')'; + $sql .= " AND t.fk_statut <> ".ExpenseReport::STATUS_DRAFT; + } // Donations - $sql .= " SELECT t.rowid as id, t.ref, paid, amount as total_ht, amount as total_ttc, 0 as total_vat, 0 as fk_soc, datedon as date, 'Donation' as item, t.societe as thirdparty_name, '' as thirdparty_code, c.code as country_code, '' as vatnum"; - $sql .= " FROM ".MAIN_DB_PREFIX."don as t LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = t.fk_country"; - $sql .= " WHERE datedon between ".$wheretail; - $sql .= " AND t.entity IN (".($entity == 1 ? '0,1' : $entity).')'; - $sql .= " AND t.fk_statut <> ".Don::STATUS_DRAFT; - $sql .= " UNION ALL"; + if (GETPOST('selectdonations')) { + if (! empty($sql)) $sql .= " UNION ALL"; + $sql .= " SELECT t.rowid as id, t.entity, t.ref, paid, amount as total_ht, amount as total_ttc, 0 as total_vat, 0 as fk_soc, t.datedon as date, t.datedon as date_due, 'Donation' as item, t.societe as thirdparty_name, '' as thirdparty_code, c.code as country_code, '' as vatnum"; + $sql .= " FROM ".MAIN_DB_PREFIX."don as t LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = t.fk_country"; + $sql .= " WHERE datedon between ".$wheretail; + $sql .= " AND t.entity IN (".($entity == 1 ? '0,1' : $entity).')'; + $sql .= " AND t.fk_statut <> ".Don::STATUS_DRAFT; + } // Paiements of salaries - $sql .= " SELECT t.rowid as id, t.ref as ref, 1 as paid, amount as total_ht, amount as total_ttc, 0 as total_vat, t.fk_user as fk_soc, datep as date, 'SalaryPayment' as item, CONCAT(CONCAT(u.lastname, ' '), u.firstname) as thirdparty_name, '' as thirdparty_code, c.code as country_code, '' as vatnum"; - $sql .= " FROM ".MAIN_DB_PREFIX."payment_salary as t LEFT JOIN ".MAIN_DB_PREFIX."user as u ON u.rowid = t.fk_user LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = u.fk_country"; - $sql .= " WHERE datep between ".$wheretail; - $sql .= " AND t.entity IN (".($entity == 1 ? '0,1' : $entity).')'; - //$sql.=" AND fk_statut <> ".PaymentSalary::STATUS_DRAFT; - $sql .= " UNION ALL"; + if (GETPOST('selectpaymentsofsalaries')) { + if (! empty($sql)) $sql .= " UNION ALL"; + $sql .= " SELECT t.rowid as id, t.entity, t.ref as ref, 1 as paid, amount as total_ht, amount as total_ttc, 0 as total_vat, t.fk_user as fk_soc, t.datep as date, t.dateep as date_due, 'SalaryPayment' as item, CONCAT(CONCAT(u.lastname, ' '), u.firstname) as thirdparty_name, '' as thirdparty_code, c.code as country_code, '' as vatnum"; + $sql .= " FROM ".MAIN_DB_PREFIX."payment_salary as t LEFT JOIN ".MAIN_DB_PREFIX."user as u ON u.rowid = t.fk_user LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = u.fk_country"; + $sql .= " WHERE datep between ".$wheretail; + $sql .= " AND t.entity IN (".($entity == 1 ? '0,1' : $entity).')'; + //$sql.=" AND fk_statut <> ".PaymentSalary::STATUS_DRAFT; + } // Social contributions - $sql .= " SELECT t.rowid as id, t.libelle as ref, paye as paid, amount as total_ht, amount as total_ttc, 0 as total_tva, 0 as fk_soc, date_creation as date, 'SocialContributions' as item, '' as thirdparty_name, '' as thirdparty_code, '' as country_code, '' as vatnum"; - $sql .= " FROM ".MAIN_DB_PREFIX."chargesociales as t"; - $sql .= " WHERE date_creation between ".$wheretail; - $sql .= " AND t.entity IN (".($entity == 1 ? '0,1' : $entity).')'; - //$sql.=" AND fk_statut <> ".ChargeSociales::STATUS_DRAFT; - $sql .= $db->order($sortfield, $sortorder); - //print $sql; + if (GETPOST('selectsocialcontributions')) { + if (! empty($sql)) $sql .= " UNION ALL"; + $sql .= " SELECT t.rowid as id, t.entity, t.libelle as ref, t.paye as paid, t.amount as total_ht, t.amount as total_ttc, 0 as total_tva, 0 as fk_soc, t.date_creation as date, t.date_ech as date_due, 'SocialContributions' as item, '' as thirdparty_name, '' as thirdparty_code, '' as country_code, '' as vatnum"; + $sql .= " FROM ".MAIN_DB_PREFIX."chargesociales as t"; + $sql .= " WHERE date_creation between ".$wheretail; + $sql .= " AND t.entity IN (".($entity == 1 ? '0,1' : $entity).')'; + //$sql.=" AND fk_statut <> ".ChargeSociales::STATUS_DRAFT; + } - $resd = $db->query($sql); - $files = array(); - $link = ''; + if ($sql) { + $sql .= $db->order($sortfield, $sortorder); + //print $sql; - if ($resd) - { - $numd = $db->num_rows($resd); + $resd = $db->query($sql); + $files = array(); + $link = ''; - $tmpinvoice = new Facture($db); - $tmpinvoicesupplier = new FactureFournisseur($db); - $tmpdonation = new Don($db); + if ($resd) + { + $numd = $db->num_rows($resd); - $upload_dir = ''; - $i = 0; - while ($i < $numd) - { - $objd = $db->fetch_object($resd); + $tmpinvoice = new Facture($db); + $tmpinvoicesupplier = new FactureFournisseur($db); + $tmpdonation = new Don($db); - switch ($objd->item) - { - case "Invoice": - $subdir = ''; - $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->ref); - $upload_dir = $conf->facture->dir_output.'/'.$subdir; - $link = "document.php?modulepart=facture&file=".str_replace('/', '%2F', $subdir).'%2F'; - break; - case "SupplierInvoice": - $tmpinvoicesupplier->fetch($objd->id); - $subdir = get_exdir($tmpinvoicesupplier->id, 2, 0, 1, $tmpinvoicesupplier, 'invoice_supplier'); // TODO Use first file - $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->ref); - $upload_dir = $conf->fournisseur->facture->dir_output.'/'.$subdir; - $link = "document.php?modulepart=facture_fournisseur&file=".str_replace('/', '%2F', $subdir).'%2F'; - break; - case "ExpenseReport": - $subdir = ''; - $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->ref); - $upload_dir = $conf->expensereport->dir_output.'/'.$subdir; - $link = "document.php?modulepart=expensereport&file=".str_replace('/', '%2F', $subdir).'%2F'; - break; - case "SalaryPayment": - $subdir = ''; - $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->id); - $upload_dir = $conf->salaries->dir_output.'/'.$subdir; - $link = "document.php?modulepart=salaries&file=".str_replace('/', '%2F', $subdir).'%2F'; - break; - case "Donation": - $tmpdonation->fetch($objp->id); - $subdir = get_exdir(0, 0, 0, 0, $tmpdonation, 'donation'); - $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->id); - $upload_dir = $conf->don->dir_output.'/'.$subdir; - $link = "document.php?modulepart=don&file=".str_replace('/', '%2F', $subdir).'%2F'; - break; - case "SocialContributions": - $subdir = ''; - $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->id); - $upload_dir = $conf->tax->dir_output.'/'.$subdir; - $link = "document.php?modulepart=tax&file=".str_replace('/', '%2F', $subdir).'%2F'; - break; - default: - $subdir = ''; - $upload_dir = ''; - $link = ''; - break; - } + $upload_dir = ''; + $i = 0; + while ($i < $numd) + { + $objd = $db->fetch_object($resd); - if (!empty($upload_dir)) - { - $result = true; + switch ($objd->item) + { + case "Invoice": + $subdir = ''; + $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->ref); + $upload_dir = $conf->facture->dir_output.'/'.$subdir; + $link = "document.php?modulepart=facture&file=".str_replace('/', '%2F', $subdir).'%2F'; + break; + case "SupplierInvoice": + $tmpinvoicesupplier->fetch($objd->id); + $subdir = get_exdir($tmpinvoicesupplier->id, 2, 0, 1, $tmpinvoicesupplier, 'invoice_supplier'); // TODO Use first file + $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->ref); + $upload_dir = $conf->fournisseur->facture->dir_output.'/'.$subdir; + $link = "document.php?modulepart=facture_fournisseur&file=".str_replace('/', '%2F', $subdir).'%2F'; + break; + case "ExpenseReport": + $subdir = ''; + $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->ref); + $upload_dir = $conf->expensereport->dir_output.'/'.$subdir; + $link = "document.php?modulepart=expensereport&file=".str_replace('/', '%2F', $subdir).'%2F'; + break; + case "SalaryPayment": + $subdir = ''; + $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->id); + $upload_dir = $conf->salaries->dir_output.'/'.$subdir; + $link = "document.php?modulepart=salaries&file=".str_replace('/', '%2F', $subdir).'%2F'; + break; + case "Donation": + $tmpdonation->fetch($objp->id); + $subdir = get_exdir(0, 0, 0, 0, $tmpdonation, 'donation'); + $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->id); + $upload_dir = $conf->don->dir_output.'/'.$subdir; + $link = "document.php?modulepart=don&file=".str_replace('/', '%2F', $subdir).'%2F'; + break; + case "SocialContributions": + $subdir = ''; + $subdir .= ($subdir ? '/' : '').dol_sanitizeFileName($objd->id); + $upload_dir = $conf->tax->dir_output.'/'.$subdir; + $link = "document.php?modulepart=tax&file=".str_replace('/', '%2F', $subdir).'%2F'; + break; + default: + $subdir = ''; + $upload_dir = ''; + $link = ''; + break; + } - $files = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview\.png)$', '', SORT_ASC, 1); - //var_dump($upload_dir); - //var_dump($files); + if (!empty($upload_dir)) + { + $result = true; - if (count($files) < 1) - { - $nofile = array(); - $nofile['id'] = $objd->id; - $nofile['date'] = $db->idate($objd->date); - $nofile['paid'] = $objd->paid; - $nofile['amount_ht'] = $objd->total_ht; - $nofile['amount_ttc'] = $objd->total_ttc; - $nofile['amount_vat'] = $objd->total_vat; - $nofile['ref'] = ($objd->ref ? $objd->ref : $objd->id); - $nofile['fk'] = $objd->fk_soc; - $nofile['item'] = $objd->item; - $nofile['thirdparty_name'] = $objd->thirdparty_name; - $nofile['thirdparty_code'] = $objd->thirdparty_code; - $nofile['country_code'] = $objd->country_code; - $nofile['vatnum'] = $objd->vatnum; + $files = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview\.png)$', '', SORT_ASC, 1); + //var_dump($upload_dir); + //var_dump($files); + if (count($files) < 1) + { + $nofile = array(); + $nofile['id'] = $objd->id; + $nofile['entity'] = $objd->entity; + $nofile['date'] = $db->idate($objd->date); + $nofile['date_due'] = $db->idate($objd->date_due); + $nofile['paid'] = $objd->paid; + $nofile['amount_ht'] = $objd->total_ht; + $nofile['amount_ttc'] = $objd->total_ttc; + $nofile['amount_vat'] = $objd->total_vat; + $nofile['ref'] = ($objd->ref ? $objd->ref : $objd->id); + $nofile['fk'] = $objd->fk_soc; + $nofile['item'] = $objd->item; + $nofile['thirdparty_name'] = $objd->thirdparty_name; + $nofile['thirdparty_code'] = $objd->thirdparty_code; + $nofile['country_code'] = $objd->country_code; + $nofile['vatnum'] = $objd->vatnum; - $filesarray[$nofile['item'].'_'.$nofile['id']] = $nofile; - } - else - { - foreach ($files as $key => $file) - { - $file['id'] = $objd->id; - $file['date'] = $db->idate($objd->date); - $file['paid'] = $objd->paid; - $file['amount_ht'] = $objd->total_ht; - $file['amount_ttc'] = $objd->total_ttc; - $file['amount_vat'] = $objd->total_vat; - $file['ref'] = ($objd->ref ? $objd->ref : $objd->id); - $file['fk'] = $objd->fk_soc; - $file['item'] = $objd->item; + $filesarray[$nofile['item'].'_'.$nofile['id']] = $nofile; + } + else + { + foreach ($files as $key => $file) + { + $file['id'] = $objd->id; + $file['entity'] = $objd->entity; + $file['date'] = $db->idate($objd->date); + $file['date_due'] = $db->idate($objd->date_due); + $file['paid'] = $objd->paid; + $file['amount_ht'] = $objd->total_ht; + $file['amount_ttc'] = $objd->total_ttc; + $file['amount_vat'] = $objd->total_vat; + $file['ref'] = ($objd->ref ? $objd->ref : $objd->id); + $file['fk'] = $objd->fk_soc; + $file['item'] = $objd->item; - $file['thirdparty_name'] = $objd->thirdparty_name; - $file['thirdparty_code'] = $objd->thirdparty_code; - $file['country_code'] = $objd->country_code; - $file['vatnum'] = $objd->vatnum; + $file['thirdparty_name'] = $objd->thirdparty_name; + $file['thirdparty_code'] = $objd->thirdparty_code; + $file['country_code'] = $objd->country_code; + $file['vatnum'] = $objd->vatnum; - // Save record into array (only the first time it is found) - if (empty($filesarray[$file['item'].'_'.$file['id']])) { - $filesarray[$file['item'].'_'.$file['id']] = $file; - } + // Save record into array (only the first time it is found) + if (empty($filesarray[$file['item'].'_'.$file['id']])) { + $filesarray[$file['item'].'_'.$file['id']] = $file; + } - // Add or concat file - if (empty($filesarray[$file['item'].'_'.$file['id']]['files'])) { - $filesarray[$file['item'].'_'.$file['id']]['files'] = array(); - } - $filesarray[$file['item'].'_'.$file['id']]['files'][] = array('link' => $link.$file['name'], 'name'=>$file['name'], 'ref'=>$file['ref'], 'fullname' => $file['fullname'], 'relpathnamelang' => $langs->trans($file['item']).'/'.$file['name']); - //var_dump($file['item'].'_'.$file['id']); - //var_dump($filesarray[$file['item'].'_'.$file['id']]['files']); - } - } - } + // Add or concat file + if (empty($filesarray[$file['item'].'_'.$file['id']]['files'])) { + $filesarray[$file['item'].'_'.$file['id']]['files'] = array(); + } + $filesarray[$file['item'].'_'.$file['id']]['files'][] = array('link' => $link.$file['name'], 'name'=>$file['name'], 'ref'=>$file['ref'], 'fullname' => $file['fullname'], 'relpathnamelang' => $langs->trans($file['item']).'/'.$file['name']); + //var_dump($file['item'].'_'.$file['id']); + //var_dump($filesarray[$file['item'].'_'.$file['id']]['files']); + } + } + } - $i++; - } - } - else - { - dol_print_error($db); - } + $i++; + } + } + else + { + dol_print_error($db); + } - $db->free($resd); + $db->free($resd); + } + else { + setEventMessages($langs->trans("ErrorSelectAtLeastOne"), null, 'errors'); + $error++; + } } } @@ -314,13 +361,19 @@ if ($result && $action == "dl" && !$error) dol_mkdir($dirfortmpfile); $log = $langs->transnoentitiesnoconv("Type"); + if (!empty($conf->multicompany->enabled) && is_object($mc)) + { + $log .= ','.$langs->transnoentitiesnoconv("Entity"); + } $log .= ','.$langs->transnoentitiesnoconv("Date"); + $log .= ','.$langs->transnoentitiesnoconv("DateDue"); $log .= ','.$langs->transnoentitiesnoconv("Ref"); $log .= ','.$langs->transnoentitiesnoconv("TotalHT"); $log .= ','.$langs->transnoentitiesnoconv("TotalTTC"); $log .= ','.$langs->transnoentitiesnoconv("TotalVAT"); $log .= ','.$langs->transnoentitiesnoconv("Paid"); - $log .= ',filename,item_id'; + $log .= ','.$langs->transnoentitiesnoconv("Document"); + $log .= ','.$langs->transnoentitiesnoconv("ItemID"); $log .= ','.$langs->transnoentitiesnoconv("ThirdParty"); $log .= ','.$langs->transnoentitiesnoconv("Code"); $log .= ','.$langs->transnoentitiesnoconv("Country"); @@ -335,25 +388,31 @@ if ($result && $action == "dl" && !$error) { foreach ($filesarray as $key => $file) { - foreach($file['files'] as $filecursor) { + foreach ($file['files'] as $filecursor) { if (file_exists($filecursor["fullname"])) { $zip->addFile($filecursor["fullname"], $filecursor["relpathnamelang"]); } } - $log .= $file['item']; + $log .= '"'.$langs->trans($file['item']).'"'; + if (!empty($conf->multicompany->enabled) && is_object($mc)) + { + $log .= ',"'.(empty($arrayofentities[$file['entity']]) ? $file['entity'] : $arrayofentities[$file['entity']]).'"'; + } $log .= ','.dol_print_date($file['date'], 'dayrfc'); - $log .= ','.$file['ref']; + $log .= ','.dol_print_date($file['date_due'], 'dayrfc'); + $log .= ',"'.$file['ref'].'"'; $log .= ','.$file['amount_ht']; $log .= ','.$file['amount_ttc']; $log .= ','.$file['amount_vat']; $log .= ','.$file['paid']; - $log .= ','.$file["name"]; + $log .= ',"'.$file["name"].'"'; $log .= ','.$file['fk']; - $log .= ','.$file['thirdparty_name']; - $log .= ','.$file['thirdparty_code']; - $log .= ','.$file['country_code']; - $log .= ',"'.$file['vatnum'].'"'."\n"; + $log .= ',"'.$file['thirdparty_name'].'"'; + $log .= ',"'.$file['thirdparty_code'].'"'; + $log .= ',"'.$file['country_code'].'"'; + $log .= ',"'.$file['vatnum'].'"'; + $log .= "\n"; } $zip->addFromString('transactions.csv', $log); $zip->close(); @@ -381,13 +440,17 @@ if ($result && $action == "dl" && !$error) $form = new Form($db); $userstatic = new User($db); +$invoice = new Facture($db); +$supplier_invoice = new FactureFournisseur($db); $title = $langs->trans("ComptaFiles").' - '.$langs->trans("List"); +$help_url = ''; llxHeader('', $title, $help_url); $h = 0; -$head[$h][0] = $_SERVER["PHP_SELF"].$varlink; +$head = array(); +$head[$h][0] = $_SERVER["PHP_SELF"]; $head[$h][1] = $langs->trans("AccountantFiles"); $head[$h][2] = 'AccountancyFiles'; @@ -400,16 +463,36 @@ print ''; print $langs->trans("ReportPeriod").': '.$form->selectDate($date_start, 'date_start', 0, 0, 0, "", 1, 1, 0); print ' - '.$form->selectDate($date_stop, 'date_stop', 0, 0, 0, "", 1, 1, 0)."\n"; -// Export is for current company only ! +// Export is for current company only if (!empty($conf->multicompany->enabled) && is_object($mc)) { - print '('.$langs->trans("Entity").' : '; - $mc->dao->getEntities(); - $mc->dao->fetch($conf->entity); - print $mc->dao->label; + $mc->getInfo($conf->entity); + print '('.$langs->trans("Entity").' : '; + print ""; print ")\n"; } +print '
'; + +$listofchoices = array( + 'selectinvoices'=>array('label'=>'Invoices', 'lang'=>'bills'), + 'selectsupplierinvoices'=>array('label'=>'BillsSuppliers', 'lang'=>'bills'), + 'selectexpensereports'=>array('label'=>'ExpenseReports', 'lang'=>'trips'), + 'selectdonations'=>array('label'=>'Donations', 'lang'=>'donation'), + 'selectpaymentsofsalaries'=>array('label'=>'SalariesPayments', 'lang'=>'salaries'), + 'selectsocialcontributions'=>array('label'=>'SocialContributions') +); +foreach($listofchoices as $choice => $val) { + $checked = (((! GETPOSTISSET('search') && $action != 'searchfiles') || GETPOST($choice))?' checked="checked"':''); + print '
'.$langs->trans($val['label']).'
'; +} + print ''; print ''."\n"; @@ -425,7 +508,9 @@ if (!empty($date_start) && !empty($date_stop)) $param .= '&date_stopday='.GETPOST('date_stopday', 'int'); $param .= '&date_stopmonth='.GETPOST('date_stopmonth', 'int'); $param .= '&date_stopyear='.GETPOST('date_stopyear', 'int'); - + foreach($listofchoices as $choice => $val) { + $param.='&'.$choice.'='.(GETPOST($choice, 'int')?1:0); + } print ''."\n"; print ''; @@ -433,14 +518,9 @@ if (!empty($date_start) && !empty($date_stop)) print ''; print ''; - - //print ''; - //print ''; - //print ''; - - //print ''; - //print ''; - //print ''; + foreach($listofchoices as $choice => $val) { + print ''; + } print ''; print ''."\n"; @@ -452,7 +532,8 @@ if (!empty($date_start) && !empty($date_stop)) print ''; print_liste_field_titre($arrayfields['type']['label'], $_SERVER["PHP_SELF"], "item", "", $param, '', $sortfield, $sortorder, 'nowrap '); print_liste_field_titre($arrayfields['date']['label'], $_SERVER["PHP_SELF"], "date", "", $param, '', $sortfield, $sortorder, 'center nowrap '); - print ''; + print_liste_field_titre($arrayfields['date_due']['label'], $_SERVER["PHP_SELF"], "date_due", "", $param, '', $sortfield, $sortorder, 'center nowrap '); + print_liste_field_titre($arrayfields['ref']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'nowraponall '); print ''; print ''; print ''; @@ -497,14 +578,32 @@ if (!empty($date_start) && !empty($date_stop)) print dol_print_date($data['date'], 'day'); print "\n"; + // Date + print '\n"; + // Ref - print ''; + print ''; // File link print ''; print ''; print ''; + print ''; print ''; print ''; print ''; diff --git a/htdocs/compta/bank/account_statement_document.php b/htdocs/compta/bank/account_statement_document.php index 08447216dda..bdb3ac4620e 100644 --- a/htdocs/compta/bank/account_statement_document.php +++ b/htdocs/compta/bank/account_statement_document.php @@ -137,9 +137,9 @@ if ($id > 0 || !empty($ref)) { $modulepart = 'bank'; $permission = $user->rights->banque->modifier; $permtoedit = $user->rights->banque->modifier; - $param = '&id='.$object->id.'&num='.$num; - $uri = '&num='.$num; - $relativepathwithnofile = $id."/statement/".$num."/"; + $param = '&id='.$object->id.'&num='.urlencode($num); + $moreparam = '&num='.urlencode($num);; + $relativepathwithnofile = $id."/statement/".dol_sanitizeFileName($num)."/"; include_once DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php'; } else { diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index db9f9443f0e..297f0dd91d4 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -353,8 +353,13 @@ if (GETPOST('save') && !$cancel && $user->rights->banque->modifier) if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->banque->modifier) { $accline = new AccountLine($db); - $result = $accline->fetch(GETPOST("rowid")); + $result = $accline->fetch(GETPOST("rowid", "int")); $result = $accline->delete($user); + if ($result <= 0) { + setEventMessages($accline->error, $accline->errors, 'errors'); + } else { + setEventMessages('RecordDeleted', null, 'mesgs'); + } } diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 594cad56ea0..60d7c4f2463 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1337,6 +1337,10 @@ class Account extends CommonObject $label .= '
'.$langs->trans('AccountAccounting').': '.length_accountg($this->account_number); $label .= '
'.$langs->trans('AccountancyJournal').': '.$this->accountancy_journal; } + if (isset($this->status)) { + $label .= '
'.$langs->trans("Status").": ".$this->getLibStatut(5); + } + $linkclose = '" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; $url = DOL_URL_ROOT.'/compta/bank/card.php?id='.$this->id; @@ -1883,13 +1887,15 @@ class AccountLine extends CommonObject } /** - * Delete transaction bank line record + * Delete bank transaction record * * @param User $user User object that delete * @return int <0 if KO, >0 if OK */ public function delete(User $user = null) { + global $conf; + $nbko = 0; if ($this->rappro) @@ -1901,6 +1907,26 @@ class AccountLine extends CommonObject $this->db->begin(); + // Protection to avoid any delete of accounted lines. Protection on by default + if (empty($conf->global->BANK_ALLOW_TRANSACTION_DELETION_EVEN_IF_IN_ACCOUNTING)) + { + $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE doc_type = 'bank' AND fk_doc = ".$this->id; + $resql = $this->db->query($sql); + if ($resql) { + $obj = $this->db->fetch_object($resql); + if ($obj && $obj->nb) { + $this->error = 'ErrorRecordAlreadyInAccountingDeletionNotPossible'; + $this->db->rollback(); + return -1; + } + } + else { + $this->error = $this->db->lasterror(); + $this->db->rollback(); + return -1; + } + } + // Delete urls $result = $this->delete_urls($user); if ($result < 0) @@ -2250,11 +2276,11 @@ class AccountLine extends CommonObject /** - * Return clicable name (with picto eventually) + * Return clickable name (with picto eventually) * * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto * @param int $maxlen Longueur max libelle - * @param string $option Option ('showall') + * @param string $option Option ('', 'showall', 'showconciliated', 'showconciliatedandaccounted'). Options may be slow. * @param int $notooltip 1=Disable tooltip * @return string Chaine avec URL */ @@ -2272,7 +2298,7 @@ class AccountLine extends CommonObject if ($withpicto != 2) $result .= ($this->ref ? $this->ref : $this->rowid); $result .= $linkend; - if ($option == 'showall' || $option == 'showconciliated') $result .= ' ('; + if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') $result .= ' ('; if ($option == 'showall') { $result .= $langs->trans("BankAccount").': '; @@ -2282,12 +2308,25 @@ class AccountLine extends CommonObject $accountstatic->label = $this->bank_account_label; $result .= $accountstatic->getNomUrl(0).', '; } - if ($option == 'showall' || $option == 'showconciliated') + if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') { $result .= $langs->trans("BankLineConciliated").': '; $result .= yn($this->rappro); } - if ($option == 'showall' || $option == 'showconciliated') $result .= ')'; + if ($option == 'showall' || $option == 'showconciliatedandaccounted') + { + $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE doc_type = 'bank' AND fk_doc = ".$this->id; + $resql = $this->db->query($sql); + if ($resql) { + $obj = $this->db->fetch_object($resql); + if ($obj && $obj->nb) { + $result .= ' - '.$langs->trans("Accounted").': '.yn(1); + } else { + $result .= ' - '.$langs->trans("Accounted").': '.yn(0); + } + } + } + if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') $result .= ')'; return $result; } diff --git a/htdocs/compta/bank/class/api_bankaccounts.class.php b/htdocs/compta/bank/class/api_bankaccounts.class.php index 2ecb59861d9..1272cfcad85 100644 --- a/htdocs/compta/bank/class/api_bankaccounts.class.php +++ b/htdocs/compta/bank/class/api_bankaccounts.class.php @@ -183,10 +183,10 @@ class BankAccounts extends DolibarrApi * * @status 201 * - * @throws 401 Unauthorized: User does not have permission to configure bank accounts - * @throws 404 Not Found: Either the source or the destination bankaccount for the provided id does not exist - * @throws 422 Unprocessable Entity: Refer to detailed exception message for the cause - * @throws 500 Internal Server Error: Error(s) returned by the RDBMS + * @throws RestException 401 Unauthorized: User does not have permission to configure bank accounts + * @throws RestException 404 Not Found: Either the source or the destination bankaccount for the provided id does not exist + * @throws RestException 422 Unprocessable Entity: Refer to detailed exception message for the cause + * @throws RestException 500 Internal Server Error: Error(s) returned by the RDBMS */ public function transfer($bankaccount_from_id = 0, $bankaccount_to_id = 0, $date = null, $description = "", $amount = 0.0, $amount_to = 0.0) { diff --git a/htdocs/compta/bank/graph.php b/htdocs/compta/bank/graph.php index fbcd06a51bc..ccf677fa2b8 100644 --- a/htdocs/compta/bank/graph.php +++ b/htdocs/compta/bank/graph.php @@ -255,13 +255,14 @@ else $px1->draw($file, $fileurl); $show1 = $px1->show(); - unset($graph_datas); - unset($px1); - unset($datas); - unset($datamin); - unset($dataall); - unset($labels); - unset($amounts); + + $px1 = null; + $graph_datas =null; + $datas = null; + $datamin = null; + $dataall = null; + $labels = null; + $amounts = null; } // Graph Balance for the year @@ -349,10 +350,11 @@ else } $datamin[$i] = $object->min_desired; $dataall[$i] = $object->min_allowed; - if ($xday == '15') + /*if ($xday == '15') // Set only some label for jflot { $labels[$i] = dol_print_date($day, "%b"); - } + }*/ + $labels[$i] = dol_print_date($day, "%Y%m"); $day += 86400; $textdate = strftime("%Y%m%d", $day); $xyear = substr($textdate, 0, 4); @@ -392,13 +394,13 @@ else $show2 = $px2->show(); - unset($px2); - unset($graph_datas); - unset($datas); - unset($datamin); - unset($dataall); - unset($labels); - unset($amounts); + $px2 = null; + $graph_datas =null; + $datas = null; + $datamin = null; + $dataall = null; + $labels = null; + $amounts = null; } // Graph 3 - Balance for all time line @@ -460,14 +462,15 @@ else } else { - $datas[$i] = '' +$solde + $subtotal; + $datas[$i] = 0 + $solde + $subtotal; } $datamin[$i] = $object->min_desired; $dataall[$i] = $object->min_allowed; - if (substr($textdate, 6, 2) == '01' || $i == 0) + /*if (substr($textdate, 6, 2) == '01' || $i == 0) // Set only few label for jflot { - $labels[$i] = substr($textdate, 4, 2); - } + $labels[$i] = substr($textdate, 0, 6); + }*/ + $labels[$i] = substr($textdate, 0, 6); $day += 86400; $textdate = strftime("%Y%m%d", $day); @@ -505,13 +508,13 @@ else $show3 = $px3->show(); - unset($px3); - unset($graph_datas); - unset($datas); - unset($datamin); - unset($dataall); - unset($labels); - unset($amounts); + $px3 = null; + $graph_datas =null; + $datas = null; + $datamin = null; + $dataall = null; + $labels = null; + $amounts = null; } // Tableau 4a - Credit/Debit @@ -634,10 +637,10 @@ else $show4 = $px4->show(); - unset($graph_datas); - unset($px4); - unset($debits); - unset($credits); + $px4 = null; + $graph_datas = null; + $debits = null; + $credits = null; } // Tableau 4b - Credit/Debit @@ -742,10 +745,10 @@ else $show5 = $px5->show(); - unset($graph_datas); - unset($px5); - unset($debits); - unset($credits); + $px5 = null; + $graph_datas = null; + $debits = null; + $credits = null; } } @@ -814,6 +817,8 @@ else } print '

'; +print '
' . $langs->trans('Ref') . '' . $langs->trans("Draft") . '
'.$langs->trans('Ref').''.$langs->trans("Draft").'
' . $langs->trans('RefCustomer') . ''; - if (!empty($conf->global->MAIN_USE_PROPAL_REFCLIENT_FOR_ORDER) && ! empty($origin) && ! empty($originid)) + print '
'.$langs->trans('RefCustomer').''; + if (!empty($conf->global->MAIN_USE_PROPAL_REFCLIENT_FOR_ORDER) && !empty($origin) && !empty($originid)) print ''; + print $form->selectMultiCurrency($search_multicurrency_code, 'search_multicurrency_code', 1); + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''.$obj->ref_client.''.$obj->ref_client.''.$obj->multicurrency_code . ' - ' . $langs->trans('Currency' . $obj->multicurrency_code)."'; + $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $obj->rowid, $obj->multicurrency_tx, 'none', $obj->multicurrency_code); + print "'.price($obj->multicurrency_total_ht)."'.price($obj->multicurrency_total_vat)."'.price($obj->multicurrency_total_ttc).""; + if (!empty($conf->global->MULTICOMPANY_ALLOW_EXPORT_ACCOUNTING_DOC_FOR_ALL_ENTITIES)) { + print $mc->select_entities(GETPOSTISSET('search_entity') ? GETPOST('search_entity', 'int') : $mc->id, 'search_entity', '', false, false, false, false, true); + } else { + print $mc->label; + } + print "
'.$langs->trans("Ref").''.$langs->trans("Document").''.$langs->trans("Paid").''.$langs->trans("TotalHT").''; + print dol_print_date($data['date_due'], 'day'); + print "'.$data['ref'].''; + + if ($data['item'] == 'Invoice') { + $invoice->id = $data['id']; + $invoice->ref = $data['ref']; + print $invoice->getNomUrl(1, '', 0, 0, '', 0, 0, 0); + } elseif ($data['item'] == 'SupplierInvoice') { + $supplier_invoice->id = $data['id']; + $supplier_invoice->ref = $data['ref']; + print $supplier_invoice->getNomUrl(1, '', 0, 0, '', 0, 0, 0); + } else { + print $data['ref']; + } + print ''; - if (! empty($data['files'])) + if (!empty($data['files'])) { - foreach($data['files'] as $filecursor) { + foreach ($data['files'] as $filecursor) { print ''.($filecursor['name'] ? $filecursor['name'] : $filecursor['ref']).'
'; } } @@ -552,6 +651,7 @@ if (!empty($date_start) && !empty($date_stop)) print '
'.price(price2num($totalET, 'MT')).''.price(price2num($totalIT, 'MT')).''.price(price2num($totalVAT, 'MT')).'
'; + // Graphs if ($mode == 'standard') @@ -825,39 +830,39 @@ if ($mode == 'standard') // For month $link = "".img_previous('', 'class="valignbottom"')." ".$langs->trans("Month")." ".img_next('', 'class="valignbottom"').""; - print '
'.$link.'
'; + print '
'; $file = "movement".$account."-".$year.$month.".png"; print $show4; - print '
'; + print '
'; print $show1; - print '
'.$link.'
'; + print '
'.$link.'
'; + + print '
'; print $show5; - print '
'; + print '
'; print $show2; - print '
'; + print '
'; print $show3; - print '
'; // End of page llxFooter(); diff --git a/htdocs/compta/bank/list.php b/htdocs/compta/bank/list.php index 329ac25ef79..37193726b01 100644 --- a/htdocs/compta/bank/list.php +++ b/htdocs/compta/bank/list.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2018 Ferran Marcet + * Copyright (C) 2020 Tobias Sekan * * 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 @@ -30,8 +31,10 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; require_once DOL_DOCUMENT_ROOT.'/compta/tva/class/tva.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; -if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php'; -if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php'; +if (!empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; +if (!empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; +if (!empty($conf->categorie->enabled)) require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; // Load translation files required by the page $langs->loadLangs(array('banks', 'categories', 'accountancy', 'compta')); @@ -49,6 +52,11 @@ $search_number=GETPOST('search_number', 'alpha'); $search_status=GETPOST('search_status')?GETPOST('search_status', 'alpha'):'opened'; // 'all' or ''='opened' $optioncss = GETPOST('optioncss', 'alpha'); +if (!empty($conf->categorie->enabled)) +{ + $search_category_list = GETPOST("search_category_".Categorie::TYPE_ACCOUNT."_list", "array"); +} + // Security check if ($user->socid) $socid=$user->socid; if (! empty($user->rights->accounting->chartofaccount)) $allowed=1; // Dictionary with list of banks accounting account allowed to manager of chart account @@ -138,9 +146,9 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' * View */ -$form=new Form($db); +$form = new FormCategory($db); -$title=$langs->trans('BankAccounts'); +$title = $langs->trans('BankAccounts'); // Load array of financial accounts (opened by default) $accounts = array(); @@ -151,14 +159,26 @@ if (! empty($extrafields->attributes[$object->table_element]['label'])) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) $sql.=($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key.' as options_'.$key : ''); } // Add fields from hooks -$parameters=array(); -$reshook=$hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook -$sql.=$hookmanager->resPrint; +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook +$sql.= $hookmanager->resPrint; $sql.= " FROM ".MAIN_DB_PREFIX."bank_account as b"; if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (b.rowid = ef.fk_object)"; + +if (!empty($conf->categorie->enabled)) +{ + $sql .= Categorie::getFilterJoinQuery(Categorie::TYPE_ACCOUNT, "b.rowid"); +} + $sql.= " WHERE b.entity IN (".getEntity('bank_account').")"; if ($search_status == 'opened') $sql.= " AND clos = 0"; if ($search_status == 'closed') $sql.= " AND clos = 1"; + +if (!empty($conf->categorie->enabled)) +{ + $sql .= Categorie::getFilterSelectQuery(Categorie::TYPE_ACCOUNT, "b.rowid", $search_category_list); +} + if ($search_ref != '') $sql.=natural_search('b.ref', $search_ref); if ($search_label != '') $sql.=natural_search('b.label', $search_label); if ($search_number != '') $sql.=natural_search('b.number', $search_number); @@ -263,6 +283,10 @@ if ($sall) $moreforfilter = ''; +if (!empty($conf->categorie->enabled)) +{ + $moreforfilter .= $form->getFilterBox(Categorie::TYPE_ACCOUNT, $search_category_list); +} // Bank accounts $parameters = array(); diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index 9ae1d5d7d83..a16927bda0b 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -49,7 +49,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; $langs->loadLangs(array("banks", "categories", "companies", "bills", "trips", "donations", "loan")); $action = GETPOST('action', 'alpha'); -$id = GETPOST('account', 'int'); +$id = GETPOST('account', 'int') ? GETPOST('account', 'int') : GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); $dvid = GETPOST('dvid', 'alpha'); $numref = GETPOST('num', 'alpha'); diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php index 7ca62b67ab8..b8d259cdc8d 100644 --- a/htdocs/compta/bank/treso.php +++ b/htdocs/compta/bank/treso.php @@ -39,18 +39,18 @@ $langs->loadLangs(array('banks', 'categories', 'bills', 'companies')); // Security check if (isset($_GET["account"]) || isset($_GET["ref"])) { - $id = isset($_GET["account"])?$_GET["account"]:(isset($_GET["ref"])?$_GET["ref"]:''); + $id = isset($_GET["account"]) ? $_GET["account"] : (isset($_GET["ref"]) ? $_GET["ref"] : ''); } -$fieldid = isset($_GET["ref"])?'ref':'rowid'; -if ($user->socid) $socid=$user->socid; -$result=restrictedArea($user, 'banque', $id, 'bank_account&bank_account', '', '', $fieldid); +$fieldid = isset($_GET["ref"]) ? 'ref' : 'rowid'; +if ($user->socid) $socid = $user->socid; +$result = restrictedArea($user, 'banque', $id, 'bank_account&bank_account', '', '', $fieldid); -$vline=isset($_GET["vline"])?$_GET["vline"]:$_POST["vline"]; -$page=isset($_GET["page"])?$_GET["page"]:0; +$vline = isset($_GET["vline"]) ? $_GET["vline"] : $_POST["vline"]; +$page = isset($_GET["page"]) ? $_GET["page"] : 0; // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$hookmanager->initHooks(array('banktreso','globalcard')); +$hookmanager->initHooks(array('banktreso', 'globalcard')); /* * View @@ -61,9 +61,9 @@ $helpurl = ""; llxHeader('', $title, $helpurl); $societestatic = new Societe($db); -$facturestatic=new Facture($db); -$facturefournstatic=new FactureFournisseur($db); -$socialcontribstatic=new ChargeSociales($db); +$facturestatic = new Facture($db); +$facturefournstatic = new FactureFournisseur($db); +$socialcontribstatic = new ChargeSociales($db); $form = new Form($db); @@ -81,17 +81,17 @@ if ($_REQUEST["account"] || $_REQUEST["ref"]) $object = new Account($db); if ($_GET["account"]) { - $result=$object->fetch($_GET["account"]); + $result = $object->fetch($_GET["account"]); } if ($_GET["ref"]) { - $result=$object->fetch(0, $_GET["ref"]); - $_GET["account"]=$object->id; + $result = $object->fetch(0, $_GET["ref"]); + $_GET["account"] = $object->id; } // Onglets - $head=bank_prepare_head($object); + $head = bank_prepare_head($object); dol_fiche_head($head, 'cash', $langs->trans("FinancialAccount"), 0, 'account'); $linkback = ''.$langs->trans("BackToList").''; @@ -103,7 +103,7 @@ if ($_REQUEST["account"] || $_REQUEST["ref"]) print '
'; $solde = $object->solde(0); - if($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED)$colspan = 6; + if ($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED)$colspan = 6; else $colspan = 5; // Show next coming entries @@ -114,7 +114,7 @@ if ($_REQUEST["account"] || $_REQUEST["ref"]) print ''; print ''.$langs->trans("DateDue").''; print ''.$langs->trans("Description").''; - if($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED )print ''.$langs->trans("Entity").''; + if ($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED)print ''.$langs->trans("Entity").''; print ''.$langs->trans("ThirdParty").''; print ''.$langs->trans("Debit").''; print ''.$langs->trans("Credit").''; @@ -139,54 +139,54 @@ if ($_REQUEST["account"] || $_REQUEST["ref"]) // Customer invoices $sql = "SELECT 'invoice' as family, f.rowid as objid, f.ref as ref, f.total_ttc, f.type, f.date_lim_reglement as dlr,"; - $sql.= " s.rowid as socid, s.nom as name, s.fournisseur"; - $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; - $sql.= " WHERE f.entity IN (".getEntity('invoice').")"; - $sql.= " AND f.paye = 0 AND f.fk_statut = 1"; // Not paid - $sql.= " AND (f.fk_account IN (0, ".$object->id.") OR f.fk_account IS NULL)"; // Id bank account of invoice - $sql.= " ORDER BY dlr ASC"; + $sql .= " s.rowid as socid, s.nom as name, s.fournisseur"; + $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; + $sql .= " WHERE f.entity IN (".getEntity('invoice').")"; + $sql .= " AND f.paye = 0 AND f.fk_statut = 1"; // Not paid + $sql .= " AND (f.fk_account IN (0, ".$object->id.") OR f.fk_account IS NULL)"; // Id bank account of invoice + $sql .= " ORDER BY dlr ASC"; $sqls[] = $sql; // Supplier invoices $sql = " SELECT 'invoice_supplier' as family, ff.rowid as objid, ff.ref as ref, ff.ref_supplier as ref_supplier, (-1*ff.total_ttc) as total_ttc, ff.type, ff.date_lim_reglement as dlr,"; - $sql.= " s.rowid as socid, s.nom as name, s.fournisseur"; - $sql.= " FROM ".MAIN_DB_PREFIX."facture_fourn as ff"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON ff.fk_soc = s.rowid"; - $sql.= " WHERE ff.entity = ".$conf->entity; - $sql.= " AND ff.paye = 0 AND fk_statut = 1"; // Not paid - $sql.= " AND (ff.fk_account IN (0, ".$object->id.") OR ff.fk_account IS NULL)"; // Id bank account of supplier invoice - $sql.= " ORDER BY dlr ASC"; + $sql .= " s.rowid as socid, s.nom as name, s.fournisseur"; + $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as ff"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON ff.fk_soc = s.rowid"; + $sql .= " WHERE ff.entity = ".$conf->entity; + $sql .= " AND ff.paye = 0 AND fk_statut = 1"; // Not paid + $sql .= " AND (ff.fk_account IN (0, ".$object->id.") OR ff.fk_account IS NULL)"; // Id bank account of supplier invoice + $sql .= " ORDER BY dlr ASC"; $sqls[] = $sql; // Social contributions $sql = " SELECT 'social_contribution' as family, cs.rowid as objid, cs.libelle as ref, (-1*cs.amount) as total_ttc, ccs.libelle as type, cs.date_ech as dlr"; - $sql.= ", cs.fk_account"; - $sql.= " FROM ".MAIN_DB_PREFIX."chargesociales as cs"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_chargesociales as ccs ON cs.fk_type = ccs.id"; - $sql.= " WHERE cs.entity = ".$conf->entity; - $sql.= " AND cs.paye = 0"; // Not paid - $sql.= " AND (cs.fk_account IN (0, ".$object->id.") OR cs.fk_account IS NULL)"; // Id bank account of social contribution - $sql.= " ORDER BY dlr ASC"; + $sql .= ", cs.fk_account"; + $sql .= " FROM ".MAIN_DB_PREFIX."chargesociales as cs"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_chargesociales as ccs ON cs.fk_type = ccs.id"; + $sql .= " WHERE cs.entity = ".$conf->entity; + $sql .= " AND cs.paye = 0"; // Not paid + $sql .= " AND (cs.fk_account IN (0, ".$object->id.") OR cs.fk_account IS NULL)"; // Id bank account of social contribution + $sql .= " ORDER BY dlr ASC"; $sqls[] = $sql; // others sql $parameters = array(); $reshook = $hookmanager->executeHooks('addMoreSQL', $parameters, $object, $action); // Note that $action and $object may have been modified by hook - if(empty($reshook) and isset($hookmanager->resArray['sql'])){ + if (empty($reshook) and isset($hookmanager->resArray['sql'])) { $sqls[] = $hookmanager->resArray['sql']; } - $error=0; - $tab_sqlobjOrder=array(); - $tab_sqlobj=array(); + $error = 0; + $tab_sqlobjOrder = array(); + $tab_sqlobj = array(); - foreach($sqls as $sql){ + foreach ($sqls as $sql) { $resql = $db->query($sql); if ($resql) { while ($sqlobj = $db->fetch_object($resql)) { $tab_sqlobj[] = $sqlobj; - $tab_sqlobjOrder[]= $db->jdate($sqlobj->dlr); + $tab_sqlobjOrder[] = $db->jdate($sqlobj->dlr); } $db->free($resql); } else { @@ -195,13 +195,13 @@ if ($_REQUEST["account"] || $_REQUEST["ref"]) } // Sort array - if (! $error) + if (!$error) { array_multisort($tab_sqlobjOrder, $tab_sqlobj); // Apply distinct filter foreach ($tab_sqlobj as $key=>$value) { - $tab_sqlobj[$key] = "'" . serialize($value) . "'"; + $tab_sqlobj[$key] = "'".serialize($value)."'"; } $tab_sqlobj = array_unique($tab_sqlobj); foreach ($tab_sqlobj as $key=>$value) { @@ -221,52 +221,52 @@ if ($_REQUEST["account"] || $_REQUEST["ref"]) if ($obj->family == 'invoice_supplier') { - $showline=1; + $showline = 1; // Uncomment this line to avoid to count suppliers credit note (ff.type = 2) //$showline=(($obj->total_ttc < 0 && $obj->type != 2) || ($obj->total_ttc > 0 && $obj->type == 2)) if ($showline) { - $ref=$obj->ref; - $facturefournstatic->ref=$ref; - $facturefournstatic->id=$obj->objid; - $facturefournstatic->type=$obj->type; + $ref = $obj->ref; + $facturefournstatic->ref = $ref; + $facturefournstatic->id = $obj->objid; + $facturefournstatic->type = $obj->type; $ref = $facturefournstatic->getNomUrl(1, ''); $societestatic->id = $obj->socid; $societestatic->name = $obj->name; - $refcomp=$societestatic->getNomUrl(1, '', 24); + $refcomp = $societestatic->getNomUrl(1, '', 24); - $totalpayment = -1*$facturefournstatic->getSommePaiement(); // Payment already done + $totalpayment = -1 * $facturefournstatic->getSommePaiement(); // Payment already done } } if ($obj->family == 'invoice') { - $facturestatic->ref=$obj->ref; - $facturestatic->id=$obj->objid; - $facturestatic->type=$obj->type; + $facturestatic->ref = $obj->ref; + $facturestatic->id = $obj->objid; + $facturestatic->type = $obj->type; $ref = $facturestatic->getNomUrl(1, ''); $societestatic->id = $obj->socid; $societestatic->name = $obj->name; - $refcomp=$societestatic->getNomUrl(1, '', 24); + $refcomp = $societestatic->getNomUrl(1, '', 24); - $totalpayment = $facturestatic->getSommePaiement(); // Payment already done - $totalpayment+= $facturestatic->getSumDepositsUsed(); - $totalpayment+= $facturestatic->getSumCreditNotesUsed(); + $totalpayment = $facturestatic->getSommePaiement(); // Payment already done + $totalpayment += $facturestatic->getSumDepositsUsed(); + $totalpayment += $facturestatic->getSumCreditNotesUsed(); } if ($obj->family == 'social_contribution') { - $socialcontribstatic->ref=$obj->ref; - $socialcontribstatic->id=$obj->objid; - $socialcontribstatic->label=$obj->type; + $socialcontribstatic->ref = $obj->ref; + $socialcontribstatic->id = $obj->objid; + $socialcontribstatic->label = $obj->type; $ref = $socialcontribstatic->getNomUrl(1, 24); - $totalpayment = -1*$socialcontribstatic->getSommePaiement(); // Payment already done + $totalpayment = -1 * $socialcontribstatic->getSommePaiement(); // Payment already done } $parameters = array('obj' => $obj, 'ref' => $ref, 'refcomp' => $refcomp, 'totalpayment' => $totalpayment); $reshook = $hookmanager->executeHooks('moreFamily', $parameters, $object, $action); // Note that $action and $object may have been modified by hook - if(empty($reshook)){ + if (empty($reshook)) { $ref = isset($hookmanager->resArray['ref']) ? $hookmanager->resArray['ref'] : $ref; $refcomp = isset($hookmanager->resArray['refcomp']) ? $hookmanager->resArray['refcomp'] : $refcomp; $totalpayment = isset($hookmanager->resArray['totalpayment']) ? $hookmanager->resArray['totalpayment'] : $totalpayment; @@ -286,11 +286,14 @@ if ($_REQUEST["account"] || $_REQUEST["ref"]) else print $langs->trans("NotDefined"); print ""; print "".$ref.""; - if($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED ){ - if($obj->family == 'invoice'){ + if ($conf->global->MULTICOMPANY_INVOICE_SHARING_ENABLED) { + if ($obj->family == 'invoice') { $mc->getInfo($obj->entity); print "".$mc->label.""; - }else print ""; + } + else { + print ""; + } } print "".$refcomp.""; if ($obj->total_ttc < 0) { print ''.price(abs($total_ttc))." "; }; @@ -310,7 +313,7 @@ if ($_REQUEST["account"] || $_REQUEST["ref"]) // Other lines $parameters = array('solde' => $solde); $reshook = $hookmanager->executeHooks('printObjectLine', $parameters, $object, $action); // Note that $action and $object may have been modified by hook - if(empty($reshook)){ + if (empty($reshook)) { print $hookmanager->resPrint; $solde = isset($hookmanager->resArray['solde']) ? $hookmanager->resArray['solde'] : $solde; } diff --git a/htdocs/compta/cashcontrol/cashcontrol_card.php b/htdocs/compta/cashcontrol/cashcontrol_card.php index 4c60434619a..8e83e6a33a4 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_card.php +++ b/htdocs/compta/cashcontrol/cashcontrol_card.php @@ -345,7 +345,8 @@ if ($action == "create" || $action == "start") print ''; $array = array(); - for($i = 1; $i <= max(1, $conf->global->TAKEPOS_NUM_TERMINALS); $i++) { + $numterminals = max(1, $conf->global->TAKEPOS_NUM_TERMINALS); + for($i = 1; $i <= $numterminals; $i++) { $array[$i] = $i; } $selectedposnumber = 0; $showempty = 1; diff --git a/htdocs/compta/deplacement/index.php b/htdocs/compta/deplacement/index.php index fde600aff8f..ea180a6b0ee 100644 --- a/htdocs/compta/deplacement/index.php +++ b/htdocs/compta/deplacement/index.php @@ -115,10 +115,10 @@ if ($conf->use_javascript_ajax) include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; $dolgraph = new DolGraph(); $dolgraph->SetData($dataseries); - $dolgraph->setShowLegend(1); + $dolgraph->setShowLegend(2); $dolgraph->setShowPercent(1); $dolgraph->SetType(array('pie')); - $dolgraph->setWidth('100%'); + $dolgraph->setHeight('200'); $dolgraph->draw('idgraphstatus'); print $dolgraph->show($totalnb?0:1); diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 0d124c34f32..8510f1caa16 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -101,6 +101,9 @@ $usehm = (!empty($conf->global->MAIN_USE_HOURMIN_IN_DATE_RANGE) ? $conf->global- $object = new Facture($db); $extrafields = new ExtraFields($db); +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + // Load object if ($id > 0 || !empty($ref)) { if ($action != 'add') { @@ -138,6 +141,7 @@ $result = restrictedArea($user, 'facture', $id, '', '', 'fk_soc', $fieldid, $isd + /* * Actions */ @@ -293,31 +297,32 @@ if (empty($reshook)) // Also negative lines should not be allowed on 'non Credit notes' invoices. A test is done when adding or updating lines but we must // do it again in validation to avoid cases where invoice is created from another object that allow negative lines. - // Note that we can accept the negative line if sum with other lines with same vat is positivie: Because all the lines will be merged together + // Note that we can accept the negative line if sum with other lines with same vat makes total positive: Because all the lines will be merged together // when converted into 'available credit' and we will get a positive available credit line. // Note: Other solution if you want to add a negative line on invoice, is to create a discount for customer and consumme it (but this is possible on standard invoice only). - $array_of_pu_ht_per_vat_rate = array(); - $array_of_pu_ht_devise_per_vat_rate = array(); - foreach ($object->lines as $line) { - if (empty($array_of_pu_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code])) $array_of_pu_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] = 0; - if (empty($array_of_pu_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code])) $array_of_pu_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] = 0; - $array_of_pu_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] += $line->subprice; - $array_of_pu_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] += $line->multicurrency_subprice; + $array_of_total_ht_per_vat_rate = array(); + $array_of_total_ht_devise_per_vat_rate = array(); + foreach($object->lines as $line) { + if (empty($array_of_total_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code])) $array_of_total_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] = 0; + if (empty($array_of_total_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code])) $array_of_total_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] = 0; + $array_of_total_ht_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] += $line->total_ht; + $array_of_total_ht_devise_per_vat_rate[$line->tva_tx.'_'.$line->vat_src_code] += $line->multicurrency_total_ht; } - //var_dump($array_of_pu_ht_per_vat_rate);exit; - foreach ($array_of_pu_ht_per_vat_rate as $vatrate => $tmpvalue) - { - $pu_ht = $array_of_pu_ht_per_vat_rate[$vatrate]; - $pu_ht_devise = $array_of_pu_ht_devise_per_vat_rate[$vatrate]; - if (($pu_ht < 0 || $pu_ht_devise < 0) && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) + //var_dump($array_of_total_ht_per_vat_rate);exit; + foreach($array_of_total_ht_per_vat_rate as $vatrate => $tmpvalue) + { + $tmp_total_ht = $array_of_total_ht_per_vat_rate[$vatrate]; + $tmp_total_ht_devise = $array_of_total_ht_devise_per_vat_rate[$vatrate]; + + if (($tmp_total_ht < 0 || $tmp_total_ht_devise < 0) && empty($conf->global->FACTURE_ENABLE_NEGATIVE_LINES)) { $langs->load("errors"); if ($object->type == $object::TYPE_DEPOSIT) { // Using negative lines on deposit lead to headach and blocking problems when you want to consume them. setEventMessages($langs->trans("ErrorLinesCantBeNegativeOnDeposits"), null, 'errors'); } else { - setEventMessages($langs->trans("ErrorFieldCantBeNegativeOnInvoice", $langs->transnoentitiesnoconv("UnitPriceHT"), $langs->transnoentitiesnoconv("CustomerAbsoluteDiscountShort")), null, 'errors'); + setEventMessages($langs->trans("ErrorLinesCantBeNegativeForOneVATRate"), null, 'errors'); } $error++; $action = ''; @@ -793,7 +798,7 @@ if (empty($reshook)) $canconvert = 0; if ($object->type == Facture::TYPE_DEPOSIT && empty($discountcheck->id)) $canconvert = 1; // we can convert deposit into discount if deposit is payed (completely, partially or not at all) and not already converted (see real condition into condition used to show button converttoreduc) - if (($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_STANDARD) && $object->paye == 0 && empty($discountcheck->id)) $canconvert = 1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc) + if (($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_SITUATION) && $object->paye == 0 && empty($discountcheck->id)) $canconvert = 1; // we can convert credit note into discount if credit note is not payed back and not already converted and amount of payment is 0 (see real condition into condition used to show button converttoreduc) if ($canconvert) { $db->begin(); @@ -1386,12 +1391,12 @@ if (empty($reshook)) dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines or deposit lines"); $result = $srcobject->fetch($object->origin_id); - // If deposit invoice - if ($_POST['type'] == Facture::TYPE_DEPOSIT) - { - $typeamount = GETPOST('typedeposit', 'alpha'); - $valuedeposit = GETPOST('valuedeposit', 'int'); + $typeamount = GETPOST('typedeposit', 'aZ09'); + $valuedeposit = GETPOST('valuedeposit', 'int'); + // If deposit invoice + if ($_POST['type'] == Facture::TYPE_DEPOSIT && in_array($typeamount, array('amount', 'variable'))) + { $amountdeposit = array(); if (!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA)) { @@ -1419,7 +1424,7 @@ if (empty($reshook)) { $amountdeposit[0] = $valuedeposit; } - else + elseif ($typeamount == 'variable') { if ($result > 0) { @@ -1449,11 +1454,15 @@ if (empty($reshook)) $amount_ttc_diff = $amountdeposit[0]; } + foreach ($amountdeposit as $tva => $amount) { if (empty($amount)) continue; - $arraylist = array('amount' => 'FixAmount', 'variable' => 'VarAmount'); + $arraylist = array( + 'amount' => 'FixAmount', + 'variable' => 'VarAmount' + ); $descline = '(DEPOSIT)'; //$descline.= ' - '.$langs->trans($arraylist[$typeamount]); if ($typeamount == 'amount') { @@ -1500,7 +1509,8 @@ if (empty($reshook)) $object->updateline($object->lines[0]->id, $object->lines[0]->desc, $subprice_diff, $object->lines[0]->qty, $object->lines[0]->remise_percent, $object->lines[0]->date_start, $object->lines[0]->date_end, $object->lines[0]->tva_tx, 0, 0, 'HT', $object->lines[0]->info_bits, $object->lines[0]->product_type, 0, 0, 0, $object->lines[0]->pa_ht, $object->lines[0]->label, 0, array(), 100); } } - else + + if ($_POST['type'] != Facture::TYPE_DEPOSIT || ($_POST['type'] == Facture::TYPE_DEPOSIT && $typeamount == 'variablealllines')) { if ($result > 0) { @@ -1511,6 +1521,16 @@ if (empty($reshook)) $lines = $srcobject->lines; } + // If we create a deposit with all lines and a percent, we change amount + if ($_POST['type'] == Facture::TYPE_DEPOSIT && $typeamount == 'variablealllines') { + if (is_array($lines)) { + foreach($lines as $line) { + // We keep ->subprice and ->pa_ht, but we change the qty + $line->qty = price2num($line->qty * $valuedeposit / 100, 'MS'); + } + } + } + $fk_parent_line = 0; $num = count($lines); for ($i = 0; $i < $num; $i++) @@ -2994,8 +3014,12 @@ if ($action == 'create') if (($origin == 'propal') || ($origin == 'commande')) { print ''; - $arraylist = array('amount' => $langs->transnoentitiesnoconv('FixAmount', $langs->transnoentitiesnoconv('Deposit')), 'variable' => $langs->transnoentitiesnoconv('VarAmountOneLine', $langs->transnoentitiesnoconv('Deposit'))); - print $form->selectarray('typedeposit', $arraylist, GETPOST('typedeposit'), 0, 0, 0, '', 1); + $arraylist = array( + 'amount' => $langs->transnoentitiesnoconv('FixAmount', $langs->transnoentitiesnoconv('Deposit')), + 'variable' => $langs->transnoentitiesnoconv('VarAmountOneLine', $langs->transnoentitiesnoconv('Deposit')), + 'variablealllines' => $langs->transnoentitiesnoconv('VarAmountAllLines') + ); + print $form->selectarray('typedeposit', $arraylist, GETPOST('typedeposit', 'aZ09'), 0, 0, 0, '', 1); print ''; print ''.$langs->trans('Value').':'; } @@ -3332,8 +3356,8 @@ if ($action == 'create') print ''; // Bank Account - if (isset($_POST['fk_account'])) { - $fk_account = $_POST['fk_account']; + if (GETPOSTISSET('fk_account')) { + $fk_account = GETPOST('fk_account'); } print ''.$langs->trans('BankAccount').''; @@ -3621,7 +3645,7 @@ elseif ($id > 0 || !empty($ref)) // Confirmation de la conversion de l'avoir en reduc if ($action == 'converttoreduc') { - if ($object->type == Facture::TYPE_STANDARD) $type_fac = 'ExcessReceived'; + if ($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_SITUATION) $type_fac = 'ExcessReceived'; elseif ($object->type == Facture::TYPE_CREDIT_NOTE) $type_fac = 'CreditNote'; elseif ($object->type == Facture::TYPE_DEPOSIT) $type_fac = 'Deposit'; $text = $langs->trans('ConfirmConvertToReduc', strtolower($langs->transnoentities($type_fac))); @@ -4498,7 +4522,7 @@ elseif ($id > 0 || !empty($ref)) $current_situation_counter = array(); foreach ($object->tab_previous_situation_invoice as $prev_invoice) { - $totalpaye = $prev_invoice->getSommePaiement(); + $totalpaye_prev = $prev_invoice->getSommePaiement(); $total_prev_ht += $prev_invoice->total_ht; $total_prev_ttc += $prev_invoice->total_ttc; $current_situation_counter[] = (($prev_invoice->type == Facture::TYPE_CREDIT_NOTE) ?-1 : 1) * $prev_invoice->situation_counter; @@ -4509,7 +4533,7 @@ elseif ($id > 0 || !empty($ref)) if (!empty($conf->banque->enabled)) print ''; print ''.price($prev_invoice->total_ht).''; print ''.price($prev_invoice->total_ttc).''; - print ''.$prev_invoice->getLibStatut(3, $totalpaye).''; + print ''.$prev_invoice->getLibStatut(3, $totalpaye_prev).''; print ''; } } @@ -5074,9 +5098,9 @@ elseif ($id > 0 || !empty($ref)) } // Reverse back money or convert to reduction - if ($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_STANDARD) { + if ($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_SITUATION) { // For credit note only - if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercanissuepayment) + if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $usercanissuepayment) { if ($resteapayer == 0) { @@ -5089,13 +5113,13 @@ elseif ($id > 0 || !empty($ref)) } // For standard invoice with excess received - if ($object->type == Facture::TYPE_STANDARD && empty($object->paye) && ($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits) < 0 && $usercancreate && empty($discount->id)) + if (($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_SITUATION) && $object->statut == Facture::STATUS_VALIDATED && empty($object->paye) && $resteapayer < 0 && $usercancreate && empty($discount->id)) { print ''.$langs->trans('ConvertExcessReceivedToReduc').''; } // For credit note - if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0 && $usercancreate - && (!empty($conf->global->INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED) || $object->getSommePaiement() == 0) + if ($object->type == Facture::TYPE_CREDIT_NOTE && $object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $usercancreate + && (! empty($conf->global->INVOICE_ALLOW_REUSE_OF_CREDIT_WHEN_PARTIALLY_REFUNDED) || $object->getSommePaiement() == 0) ) { print ''.$langs->trans('ConvertToReduc').''; } @@ -5107,7 +5131,7 @@ elseif ($id > 0 || !empty($ref)) } // Classify paid - if (($object->statut == 1 && $object->paye == 0 && $usercanissuepayment && (($object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT && $resteapayer <= 0) || ($object->type == Facture::TYPE_CREDIT_NOTE && $resteapayer >= 0))) + if (($object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $usercanissuepayment && (($object->type != Facture::TYPE_CREDIT_NOTE && $object->type != Facture::TYPE_DEPOSIT && $resteapayer <= 0) || ($object->type == Facture::TYPE_CREDIT_NOTE && $resteapayer >= 0))) || ($object->type == Facture::TYPE_DEPOSIT && $object->paye == 0 && $object->total_ttc > 0 && $resteapayer == 0 && $usercanissuepayment && empty($discount->id)) ) { @@ -5116,7 +5140,7 @@ elseif ($id > 0 || !empty($ref)) // Classify 'closed not completely paid' (possible si validee et pas encore classee payee) - if ($object->statut == 1 && $object->paye == 0 && $resteapayer > 0 && $usercanissuepayment) + if ($object->statut == Facture::STATUS_VALIDATED && $object->paye == 0 && $resteapayer > 0 && $usercanissuepayment) { if ($totalpaye > 0 || $totalcreditnotes > 0) { diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index 7c7437bfb8e..969d351d1bb 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -1,5 +1,6 @@ +/* Copyright (C) 2020 Thibault FOUCART * * 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,11 +64,65 @@ class Invoices extends DolibarrApi */ public function get($id, $contact_list = 1) { + return $this->_fetch($id, '', '', $contact_list); + } + + /** + * Get properties of an invoice object by ref + * + * Return an array with invoice informations + * + * @param string $ref Ref of object + * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id + * @return array|mixed data without useless information + * + * @url GET ref/{ref} + * + * @throws RestException + */ + public function getByRef($ref, $contact_list = 1) + { + return $this->_fetch('', $ref, '', $contact_list); + } + + /** + * Get properties of an invoice object by ref_ext + * + * Return an array with invoice informations + * + * @param string $ref_ext External reference of object + * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id + * @return array|mixed data without useless information + * + * @url GET ref_ext/{ref_ext} + * + * @throws RestException + */ + public function getByRefExt($ref_ext, $contact_list = 1) + { + return $this->_fetch('', '', $ref_ext, $contact_list); + } + + /** + * Get properties of an invoice object + * + * Return an array with invoice informations + * + * @param int $id ID of order + * @param string $ref Ref of object + * @param string $ref_ext External reference of object + * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id + * @return array|mixed data without useless information + * + * @throws RestException + */ + private function _fetch($id, $ref = '', $ref_ext = '', $contact_list = 1) + { if (!DolibarrApiAccess::$user->rights->facture->lire) { throw new RestException(401); } - $result = $this->invoice->fetch($id); + $result = $this->invoice->fetch($id, $ref, $ref_ext); if (!$result) { throw new RestException(404, 'Invoice not found'); } @@ -87,7 +142,7 @@ class Invoices extends DolibarrApi $this->invoice->fetchObjectLinked(); return $this->_cleanObjectDatas($this->invoice); - } + } /** * List invoices @@ -242,10 +297,10 @@ class Invoices extends DolibarrApi * @url POST /createfromorder/{orderid} * * @return int - * @throws 400 - * @throws 401 - * @throws 404 - * @throws 405 + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 */ public function createInvoiceFromOrder($orderid) { @@ -318,10 +373,9 @@ class Invoices extends DolibarrApi * * @return array * - * @throws 200 - * @throws 304 - * @throws 401 - * @throws 404 + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 Invoice not found */ public function putLine($id, $lineid, $request_data = null) { @@ -383,8 +437,9 @@ class Invoices extends DolibarrApi * @url POST {id}/contact/{contactid}/{type} * * @return int - * @throws 401 - * @throws 404 + * + * @throws RestException 401 + * @throws RestException 404 */ public function postContact($id, $contactid, $type) { @@ -424,9 +479,10 @@ class Invoices extends DolibarrApi * @url DELETE {id}/contact/{rowid} * * @return array - * @throws 401 - * @throws 404 - * @throws 500 + * + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 */ public function deleteContact($id, $rowid) { @@ -463,10 +519,10 @@ class Invoices extends DolibarrApi * * @return array * - * @throws 400 - * @throws 401 - * @throws 404 - * @throws 405 + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 */ public function deleteLine($id, $lineid) { @@ -591,10 +647,10 @@ class Invoices extends DolibarrApi * * @return int * - * @throws 200 - * @throws 401 - * @throws 404 - * @throws 400 + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 400 */ public function postLine($id, $request_data = null) { @@ -673,11 +729,10 @@ class Invoices extends DolibarrApi * * @return array * - * @throws 200 - * @throws 304 - * @throws 401 - * @throws 404 - * @throws 500 + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 * */ public function addContact($id, $fk_socpeople, $type_contact, $source, $notrigger = 0) @@ -723,11 +778,10 @@ class Invoices extends DolibarrApi * * @return array * - * @throws 200 - * @throws 304 - * @throws 401 - * @throws 404 - * @throws 500 + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 * */ public function settodraft($id, $idwarehouse = -1) @@ -827,11 +881,10 @@ class Invoices extends DolibarrApi * * @return array An invoice object * - * @throws 200 - * @throws 304 - * @throws 401 - * @throws 404 - * @throws 500 + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 */ public function settopaid($id, $close_code = '', $close_note = '') { @@ -878,11 +931,10 @@ class Invoices extends DolibarrApi * * @return array An invoice object * - * @throws 200 - * @throws 304 - * @throws 401 - * @throws 404 - * @throws 500 + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 */ public function settounpaid($id) { @@ -927,11 +979,10 @@ class Invoices extends DolibarrApi * * @return array An invoice object * - * @throws 200 - * @throws 304 - * @throws 401 - * @throws 404 - * @throws 500 + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 */ public function markAsCreditAvailable($id) { @@ -1103,10 +1154,11 @@ class Invoices extends DolibarrApi * @url POST {id}/usediscount/{discountid} * * @return int - * @throws 400 - * @throws 401 - * @throws 404 - * @throws 405 + * + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 */ public function useDiscount($id, $discountid) { @@ -1149,10 +1201,11 @@ class Invoices extends DolibarrApi * @url POST {id}/usecreditnote/{discountid} * * @return int - * @throws 400 - * @throws 401 - * @throws 404 - * @throws 405 + * + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 */ public function useCreditNote($id, $discountid) { @@ -1194,10 +1247,11 @@ class Invoices extends DolibarrApi * @url GET {id}/payments * * @return array - * @throws 400 - * @throws 401 - * @throws 404 - * @throws 405 + * + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 */ public function getPayments($id) { @@ -1243,9 +1297,10 @@ class Invoices extends DolibarrApi * @url POST {id}/payments * * @return int Payment ID - * @throws 400 - * @throws 401 - * @throws 404 + * + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 */ public function addPayment($id, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_paiement = '', $comment = '', $chqemetteur = '', $chqbank = '') { @@ -1362,10 +1417,11 @@ class Invoices extends DolibarrApi * @url POST /paymentsdistributed * * @return int Payment ID - * @throws 400 - * @throws 401 - * @throws 403 - * @throws 404 + * + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 403 + * @throws RestException 404 */ public function addPaymentDistributed($arrayofamounts, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_paiement = '', $comment = '', $chqemetteur = '', $chqbank = '') { diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 8a25ee42745..fdffc320880 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -128,8 +128,8 @@ class FactureRec extends CommonInvoice 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>30), //'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35), 'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>40), - 'remise_percent' =>array('type'=>'double', 'label'=>'Remise percent', 'enabled'=>1, 'visible'=>-1, 'position'=>45), - 'remise_absolue' =>array('type'=>'double', 'label'=>'Remise absolue', 'enabled'=>1, 'visible'=>-1, 'position'=>50), + //'remise_percent' =>array('type'=>'double', 'label'=>'Remise percent', 'enabled'=>1, 'visible'=>-1, 'position'=>45), + //'remise_absolue' =>array('type'=>'double', 'label'=>'Remise absolue', 'enabled'=>1, 'visible'=>-1, 'position'=>50), 'tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>-1, 'position'=>55, 'isameasure'=>1), 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'isameasure'=>1), 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>65, 'isameasure'=>1), @@ -150,20 +150,19 @@ class FactureRec extends CommonInvoice 'nb_gen_done' =>array('type'=>'integer', 'label'=>'Nb gen done', 'enabled'=>1, 'visible'=>-1, 'position'=>140), 'nb_gen_max' =>array('type'=>'integer', 'label'=>'Nb gen max', 'enabled'=>1, 'visible'=>-1, 'position'=>145), 'frequency' =>array('type'=>'integer', 'label'=>'Frequency', 'enabled'=>1, 'visible'=>-1, 'position'=>150), - 'usenewprice' =>array('type'=>'integer', 'label'=>'Usenewprice', 'enabled'=>1, 'visible'=>-1, 'position'=>155), - 'revenuestamp' =>array('type'=>'double(24,8)', 'label'=>'Revenuestamp', 'enabled'=>1, 'visible'=>-1, 'position'=>160), + 'usenewprice' =>array('type'=>'integer', 'label'=>'UseNewPrice', 'enabled'=>1, 'visible'=>0, 'position'=>155), + 'revenuestamp' =>array('type'=>'double(24,8)', 'label'=>'RevenueStamp', 'enabled'=>1, 'visible'=>-1, 'position'=>160, 'isameasure'=>1), 'auto_validate' =>array('type'=>'integer', 'label'=>'Auto validate', 'enabled'=>1, 'visible'=>-1, 'position'=>165), 'generate_pdf' =>array('type'=>'integer', 'label'=>'Generate pdf', 'enabled'=>1, 'visible'=>-1, 'position'=>170), 'fk_account' =>array('type'=>'integer', 'label'=>'Fk account', 'enabled'=>1, 'visible'=>-1, 'position'=>175), 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'Fk multicurrency', 'enabled'=>1, 'visible'=>-1, 'position'=>180), 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'Multicurrency code', 'enabled'=>1, 'visible'=>-1, 'position'=>185), - 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency tx', 'enabled'=>1, 'visible'=>-1, 'position'=>190), - 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ht', 'enabled'=>1, 'visible'=>-1, 'position'=>195), - 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total tva', 'enabled'=>1, 'visible'=>-1, 'position'=>200), - 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ttc', 'enabled'=>1, 'visible'=>-1, 'position'=>205), + 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency tx', 'enabled'=>1, 'visible'=>-1, 'position'=>190, 'isameasure'=>1), + 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ht', 'enabled'=>1, 'visible'=>-1, 'position'=>195, 'isameasure'=>1), + 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total tva', 'enabled'=>1, 'visible'=>-1, 'position'=>200, 'isameasure'=>1), + 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ttc', 'enabled'=>1, 'visible'=>-1, 'position'=>205, 'isameasure'=>1), 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>210), 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>215), - 'vat_src_code' =>array('type'=>'varchar(10)', 'label'=>'Vat src code', 'enabled'=>1, 'visible'=>-1, 'position'=>220), 'suspended' =>array('type'=>'integer', 'label'=>'Suspended', 'enabled'=>1, 'visible'=>-1, 'position'=>225), ); // END MODULEBUILDER PROPERTIES @@ -1676,7 +1675,7 @@ class FactureRec extends CommonInvoice $xnbp++; } - $this->usenewprice = 1; + $this->usenewprice = 0; } /** diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index a9a1e286d1e..b9e80ca1cf8 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -112,7 +112,13 @@ class Facture extends CommonInvoice public $date; // Date invoice public $datem; public $ref_client; - public $ref_int; + + /** + * @var int Ref Int + * @deprecated + */ + public $ref_int; // deprecated + //Check constants for types public $type = self::TYPE_STANDARD; @@ -250,15 +256,15 @@ class Facture extends CommonInvoice /** * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. */ - public $fields=array( + public $fields = array( 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), 'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>15), 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>20, 'index'=>1), 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>25), - 'ref_int' =>array('type'=>'varchar(255)', 'label'=>'Ref int', 'enabled'=>1, 'visible'=>0, 'position'=>30), + 'ref_int' =>array('type'=>'varchar(255)', 'label'=>'Ref int', 'enabled'=>1, 'visible'=>0, 'position'=>30), // deprecated 'type' =>array('type'=>'smallint(6)', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35), 'ref_client' =>array('type'=>'varchar(255)', 'label'=>'Ref client', 'enabled'=>1, 'visible'=>-1, 'position'=>40), - 'increment' =>array('type'=>'varchar(10)', 'label'=>'Increment', 'enabled'=>1, 'visible'=>-1, 'position'=>45), + //'increment' =>array('type'=>'varchar(10)', 'label'=>'Increment', 'enabled'=>1, 'visible'=>-1, 'position'=>45), 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>50), 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>55), 'datef' =>array('type'=>'date', 'label'=>'DateInvoice', 'enabled'=>1, 'visible'=>-1, 'position'=>60), @@ -267,18 +273,17 @@ class Facture extends CommonInvoice 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>75), 'paye' =>array('type'=>'smallint(6)', 'label'=>'InvoicePaidCompletely', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>80), //'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>85), - 'remise_percent' =>array('type'=>'double', 'label'=>'Remise percent', 'enabled'=>1, 'visible'=>-1, 'position'=>90), - 'remise_absolue' =>array('type'=>'double', 'label'=>'Remise absolue', 'enabled'=>1, 'visible'=>-1, 'position'=>95), - 'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>100), + 'remise_percent' =>array('type'=>'double', 'label'=>'RelativeDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>90), + 'remise_absolue' =>array('type'=>'double', 'label'=>'CustomerRelativeDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>95), + //'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>100), 'close_code' =>array('type'=>'varchar(16)', 'label'=>'EarlyClosingReason', 'enabled'=>1, 'visible'=>-1, 'position'=>105), 'close_note' =>array('type'=>'varchar(128)', 'label'=>'EarlyClosingComment', 'enabled'=>1, 'visible'=>-1, 'position'=>110), 'tva' =>array('type'=>'double(24,8)', 'label'=>'TotalVAT', 'enabled'=>1, 'visible'=>-1, 'position'=>115, 'isameasure'=>1), - 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>120, 'isameasure'=>1), - 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>125, 'isameasure'=>1), + 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'LocalTax1', 'enabled'=>1, 'visible'=>-1, 'position'=>120, 'isameasure'=>1), + 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'LocalTax2', 'enabled'=>1, 'visible'=>-1, 'position'=>125, 'isameasure'=>1), 'revenuestamp' =>array('type'=>'double(24,8)', 'label'=>'RevenueStamp', 'enabled'=>1, 'visible'=>-1, 'position'=>130, 'isameasure'=>1), 'total' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>135, 'isameasure'=>1), 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>140, 'isameasure'=>1), - 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>150), 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>155), 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>160), @@ -293,7 +298,6 @@ class Facture extends CommonInvoice 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>205), 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>210), 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>215), - 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>220), 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>225), 'situation_cycle_ref' =>array('type'=>'smallint(6)', 'label'=>'Situation cycle ref', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION', 'visible'=>-1, 'position'=>230), 'situation_counter' =>array('type'=>'smallint(6)', 'label'=>'Situation counter', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION', 'visible'=>-1, 'position'=>235), @@ -301,19 +305,21 @@ class Facture extends CommonInvoice 'retained_warranty' =>array('type'=>'double', 'label'=>'Retained warranty', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION_RETAINED_WARRANTY', 'visible'=>-1, 'position'=>245), 'retained_warranty_date_limit' =>array('type'=>'date', 'label'=>'Retained warranty date limit', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION_RETAINED_WARRANTY', 'visible'=>-1, 'position'=>250), 'retained_warranty_fk_cond_reglement' =>array('type'=>'integer', 'label'=>'Retained warranty fk cond reglement', 'enabled'=>'$conf->global->INVOICE_USE_SITUATION_RETAINED_WARRANTY', 'visible'=>-1, 'position'=>255), - 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermsCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>260), - 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermsLocation', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>265), + 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>260), + 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermLabel', 'enabled'=>'$conf->incoterm->enabled', 'visible'=>-1, 'position'=>265), 'date_pointoftax' =>array('type'=>'date', 'label'=>'DatePointOfTax', 'enabled'=>'$conf->global->INVOICE_POINTOFTAX_DATE', 'visible'=>-1, 'position'=>270), 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'MulticurrencyID', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>275), - 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCode', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>280), - 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>285), - 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ht', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>290), - 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total tva', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>295), - 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Multicurrency total ttc', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>300), + 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCurrency', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>280), + 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>285, 'isameasure'=>1), + 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountHT', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>290, 'isameasure'=>1), + 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountVAT', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>295, 'isameasure'=>1), + 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyAmountTTC', 'enabled'=>'$conf->multicurrency->enabled', 'visible'=>-1, 'position'=>300, 'isameasure'=>1), 'fk_fac_rec_source' =>array('type'=>'integer', 'label'=>'RecurringInvoiceSource', 'enabled'=>1, 'visible'=>-1, 'position'=>305), - 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>310), + 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>-1, 'position'=>310), 'module_source' =>array('type'=>'varchar(32)', 'label'=>'POSModule', 'enabled'=>1, 'visible'=>-1, 'position'=>315), 'pos_source' =>array('type'=>'varchar(32)', 'label'=>'POSTerminal', 'enabled'=>1, 'visible'=>-1, 'position'=>320), + 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Paid', 3=>'Abandonned')), + 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900), ); // END MODULEBUILDER PROPERTIES @@ -477,7 +483,7 @@ class Facture extends CommonInvoice $this->fk_project = GETPOST('projectid', 'int') > 0 ? ((int) GETPOST('projectid', 'int')) : $_facrec->fk_project; $this->note_public = GETPOST('note_public', 'none') ? GETPOST('note_public', 'none') : $_facrec->note_public; $this->note_private = GETPOST('note_private', 'none') ? GETPOST('note_private', 'none') : $_facrec->note_private; - $this->modelpdf = GETPOST('model', 'alpha') ? GETPOST('model', 'apha') : $_facrec->modelpdf; + $this->modelpdf = GETPOST('model', 'alpha') ? GETPOST('model', 'alpha') : $_facrec->modelpdf; $this->cond_reglement_id = GETPOST('cond_reglement_id', 'int') > 0 ? ((int) GETPOST('cond_reglement_id', 'int')) : $_facrec->cond_reglement_id; $this->mode_reglement_id = GETPOST('mode_reglement_id', 'int') > 0 ? ((int) GETPOST('mode_reglement_id', 'int')) : $_facrec->mode_reglement_id; $this->fk_account = GETPOST('fk_account') > 0 ? ((int) GETPOST('fk_account')) : $_facrec->fk_account; @@ -1253,6 +1259,14 @@ class Facture extends CommonInvoice $line->date_start = $object->lines[$i]->date_start; $line->date_end = $object->lines[$i]->date_end; + // Multicurrency + $line->fk_multicurrency = $object->lines[$i]->fk_multicurrency; + $line->multicurrency_code = $object->lines[$i]->multicurrency_code; + $line->multicurrency_subprice = $object->lines[$i]->multicurrency_subprice; + $line->multicurrency_total_ht = $object->lines[$i]->multicurrency_total_ht; + $line->multicurrency_total_tva = $object->lines[$i]->multicurrency_total_tva; + $line->multicurrency_total_ttc = $object->lines[$i]->multicurrency_total_ttc; + $line->fk_fournprice = $object->lines[$i]->fk_fournprice; $marginInfos = getMarginInfos($object->lines[$i]->subprice, $object->lines[$i]->remise_percent, $object->lines[$i]->tva_tx, $object->lines[$i]->localtax1_tx, $object->lines[$i]->localtax2_tx, $object->lines[$i]->fk_fournprice, $object->lines[$i]->pa_ht); $line->pa_ht = $marginInfos[0]; @@ -1267,6 +1281,7 @@ class Facture extends CommonInvoice $this->socid = $object->socid; $this->fk_project = $object->fk_project; + $this->fk_account = $object->fk_account; $this->cond_reglement_id = $object->cond_reglement_id; $this->mode_reglement_id = $object->mode_reglement_id; $this->availability_id = $object->availability_id; @@ -1388,6 +1403,9 @@ class Facture extends CommonInvoice if (!empty($this->total_ttc)) $label .= '
'.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); if ($moretitle) $label .= ' - '.$moretitle; + if (isset($this->statut) && isset($this->alreadypaid)) { + $label .= '
'.$langs->trans("Status").": ".$this->getLibStatut(5, $this->alreadypaid); + } } $linkclose = ($target ? ' target="'.$target.'"' : ''); @@ -1436,20 +1454,20 @@ class Facture extends CommonInvoice } /** - * Get object and lines from database + * Get object from database. Get also lines. * - * @param int $rowid Id of object to load - * @param string $ref Reference of invoice - * @param string $ref_ext External reference of invoice - * @param int $ref_int Internal reference of other object + * @param int $rowid Id of object to load + * @param string $ref Reference of invoice + * @param string $ref_ext External reference of invoice + * @param int $notused Not used * @param bool $fetch_situation Fetch the previous and next situation in $tab_previous_situation_invoice and $tab_next_situation_invoice - * @return int >0 if OK, <0 if KO, 0 if not found + * @return int >0 if OK, <0 if KO, 0 if not found */ - public function fetch($rowid, $ref = '', $ref_ext = '', $ref_int = '', $fetch_situation = false) + public function fetch($rowid, $ref = '', $ref_ext = '', $notused = '', $fetch_situation = false) { global $conf; - if (empty($rowid) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1; + if (empty($rowid) && empty($ref) && empty($ref_ext)) return -1; $sql = 'SELECT f.rowid,f.entity,f.ref,f.ref_client,f.ref_ext,f.ref_int,f.type,f.fk_soc'; $sql .= ', f.tva, f.localtax1, f.localtax2, f.total, f.total_ttc, f.revenuestamp'; @@ -1481,7 +1499,7 @@ class Facture extends CommonInvoice $sql .= ' WHERE f.entity IN ('.getEntity('invoice').')'; // Dont't use entity if you use rowid if ($ref) $sql .= " AND f.ref='".$this->db->escape($ref)."'"; if ($ref_ext) $sql .= " AND f.ref_ext='".$this->db->escape($ref_ext)."'"; - if ($ref_int) $sql .= " AND f.ref_int='".$this->db->escape($ref_int)."'"; + if ($notused) $sql .= " AND f.ref_int='".$this->db->escape($notused)."'"; // deprecated } dol_syslog(get_class($this)."::fetch", LOG_DEBUG); @@ -1514,10 +1532,16 @@ class Facture extends CommonInvoice $this->total_localtax2 = $obj->localtax2; $this->total_ttc = $obj->total_ttc; $this->revenuestamp = $obj->revenuestamp; - $this->paye = $obj->paye; + $this->paye = $obj->paye; $this->close_code = $obj->close_code; $this->close_note = $obj->close_note; - $this->socid = $obj->fk_soc; + + $this->socid = $obj->fk_soc; + $this->thirdparty = null; // Clear if another value was already set by fetch_thirdparty + + $this->fk_project = $obj->fk_project; + $this->project = null; // Clear if another value was already set by fetch_projet + $this->statut = $obj->fk_statut; $this->date_lim_reglement = $this->db->jdate($obj->dlr); $this->mode_reglement_id = $obj->fk_mode_reglement; @@ -1528,7 +1552,6 @@ class Facture extends CommonInvoice $this->cond_reglement = $obj->cond_reglement_libelle; $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc; $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account : null; - $this->fk_project = $obj->fk_project; $this->fk_facture_source = $obj->fk_facture_source; $this->fk_fac_rec_source = $obj->fk_fac_rec_source; $this->note = $obj->note_private; // deprecated @@ -1574,10 +1597,7 @@ class Facture extends CommonInvoice // fetch optionals attributes and labels $this->fetch_optionals(); - /* - * Lines - */ - + // Lines $this->lines = array(); $result = $this->fetch_lines(); @@ -2408,12 +2428,23 @@ class Facture extends CommonInvoice * @param string $force_number Reference to force on invoice * @param int $idwarehouse Id of warehouse to use for stock decrease if option to decreasenon stock is on (0=no decrease) * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @param int $batch_rule [=0] 0 not decrement batch, else batch rule to use + * 1=take in batches ordered by sellby and eatby dates * @return int <0 if KO, 0=Nothing done because invoice is not a draft, >0 if OK */ - public function validate($user, $force_number = '', $idwarehouse = 0, $notrigger = 0) + public function validate($user, $force_number = '', $idwarehouse = 0, $notrigger = 0, $batch_rule = 0) { global $conf, $langs; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + $productStatic = null; + $warehouseStatic = null; + if ($batch_rule > 0) { + require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + require_once DOL_DOCUMENT_ROOT . '/product/class/productbatch.class.php'; + require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php'; + $productStatic = new Product($this->db); + $warehouseStatic = new Entrepot($this->db); + } $now = dol_now(); @@ -2505,7 +2536,7 @@ class Facture extends CommonInvoice { $num = $this->ref; } - $this->newref = $num; + $this->newref = dol_sanitizeFileName($num); if ($num) { @@ -2555,11 +2586,94 @@ class Facture extends CommonInvoice $mouvP = new MouvementStock($this->db); $mouvP->origin = &$this; // We decrease stock for product - if ($this->type == self::TYPE_CREDIT_NOTE) $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceValidatedInDolibarr", $num)); - else $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr", $num)); - if ($result < 0) { - $error++; - $this->error = $mouvP->error; + if ($this->type == self::TYPE_CREDIT_NOTE) { + $result = $mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, 0, $langs->trans("InvoiceValidatedInDolibarr", $num)); + if ($result < 0) { + $error++; + $this->error = $mouvP->error; + } + } else { + $is_batch_line = false; + if ($batch_rule > 0) { + $productStatic->fetch($this->lines[$i]->fk_product); + if ($productStatic->hasbatch()) { + $is_batch_line = true; + $product_qty_remain = $this->lines[$i]->qty; + + $sortfield = null; + $sortorder = null; + // find all batch order by sellby (DLC) and eatby dates (DLUO) first + if ($batch_rule == Productbatch::BATCH_RULE_SELLBY_EATBY_DATES_FIRST) { + $sortfield = 'pl.sellby,pl.eatby,pb.qty,pl.rowid'; + $sortorder = 'ASC,ASC,ASC,ASC'; + } + + $resBatchList = Productbatch::findAllForProduct($this->db, $productStatic->id, $idwarehouse, (!empty($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER) ? null : 0), $sortfield, $sortorder); + if (!is_array($resBatchList)) { + $error++; + $this->error = $this->db->lasterror(); + } + + if (!$error) { + $batchList = $resBatchList; + if (empty($batchList)) { + $error++; + $langs->load('errors'); + $warehouseStatic->fetch($idwarehouse); + $this->error = $langs->trans('ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref); + dol_syslog(__METHOD__ . ' Error: ' . $langs->transnoentitiesnoconv('ErrorBatchNoFoundForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR); + } + + foreach ($batchList as $batch) { + if ($batch->qty <= 0) continue; // try to decrement only batches have positive quantity first + + // enough quantity in this batch + if ($batch->qty >= $product_qty_remain) { + $product_batch_qty = $product_qty_remain; + } // not enough (take all in batch) + else { + $product_batch_qty = $batch->qty; + } + $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_batch_qty, $this->lines[$i]->subprice, $langs->trans('InvoiceValidatedInDolibarr', $num), '', '', '', $batch->batch); + if ($result < 0) { + $error++; + $this->error = $mouvP->error; + break; + } + + $product_qty_remain -= $product_batch_qty; + // all product quantity was decremented + if ($product_qty_remain <= 0) break; + } + + if (!$error && $product_qty_remain > 0) { + if ($conf->global->STOCK_ALLOW_NEGATIVE_TRANSFER) { + // take in the first batch + $batch = $batchList[0]; + $result = $mouvP->livraison($user, $productStatic->id, $idwarehouse, $product_qty_remain, $this->lines[$i]->subprice, $langs->trans('InvoiceValidatedInDolibarr', $num), '', '', '', $batch->batch); + if ($result < 0) { + $error++; + $this->error = $mouvP->error; + } + } else { + $error++; + $langs->load('errors'); + $warehouseStatic->fetch($idwarehouse); + $this->error = $langs->trans('ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref); + dol_syslog(__METHOD__ . ' Error: ' . $langs->transnoentitiesnoconv('ErrorBatchNoFoundEnoughQuantityForProductInWarehouse', $productStatic->label, $warehouseStatic->ref), LOG_ERR); + } + } + } + } + } + + if (!$is_batch_line) { + $result = $mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceValidatedInDolibarr", $num)); + if ($result < 0) { + $error++; + $this->error = $mouvP->error; + } + } } } } @@ -4102,7 +4216,7 @@ class Facture extends CommonInvoice if ($generic_facture->hasDelay()) { $response->nbtodolate++; - $response->url_late=DOL_URL_ROOT.'/compta/facture/list.php?search_option=late&mainmenu=billing&leftmenu=customers_bills'; + $response->url_late = DOL_URL_ROOT.'/compta/facture/list.php?search_option=late&mainmenu=billing&leftmenu=customers_bills'; } } @@ -4578,15 +4692,40 @@ class Facture extends CommonInvoice // Paid invoices have status STATUS_CLOSED if ($this->statut != Facture::STATUS_VALIDATED) return false; - return $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay); + $hasDelay = $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay); + if ($hasDelay && !empty($this->retained_warranty) && !empty($this->retained_warranty_date_limit)) + { + $totalpaye = $this->getSommePaiement(); + $totalpaye = floatval($totalpaye); + $RetainedWarrantyAmount = $this->getRetainedWarrantyAmount(); + if ($totalpaye >= 0 && $RetainedWarrantyAmount >= 0) + { + if (($totalpaye < $this->total_ttc - $RetainedWarrantyAmount) && $this->date_lim_reglement < ($now - $conf->facture->client->warning_delay)) + { + $hasDelay = 1; + } + elseif ($totalpaye < $this->total_ttc && $this->retained_warranty_date_limit < ($now - $conf->facture->client->warning_delay)) + { + $hasDelay = 1; + } + else + { + $hasDelay = 0; + } + } + } + + return $hasDelay; } /** + * @param int $rounding Minimum number of decimal to show. If 0, no change, if -1, we use min($conf->global->MAIN_MAX_DECIMALS_UNIT,$conf->global->MAIN_MAX_DECIMALS_TOT) * @return number or -1 if not available */ - public function getRetainedWarrantyAmount() + public function getRetainedWarrantyAmount($rounding = -1) { + global $conf; if (empty($this->retained_warranty)) { return -1; } @@ -4630,6 +4769,11 @@ class Facture extends CommonInvoice $retainedWarrantyAmount = $this->total_ttc * $this->retained_warranty / 100; } + if ($rounding < 0) { + $rounding = min($conf->global->MAIN_MAX_DECIMALS_UNIT, $conf->global->MAIN_MAX_DECIMALS_TOT); + return round($retainedWarrantyAmount, 2); + } + return $retainedWarrantyAmount; } diff --git a/htdocs/compta/facture/class/facturestats.class.php b/htdocs/compta/facture/class/facturestats.class.php index f24f31bbc9a..730df6ee6e4 100644 --- a/htdocs/compta/facture/class/facturestats.class.php +++ b/htdocs/compta/facture/class/facturestats.class.php @@ -205,10 +205,11 @@ class FactureStats extends Stats /** * Return nb, amount of predefined product for year * - * @param int $year Year to scan - * @return array Array of values + * @param int $year Year to scan + * @param int $limit Limit + * @return array Array of values */ - public function getAllByProduct($year) + public function getAllByProduct($year, $limit = 10) { global $user; @@ -222,6 +223,6 @@ class FactureStats extends Stats $sql.= $this->db->order('nb', 'DESC'); //$sql.= $this->db->plimit(20); - return $this->_getAllByProduct($sql); + return $this->_getAllByProduct($sql, $limit); } } diff --git a/htdocs/compta/facture/invoicetemplate_list.php b/htdocs/compta/facture/invoicetemplate_list.php index 370bfe9a8b9..b55f0c412b9 100644 --- a/htdocs/compta/facture/invoicetemplate_list.php +++ b/htdocs/compta/facture/invoicetemplate_list.php @@ -33,10 +33,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; -if (!empty($conf->projet->enabled)) { - require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; - //require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php'; -} +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php'; @@ -54,6 +51,8 @@ $cancel = GETPOST('cancel', 'alpha'); $toselect = GETPOST('toselect', 'array'); $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'invoicetemplatelist'; // To manage different context of search +$socid = GETPOST('socid', 'int'); + // Security check $id = (GETPOST('facid', 'int') ?GETPOST('facid', 'int') : GETPOST('id', 'int')); $lineid = GETPOST('lineid', 'int'); @@ -62,7 +61,6 @@ if ($user->socid) $socid = $user->socid; $objecttype = 'facture_rec'; if ($action == "create" || $action == "add") $objecttype = ''; $result = restrictedArea($user, 'facture', $id, $objecttype); -$projectid = GETPOST('projectid', 'int'); $search_ref = GETPOST('search_ref'); $search_societe = GETPOST('search_societe'); @@ -146,6 +144,13 @@ if (is_array($extrafields->attributes[$object->table_element]['label']) && count $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); +if ($socid > 0) { + $tmpthirdparty = new Societe($db); + $res = $tmpthirdparty->fetch($socid); + if ($res > 0) $search_societe = $tmpthirdparty->name; +} + + /* * Actions @@ -218,6 +223,7 @@ $today = dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray[' /* * List mode */ + $sql = "SELECT s.nom as name, s.rowid as socid, f.rowid as facid, f.titre as title, f.total, f.tva as total_vat, f.total_ttc, f.frequency, f.unit_frequency,"; $sql .= " f.nb_gen_done, f.nb_gen_max, f.date_last_gen, f.date_when, f.suspended,"; $sql .= " f.datec, f.tms,"; @@ -243,6 +249,7 @@ if (!$user->rights->societe->client->voir && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; } if ($search_ref) $sql .= natural_search('f.titre', $search_ref); +if ($socid) $sql .= ' AND s.rowid = '.(int) $socid; if ($search_societe) $sql .= natural_search('s.nom', $search_societe); if ($search_montant_ht != '') $sql .= natural_search('f.total', $search_montant_ht, 1); if ($search_montant_vat != '') $sql .= natural_search('f.tva', $search_montant_vat, 1); @@ -286,7 +293,7 @@ if ($resql) $param = ''; if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage); if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit); - if ($socid) $param .= '&socid='.urlencode($socid); + if ($socid > 0) $param .= '&socid='.urlencode($socid); if ($search_day) $param .= '&search_day='.urlencode($search_day); if ($search_month) $param .= '&search_month='.urlencode($search_month); if ($search_year) $param .= '&search_year='.urlencode($search_year); @@ -299,12 +306,11 @@ if ($resql) if ($search_montant_vat != '') $param .= '&search_montant_vat='.urlencode($search_montant_vat); if ($search_montant_ttc != '') $param .= '&search_montant_ttc='.urlencode($search_montant_ttc); if ($search_payment_mode != '') $param .= '&search_payment_mode='.urlencode($search_payment_mode); - if ($search_payment_type != '') $param .= '&search_payment_type='.urlencode($search_payment_type); + if ($search_payment_term != '') $param .= '&search_payment_term='.urlencode($search_payment_term); if ($search_recurring != '' && $search_recurrning != '-1') $param .= '&search_recurring='.urlencode($search_recurring); if ($search_frequency > 0) $param .= '&search_frequency='.urlencode($search_frequency); if ($search_unit_frequency != '') $param .= '&search_unit_frequency='.urlencode($search_unit_frequency); if ($search_status != '') $param .= '&search_status='.urlencode($search_status); - if ($option) $param .= "&option=".urlencode($option); if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss); // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; @@ -326,12 +332,16 @@ if ($resql) print ''; print ''; - print_barre_liste($langs->trans("RepeatableInvoices"), $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'invoicing', 0, '', '', $limit); + $title = $langs->trans("RepeatableInvoices"); + + print_barre_liste($title, $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'invoicing', 0, '', '', $limit); print ''.$langs->trans("ToCreateAPredefinedInvoice", $langs->transnoentitiesnoconv("ChangeIntoRepeatableInvoice")).'

'; $i = 0; + $moreforfilter = ''; + print '
'; print ''."\n"; @@ -467,7 +477,6 @@ if ($resql) print ''; print "\n"; - print ''; if (!empty($arrayfields['f.titre']['checked'])) print_liste_field_titre($arrayfields['f.titre']['label'], $_SERVER['PHP_SELF'], "f.titre", "", $param, "", $sortfield, $sortorder); if (!empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER['PHP_SELF'], "s.nom", "", $param, "", $sortfield, $sortorder); @@ -527,21 +536,21 @@ if ($resql) } if (!empty($arrayfields['f.total']['checked'])) { - print ''."\n"; + print ''."\n"; if (!$i) $totalarray['nbfield']++; if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'f.total'; $totalarray['val']['f.total'] += $objp->total; } if (!empty($arrayfields['f.tva']['checked'])) { - print ''."\n"; + print ''."\n"; if (!$i) $totalarray['nbfield']++; if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'f.tva'; $totalarray['val']['f.tva'] += $objp->total_vat; } if (!empty($arrayfields['f.total_ttc']['checked'])) { - print ''."\n"; + print ''."\n"; if (!$i) $totalarray['nbfield']++; if (!$i) $totalarray['pos'][$totalarray['nbfield']] = 'f.total_ttc'; $totalarray['val']['f.total_ttc'] += $objp->total_ttc; diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 32cd30ea207..82f92085abf 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -87,6 +87,11 @@ $search_montant_vat = GETPOST('search_montant_vat', 'alpha'); $search_montant_localtax1 = GETPOST('search_montant_localtax1', 'alpha'); $search_montant_localtax2 = GETPOST('search_montant_localtax2', 'alpha'); $search_montant_ttc = GETPOST('search_montant_ttc', 'alpha'); +$search_multicurrency_code = GETPOST('search_multicurrency_code', 'alpha'); +$search_multicurrency_tx = GETPOST('search_multicurrency_tx', 'alpha'); +$search_multicurrency_montant_ht = GETPOST('search_multicurrency_montant_ht', 'alpha'); +$search_multicurrency_montant_vat = GETPOST('search_multicurrency_montant_vat', 'alpha'); +$search_multicurrency_montant_ttc = GETPOST('search_multicurrency_montant_ttc', 'alpha'); $search_status = GETPOST('search_status', 'intcomma'); $search_paymentmode = GETPOST('search_paymentmode', 'int'); $search_paymentterms = GETPOST('search_paymentterms', 'int'); @@ -183,6 +188,13 @@ $arrayfields = array( 'f.total_ttc'=>array('label'=>"AmountTTC", 'checked'=>0, 'position'=>130), 'dynamount_payed'=>array('label'=>"Received", 'checked'=>0, 'position'=>140), 'rtp'=>array('label'=>"Rest", 'checked'=>0, 'position'=>150), // Not enabled by default because slow + 'f.multicurrency_code'=>array('label'=>'Currency', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>160), + 'f.multicurrency_tx'=>array('label'=>'CurrencyRate', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>170), + 'f.multicurrency_total_ht'=>array('label'=>'MulticurrencyAmountHT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>180), + 'f.multicurrency_total_vat'=>array('label'=>'MulticurrencyAmountVAT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>190), + 'f.multicurrency_total_ttc'=>array('label'=>'MulticurrencyAmountTTC', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>200), + 'multicurrency_dynamount_payed'=>array('label'=>'MulticurrencyAlreadyPaid', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>210), + 'multicurrency_rtp'=>array('label'=>'MulticurrencyRemainderToPay', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>220), // Not enabled by default because slow 'f.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500), 'f.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500), 'f.fk_statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000), @@ -236,6 +248,11 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', $search_montant_localtax1 = ''; $search_montant_localtax2 = ''; $search_montant_ttc = ''; + $search_multicurrency_code = ''; + $search_multicurrency_tx = ''; + $search_multicurrency_montant_ht = ''; + $search_multicurrency_montant_vat = ''; + $search_multicurrency_montant_ttc = ''; $search_status = ''; $search_paymentmode = ''; $search_paymentterms = ''; @@ -383,6 +400,7 @@ $sql = 'SELECT'; if ($sall || $search_product_category > 0) $sql = 'SELECT DISTINCT'; $sql .= ' f.rowid as id, f.ref, f.ref_client, f.type, f.note_private, f.note_public, f.increment, f.fk_mode_reglement, f.fk_cond_reglement, f.total as total_ht, f.tva as total_vat, f.total_ttc,'; $sql .= ' f.localtax1 as total_localtax1, f.localtax2 as total_localtax2,'; +$sql .= ' f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva as multicurrency_total_vat, f.multicurrency_total_ttc,'; $sql .= ' f.datef as df, f.date_lim_reglement as datelimite, f.module_source, f.pos_source,'; $sql .= ' f.paye as paye, f.fk_statut, f.close_code,'; $sql .= ' f.datec as date_creation, f.tms as date_update, f.date_closing as date_closing,'; @@ -394,7 +412,7 @@ $sql .= " country.code as country_code,"; $sql .= " p.rowid as project_id, p.ref as project_ref, p.title as project_label"; // We need dynamount_payed to be able to sort on status (value is surely wrong because we can count several lines several times due to other left join or link with contacts. But what we need is just 0 or > 0) // TODO Better solution to be able to sort on already payed or remain to pay is to store amount_payed in a denormalized field. -if (!$sall) $sql .= ', SUM(pf.amount) as dynamount_payed'; +if (!$sall) $sql .= ', SUM(pf.amount) as dynamount_payed, SUM(pf.multicurrency_amount) as multicurrency_dynamount_payed'; if ($search_categ_cus) $sql .= ", cc.fk_categorie, cc.fk_soc"; // Add fields from extrafields if (!empty($extrafields->attributes[$object->table_element]['label'])) { @@ -459,6 +477,11 @@ if ($search_montant_vat != '') $sql .= natural_search('f.tva', $search_montant_v if ($search_montant_localtax1 != '') $sql .= natural_search('f.localtax1', $search_montant_localtax1, 1); if ($search_montant_localtax2 != '') $sql .= natural_search('f.localtax2', $search_montant_localtax2, 1); if ($search_montant_ttc != '') $sql .= natural_search('f.total_ttc', $search_montant_ttc, 1); +if ($search_multicurrency_code != '') $sql .= ' AND f.multicurrency_code = "' . $db->escape($search_multicurrency_code) . '"'; +if ($search_multicurrency_tx != '') $sql .= natural_search('f.multicurrency_tx', $search_multicurrency_tx, 1); +if ($search_multicurrency_montant_ht != '') $sql .= natural_search('f.multicurrency_total_ht', $search_multicurrency_montant_ht, 1); +if ($search_multicurrency_montant_vat != '') $sql .= natural_search('f.multicurrency_total_tva', $search_multicurrency_montant_vat, 1); +if ($search_multicurrency_montant_ttc != '') $sql .= natural_search('f.multicurrency_total_ttc', $search_multicurrency_montant_ttc, 1); if ($search_categ_cus > 0) $sql .= " AND cc.fk_categorie = ".$db->escape($search_categ_cus); if ($search_categ_cus == -2) $sql .= " AND cc.fk_categorie IS NULL"; if ($search_status != '-1' && $search_status != '') @@ -591,6 +614,11 @@ if ($resql) if ($search_montant_localtax1 != '') $param .= '&search_montant_localtax1='.urlencode($search_montant_localtax1); if ($search_montant_localtax2 != '') $param .= '&search_montant_localtax2='.urlencode($search_montant_localtax2); if ($search_montant_ttc != '') $param .= '&search_montant_ttc='.urlencode($search_montant_ttc); + if ($search_multicurrency_code != '') $param .= '&search_multicurrency_code='.urlencode($search_multicurrency_code); + if ($search_multicurrency_tx != '') $param .= '&search_multicurrency_tx='.urlencode($search_multicurrency_tx); + if ($search_multicurrency_montant_ht != '') $param .= '&search_multicurrency_montant_ht='.urlencode($search_multicurrency_montant_ht); + if ($search_multicurrency_montant_vat != '') $param .= '&search_multicurrency_montant_vat='.urlencode($search_multicurrency_montant_vat); + if ($search_multicurrency_montant_ttc != '') $param .= '&search_multicurrency_montant_ttc='.urlencode($search_multicurrency_montant_ttc); if ($search_status != '') $param .= '&search_status='.urlencode($search_status); if ($search_paymentmode > 0) $param .= '&search_paymentmode='.urlencode($search_paymentmode); if ($search_paymentterms > 0) $param .= '&search_paymentterms='.urlencode($search_paymentterms); @@ -878,13 +906,11 @@ if ($resql) print ''; print ''; } - if (!empty($arrayfields['f.retained_warranty']['checked'])) { print ''; } - if (!empty($arrayfields['dynamount_payed']['checked'])) { print ''; } + if (!empty($arrayfields['f.multicurrency_code']['checked'])) + { + // Currency + print ''; + } + if (!empty($arrayfields['f.multicurrency_tx']['checked'])) + { + // Currency rate + print ''; + } + if (!empty($arrayfields['f.multicurrency_total_ht']['checked'])) + { + // Amount + print ''; + } + if (!empty($arrayfields['f.multicurrency_total_vat']['checked'])) + { + // Amount + print ''; + } + if (!empty($arrayfields['f.multicurrency_total_ttc']['checked'])) + { + // Amount + print ''; + } + if (!empty($arrayfields['multicurrency_dynamount_payed']['checked'])) + { + print ''; + } + if (!empty($arrayfields['multicurrency_rtp']['checked'])) + { + print ''; + } if (!empty($arrayfields['f.date_closing']['checked'])) { print '\n"; print ''; - if (!empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($arrayfields['f.ref']['label'], $_SERVER['PHP_SELF'], 'f.ref', '', $param, '', $sortfield, $sortorder); - if (!empty($arrayfields['f.ref_client']['checked'])) print_liste_field_titre($arrayfields['f.ref_client']['label'], $_SERVER["PHP_SELF"], 'f.ref_client', '', $param, '', $sortfield, $sortorder); - if (!empty($arrayfields['f.type']['checked'])) print_liste_field_titre($arrayfields['f.type']['label'], $_SERVER["PHP_SELF"], 'f.type', '', $param, '', $sortfield, $sortorder); - if (!empty($arrayfields['f.date']['checked'])) print_liste_field_titre($arrayfields['f.date']['label'], $_SERVER['PHP_SELF'], 'f.datef', '', $param, 'align="center"', $sortfield, $sortorder); - if (!empty($arrayfields['f.date_lim_reglement']['checked'])) print_liste_field_titre($arrayfields['f.date_lim_reglement']['label'], $_SERVER['PHP_SELF'], "f.date_lim_reglement", '', $param, 'align="center"', $sortfield, $sortorder); - if (!empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER['PHP_SELF'], "p.ref", '', $param, '', $sortfield, $sortorder); - if (!empty($arrayfields['p.title']['checked'])) print_liste_field_titre($arrayfields['p.title']['label'], $_SERVER['PHP_SELF'], "p.title", '', $param, '', $sortfield, $sortorder); - if (!empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER['PHP_SELF'], 's.nom', '', $param, '', $sortfield, $sortorder); - if (!empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'], $_SERVER["PHP_SELF"], 's.town', '', $param, '', $sortfield, $sortorder); - if (!empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'], $_SERVER["PHP_SELF"], 's.zip', '', $param, '', $sortfield, $sortorder); - if (!empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($arrayfields['state.nom']['label'], $_SERVER["PHP_SELF"], "state.nom", "", $param, '', $sortfield, $sortorder); - if (!empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'], $_SERVER["PHP_SELF"], "country.code_iso", "", $param, 'align="center"', $sortfield, $sortorder); - if (!empty($arrayfields['typent.code']['checked'])) print_liste_field_titre($arrayfields['typent.code']['label'], $_SERVER["PHP_SELF"], "typent.code", "", $param, 'align="center"', $sortfield, $sortorder); - if (!empty($arrayfields['f.fk_mode_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_mode_reglement']['label'], $_SERVER["PHP_SELF"], "f.fk_mode_reglement", "", $param, "", $sortfield, $sortorder); - if (!empty($arrayfields['f.fk_cond_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_cond_reglement']['label'], $_SERVER["PHP_SELF"], "f.fk_cond_reglement", "", $param, "", $sortfield, $sortorder); - if (!empty($arrayfields['f.module_source']['checked'])) print_liste_field_titre($arrayfields['f.module_source']['label'], $_SERVER["PHP_SELF"], "f.module_source", "", $param, "", $sortfield, $sortorder); - if (!empty($arrayfields['f.pos_source']['checked'])) print_liste_field_titre($arrayfields['f.pos_source']['label'], $_SERVER["PHP_SELF"], "f.pos_source", "", $param, "", $sortfield, $sortorder); - if (!empty($arrayfields['f.total_ht']['checked'])) print_liste_field_titre($arrayfields['f.total_ht']['label'], $_SERVER['PHP_SELF'], 'f.total', '', $param, 'class="right"', $sortfield, $sortorder); - if (!empty($arrayfields['f.total_vat']['checked'])) print_liste_field_titre($arrayfields['f.total_vat']['label'], $_SERVER['PHP_SELF'], 'f.tva', '', $param, 'class="right"', $sortfield, $sortorder); - if (!empty($arrayfields['f.total_localtax1']['checked'])) print_liste_field_titre($arrayfields['f.total_localtax1']['label'], $_SERVER['PHP_SELF'], 'f.localtax1', '', $param, 'class="right"', $sortfield, $sortorder); - if (!empty($arrayfields['f.total_localtax2']['checked'])) print_liste_field_titre($arrayfields['f.total_localtax2']['label'], $_SERVER['PHP_SELF'], 'f.localtax2', '', $param, 'class="right"', $sortfield, $sortorder); - if (!empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'], $_SERVER['PHP_SELF'], 'f.total_ttc', '', $param, 'class="right"', $sortfield, $sortorder); - if (!empty($arrayfields['f.retained_warranty']['checked'])) print_liste_field_titre($arrayfields['f.retained_warranty']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'align="right"', $sortfield, $sortorder); - if (!empty($arrayfields['dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['dynamount_payed']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); - if (!empty($arrayfields['rtp']['checked'])) print_liste_field_titre($arrayfields['rtp']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($arrayfields['f.ref']['label'], $_SERVER['PHP_SELF'], 'f.ref', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['f.ref_client']['checked'])) print_liste_field_titre($arrayfields['f.ref_client']['label'], $_SERVER["PHP_SELF"], 'f.ref_client', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['f.type']['checked'])) print_liste_field_titre($arrayfields['f.type']['label'], $_SERVER["PHP_SELF"], 'f.type', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['f.date']['checked'])) print_liste_field_titre($arrayfields['f.date']['label'], $_SERVER['PHP_SELF'], 'f.datef', '', $param, 'align="center"', $sortfield, $sortorder); + if (!empty($arrayfields['f.date_lim_reglement']['checked'])) print_liste_field_titre($arrayfields['f.date_lim_reglement']['label'], $_SERVER['PHP_SELF'], "f.date_lim_reglement", '', $param, 'align="center"', $sortfield, $sortorder); + if (!empty($arrayfields['p.ref']['checked'])) print_liste_field_titre($arrayfields['p.ref']['label'], $_SERVER['PHP_SELF'], "p.ref", '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['p.title']['checked'])) print_liste_field_titre($arrayfields['p.title']['label'], $_SERVER['PHP_SELF'], "p.title", '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER['PHP_SELF'], 's.nom', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['s.town']['checked'])) print_liste_field_titre($arrayfields['s.town']['label'], $_SERVER["PHP_SELF"], 's.town', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['s.zip']['checked'])) print_liste_field_titre($arrayfields['s.zip']['label'], $_SERVER["PHP_SELF"], 's.zip', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['state.nom']['checked'])) print_liste_field_titre($arrayfields['state.nom']['label'], $_SERVER["PHP_SELF"], "state.nom", "", $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['country.code_iso']['checked'])) print_liste_field_titre($arrayfields['country.code_iso']['label'], $_SERVER["PHP_SELF"], "country.code_iso", "", $param, 'align="center"', $sortfield, $sortorder); + if (!empty($arrayfields['typent.code']['checked'])) print_liste_field_titre($arrayfields['typent.code']['label'], $_SERVER["PHP_SELF"], "typent.code", "", $param, 'align="center"', $sortfield, $sortorder); + if (!empty($arrayfields['f.fk_mode_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_mode_reglement']['label'], $_SERVER["PHP_SELF"], "f.fk_mode_reglement", "", $param, "", $sortfield, $sortorder); + if (!empty($arrayfields['f.fk_cond_reglement']['checked'])) print_liste_field_titre($arrayfields['f.fk_cond_reglement']['label'], $_SERVER["PHP_SELF"], "f.fk_cond_reglement", "", $param, "", $sortfield, $sortorder); + if (!empty($arrayfields['f.module_source']['checked'])) print_liste_field_titre($arrayfields['f.module_source']['label'], $_SERVER["PHP_SELF"], "f.module_source", "", $param, "", $sortfield, $sortorder); + if (!empty($arrayfields['f.pos_source']['checked'])) print_liste_field_titre($arrayfields['f.pos_source']['label'], $_SERVER["PHP_SELF"], "f.pos_source", "", $param, "", $sortfield, $sortorder); + if (!empty($arrayfields['f.total_ht']['checked'])) print_liste_field_titre($arrayfields['f.total_ht']['label'], $_SERVER['PHP_SELF'], 'f.total', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['f.total_vat']['checked'])) print_liste_field_titre($arrayfields['f.total_vat']['label'], $_SERVER['PHP_SELF'], 'f.tva', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['f.total_localtax1']['checked'])) print_liste_field_titre($arrayfields['f.total_localtax1']['label'], $_SERVER['PHP_SELF'], 'f.localtax1', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['f.total_localtax2']['checked'])) print_liste_field_titre($arrayfields['f.total_localtax2']['label'], $_SERVER['PHP_SELF'], 'f.localtax2', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'], $_SERVER['PHP_SELF'], 'f.total_ttc', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['f.retained_warranty']['checked'])) print_liste_field_titre($arrayfields['f.retained_warranty']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'align="right"', $sortfield, $sortorder); + if (!empty($arrayfields['dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['dynamount_payed']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['rtp']['checked'])) print_liste_field_titre($arrayfields['rtp']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['f.multicurrency_code']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_code']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_code', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['f.multicurrency_tx']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_tx']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_tx', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['f.multicurrency_total_ht']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_total_ht']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_total_ht', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['f.multicurrency_total_vat']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_total_vat']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_total_tva', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['f.multicurrency_total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_total_ttc']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_total_ttc', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['multicurrency_dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['multicurrency_dynamount_payed']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['multicurrency_rtp']['checked'])) print_liste_field_titre($arrayfields['multicurrency_rtp']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields @@ -989,10 +1067,16 @@ if ($resql) $facturestatic->id = $obj->id; $facturestatic->ref = $obj->ref; + $facturestatic->ref_client = $obj->ref_client; $facturestatic->type = $obj->type; $facturestatic->total_ht = $obj->total_ht; $facturestatic->total_tva = $obj->total_vat; $facturestatic->total_ttc = $obj->total_ttc; + $facturestatic->multicurrency_code = $obj->multicurrency_code; + $facturestatic->multicurrency_tx = $obj->multicurrency_tx; + $facturestatic->multicurrency_total_ht = $obj->multicurrency_total_ht; + $facturestatic->multicurrency_total_tva = $obj->multicurrency_total_vat; + $facturestatic->multicurrency_total_ttc = $obj->multicurrency_total_ttc; $facturestatic->statut = $obj->fk_statut; $facturestatic->close_code = $obj->close_code; $facturestatic->total_ttc = $obj->total_ttc; @@ -1030,16 +1114,27 @@ if ($resql) $totaldeposits = $facturestatic->getSumDepositsUsed(); $totalpay = $paiement + $totalcreditnotes + $totaldeposits; $remaintopay = price2num($facturestatic->total_ttc - $totalpay); + $multicurrency_paiement = $facturestatic->getSommePaiement(1); + $multicurrency_totalcreditnotes = $facturestatic->getSumCreditNotesUsed(1); + $multicurrency_totaldeposits = $facturestatic->getSumDepositsUsed(1); + $multicurrency_totalpay = $multicurrency_paiement + $multicurrency_totalcreditnotes + $multicurrency_totaldeposits; + $multicurrency_remaintopay = price2num($facturestatic->multicurrency_total_ttc - $multicurrency_totalpay); if ($facturestatic->statut == Facture::STATUS_CLOSED && $facturestatic->close_code == 'discount_vat') { // If invoice closed with discount for anticipated payment $remaintopay = 0; + $multicurrency_remaintopay = 0; } if ($facturestatic->type == Facture::TYPE_CREDIT_NOTE && $obj->paye == 1) { // If credit note closed, we take into account the amount not yet consummed - $remaincreditnote = $discount->getAvailableDiscounts($obj->fk_soc, '', 'rc.fk_facture_source='.$facturestatic->id); + $remaincreditnote = $discount->getAvailableDiscounts($thirdpartystatic, '', 'rc.fk_facture_source='.$facturestatic->id); $remaintopay = -$remaincreditnote; $totalpay = price2num($facturestatic->total_ttc - $remaintopay); + $multicurrency_remaincreditnote = $discount->getAvailableDiscounts($thirdpartystatic, '', 'rc.fk_facture_source='.$facturestatic->id, 0, 0, 1); + $multicurrency_remaintopay = -$multicurrency_remaincreditnote; + $multicurrency_totalpay = price2num($facturestatic->multicurrency_total_ttc - $multicurrency_remaintopay); } + $facturestatic->alreadypaid = $paiement; + print ''; + print ''; if (!$i) $totalarray['nbfield']++; @@ -1303,6 +1398,55 @@ if ($resql) $totalarray['val']['rtp'] += $remaintopay; } + + // Currency + if (!empty($arrayfields['f.multicurrency_code']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + + // Currency rate + if (!empty($arrayfields['f.multicurrency_tx']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount HT + if (!empty($arrayfields['f.multicurrency_total_ht']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount VAT + if (!empty($arrayfields['f.multicurrency_total_vat']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount TTC + if (!empty($arrayfields['f.multicurrency_total_ttc']['checked'])) + { + print '\n"; + if (!$i) $totalarray['nbfield']++; + } + if (!empty($arrayfields['multicurrency_dynamount_payed']['checked'])) + { + print ''; // TODO Use a denormalized field + if (!$i) $totalarray['nbfield']++; + } + + // Pending amount + if (!empty($arrayfields['multicurrency_rtp']['checked'])) + { + print ''; // TODO Use a denormalized field + if (!$i) $totalarray['nbfield']++; + } + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php index 447f5f47ecc..c9a77e5cc26 100644 --- a/htdocs/compta/index.php +++ b/htdocs/compta/index.php @@ -455,7 +455,7 @@ if (!empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture-> $sql = "SELECT ff.rowid, ff.ref, ff.fk_statut, ff.libelle, ff.total_ht, ff.total_tva, ff.total_ttc, ff.tms, ff.paye"; $sql .= ", s.nom as name"; $sql .= ", s.rowid as socid"; - $sql .= ", s.code_fournisseur, s.code_compta_fournisseur"; + $sql .= ", s.code_fournisseur, s.code_compta_fournisseur, s.email"; $sql .= ", SUM(pf.amount) as am"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as ff"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf on ff.rowid=pf.fk_facturefourn"; @@ -503,10 +503,14 @@ if (!empty($conf->fournisseur->enabled) && $user->rights->fournisseur->facture-> $thirdpartystatic->id = $obj->socid; $thirdpartystatic->name = $obj->name; + $thirdpartystatic->email = $obj->email; + $thirdpartystatic->country_id = 0; + $thirdpartystatic->country_code = ''; + $thirdpartystatic->client = 0; $thirdpartystatic->fournisseur = 1; - //$thirdpartystatic->code_client = $obj->code_client; + $thirdpartystatic->code_client = ''; $thirdpartystatic->code_fournisseur = $obj->code_fournisseur; - //$thirdpartystatic->code_compta = $obj->code_compta; + $thirdpartystatic->code_compta = ''; $thirdpartystatic->code_compta_fournisseur = $obj->code_compta_fournisseur; print ''; // Payment type (VIR, LIQ, ...) $labeltype = $langs->trans("PaymentType".$object->type_code) != ("PaymentType".$object->type_code) ? $langs->trans("PaymentType".$object->type_code) : $object->type_label; print ''; // Amount @@ -297,7 +297,7 @@ if (!empty($conf->banque->enabled)) print ''; print ''; print ''; print ''; } diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index 75dcb837df9..9b0ee645fc7 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -29,8 +29,8 @@ * \ingroup facture * \brief File of class to manage payments of customers invoices */ -require_once DOL_DOCUMENT_ROOT .'/core/class/commonobject.class.php'; -require_once DOL_DOCUMENT_ROOT .'/multicurrency/class/multicurrency.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php'; /** @@ -41,12 +41,12 @@ class Paiement extends CommonObject /** * @var string ID to identify managed object */ - public $element='payment'; + public $element = 'payment'; /** * @var string Name of table without prefix where object is stored */ - public $table_element='paiement'; + public $table_element = 'paiement'; /** * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png @@ -68,12 +68,12 @@ class Paiement extends CommonObject */ public $montant; - public $amount; // Total amount of payment - public $amounts=array(); // Array of amounts - public $multicurrency_amounts=array(); // Array of amounts + public $amount; // Total amount of payment + public $amounts = array(); // Array of amounts + public $multicurrency_amounts = array(); // Array of amounts public $author; - public $paiementid; // Type of payment. Id saved into fields fk_paiement on llx_paiement - public $paiementcode; // Code of payment. + public $paiementid; // Type of payment. Id saved into fields fk_paiement on llx_paiement + public $paiementcode; // Code of payment. /** * @var string type libelle @@ -136,7 +136,7 @@ class Paiement extends CommonObject /** * @var int payment id */ - public $fk_paiement; // Type of payment + public $fk_paiement; // Type of payment /** @@ -160,18 +160,18 @@ class Paiement extends CommonObject public function fetch($id, $ref = '', $fk_bank = '') { $sql = 'SELECT p.rowid, p.ref, p.datep as dp, p.amount, p.statut, p.ext_payment_id, p.ext_payment_site, p.fk_bank,'; - $sql.= ' c.code as type_code, c.libelle as type_label,'; - $sql.= ' p.num_paiement as num_payment, p.note,'; - $sql.= ' b.fk_account'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement as p LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; - $sql.= ' WHERE p.entity IN (' . getEntity('invoice').')'; + $sql .= ' c.code as type_code, c.libelle as type_label,'; + $sql .= ' p.num_paiement as num_payment, p.note,'; + $sql .= ' b.fk_account'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement as p LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id'; + $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; + $sql .= ' WHERE p.entity IN ('.getEntity('invoice').')'; if ($id > 0) - $sql.= ' AND p.rowid = '.$id; + $sql .= ' AND p.rowid = '.$id; elseif ($ref) - $sql.= " AND p.ref = '".$ref."'"; + $sql .= " AND p.ref = '".$ref."'"; elseif ($fk_bank) - $sql.= ' AND p.fk_bank = '.$fk_bank; + $sql .= ' AND p.fk_bank = '.$fk_bank; $resql = $this->db->query($sql); if ($resql) @@ -180,15 +180,15 @@ class Paiement extends CommonObject { $obj = $this->db->fetch_object($resql); $this->id = $obj->rowid; - $this->ref = $obj->ref?$obj->ref:$obj->rowid; + $this->ref = $obj->ref ? $obj->ref : $obj->rowid; $this->date = $this->db->jdate($obj->dp); $this->datepaye = $this->db->jdate($obj->dp); - $this->num_paiement = $obj->num_payment; // deprecated + $this->num_paiement = $obj->num_payment; // deprecated $this->num_payment = $obj->num_payment; - $this->montant = $obj->amount; // deprecated + $this->montant = $obj->amount; // deprecated $this->amount = $obj->amount; $this->note = $obj->note; - $this->type_label = $obj->type_label; + $this->type_label = $obj->type_label; $this->type_code = $obj->type_code; $this->statut = $obj->statut; $this->ext_payment_id = $obj->ext_payment_id; @@ -231,7 +231,7 @@ class Paiement extends CommonObject $error = 0; $way = $this->getWay(); - $now=dol_now(); + $now = dol_now(); // Clean parameters $totalamount = 0; @@ -258,7 +258,7 @@ class Paiement extends CommonObject $newvalue = price2num($value, 'MT'); $amounts[$key] = $newvalue; $totalamount += $newvalue; - if (! empty($newvalue)) $atleastonepaymentnotnull++; + if (!empty($newvalue)) $atleastonepaymentnotnull++; } $totalamount = price2num($totalamount); @@ -267,14 +267,16 @@ class Paiement extends CommonObject // Check parameters if (empty($totalamount) && empty($atleastonepaymentnotnull)) // We accept negative amounts for withdraw reject but not empty arrays { - $this->errors[]='TotalAmountEmpty'; - $this->error='TotalAmountEmpty'; + $this->errors[] = 'TotalAmountEmpty'; + $this->error = 'TotalAmountEmpty'; return -1; } - $this->db->begin(); + dol_syslog(get_class($this)."::create insert paiement", LOG_DEBUG); - $this->ref = $this->getNextNumRef(is_object($thirdparty)?$thirdparty:''); + $this->db->begin(); + + $this->ref = $this->getNextNumRef(is_object($thirdparty) ? $thirdparty : ''); if ($way == 'dolibarr') { @@ -287,13 +289,12 @@ class Paiement extends CommonObject $mtotal = $totalamount; } - $num_payment = ($this->num_payment?$this->num_payment:$this->num_paiement); - $note = ($this->note_public?$this->note_public:$this->note); + $num_payment = ($this->num_payment ? $this->num_payment : $this->num_paiement); + $note = ($this->note_public ? $this->note_public : $this->note); $sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement (entity, ref, datec, datep, amount, multicurrency_amount, fk_paiement, num_paiement, note, ext_payment_id, ext_payment_site, fk_user_creat)"; - $sql.= " VALUES (".$conf->entity.", '".$this->db->escape($this->ref)."', '". $this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', ".$total.", ".$mtotal.", ".$this->paiementid.", '".$this->db->escape($num_payment)."', '".$this->db->escape($note)."', ".($this->ext_payment_id?"'".$this->db->escape($this->ext_payment_id)."'":"null").", ".($this->ext_payment_site?"'".$this->db->escape($this->ext_payment_site)."'":"null").", ".$user->id.")"; + $sql .= " VALUES (".$conf->entity.", '".$this->db->escape($this->ref)."', '".$this->db->idate($now)."', '".$this->db->idate($this->datepaye)."', ".$total.", ".$mtotal.", ".$this->paiementid.", '".$this->db->escape($num_payment)."', '".$this->db->escape($note)."', ".($this->ext_payment_id ? "'".$this->db->escape($this->ext_payment_id)."'" : "null").", ".($this->ext_payment_site ? "'".$this->db->escape($this->ext_payment_site)."'" : "null").", ".$user->id.")"; - dol_syslog(get_class($this)."::Create insert paiement", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { @@ -307,23 +308,23 @@ class Paiement extends CommonObject { $amount = price2num($amount); $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'paiement_facture (fk_facture, fk_paiement, amount, multicurrency_amount)'; - $sql .= ' VALUES ('.$facid.', '. $this->id.', \''.$amount.'\', \''.$this->multicurrency_amounts[$key].'\')'; + $sql .= ' VALUES ('.$facid.', '.$this->id.', \''.$amount.'\', \''.$this->multicurrency_amounts[$key].'\')'; - dol_syslog(get_class($this).'::Create Amount line '.$key.' insert paiement_facture', LOG_DEBUG); - $resql=$this->db->query($sql); + dol_syslog(get_class($this).'::create Amount line '.$key.' insert paiement_facture', LOG_DEBUG); + $resql = $this->db->query($sql); if ($resql) { - $invoice=new Facture($this->db); + $invoice = new Facture($this->db); $invoice->fetch($facid); // If we want to closed payed invoices if ($closepaidinvoices) { $paiement = $invoice->getSommePaiement(); - $creditnotes=$invoice->getSumCreditNotesUsed(); - $deposits=$invoice->getSumDepositsUsed(); - $alreadypayed=price2num($paiement + $creditnotes + $deposits, 'MT'); - $remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits, 'MT'); + $creditnotes = $invoice->getSumCreditNotesUsed(); + $deposits = $invoice->getSumDepositsUsed(); + $alreadypayed = price2num($paiement + $creditnotes + $deposits, 'MT'); + $remaintopay = price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits, 'MT'); //var_dump($invoice->total_ttc.' - '.$paiement.' -'.$creditnotes.' - '.$deposits.' - '.$remaintopay);exit; @@ -394,12 +395,12 @@ class Paiement extends CommonObject } // Set invoice to paid - if (! $error) + if (!$error) { - $result=$invoice->set_paid($user, '', ''); - if ($result<0) + $result = $invoice->set_paid($user, '', ''); + if ($result < 0) { - $this->error=$invoice->error; + $this->error = $invoice->error; $error++; } } @@ -409,10 +410,15 @@ class Paiement extends CommonObject // Regenerate documents of invoices if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $newlang=''; + dol_syslog(get_class($this).'::create Regenerate the document after inserting payment for thirdparty default_lang='.(is_object($invoice->thirdparty) ? $invoice->thirdparty->default_lang : 'null'), LOG_DEBUG); + + $newlang = ''; $outputlangs = $langs; - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $invoice->thirdparty->default_lang; - if (! empty($newlang)) { + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) { + $invoice->fetch_thirdparty(); + $newlang = $invoice->thirdparty->default_lang; + } + if (!empty($newlang)) { $outputlangs = new Translate("", $conf); $outputlangs->setDefaultLang($newlang); } @@ -426,7 +432,7 @@ class Paiement extends CommonObject } else { - $this->error=$this->db->lasterror(); + $this->error = $this->db->lasterror(); $error++; } } @@ -436,25 +442,25 @@ class Paiement extends CommonObject } } - if (! $error) // All payments into $this->amounts were recorded without errors + if (!$error) // All payments into $this->amounts were recorded without errors { // Appel des triggers - $result=$this->call_trigger('PAYMENT_CUSTOMER_CREATE', $user); + $result = $this->call_trigger('PAYMENT_CUSTOMER_CREATE', $user); if ($result < 0) { $error++; } // Fin appel triggers } } else { - $this->error=$this->db->lasterror(); + $this->error = $this->db->lasterror(); $error++; } - if (! $error) + if (!$error) { - $this->amount=$total; - $this->total=$total; // deprecated - $this->multicurrency_amount=$mtotal; + $this->amount = $total; + $this->total = $total; // deprecated + $this->multicurrency_amount = $mtotal; $this->db->commit(); return $this->id; } @@ -478,7 +484,7 @@ class Paiement extends CommonObject { global $conf, $user, $langs; - $error=0; + $error = 0; $bank_line_id = $this->bank_line; @@ -486,12 +492,12 @@ class Paiement extends CommonObject // Verifier si paiement porte pas sur une facture classee // Si c'est le cas, on refuse la suppression - $billsarray=$this->getBillsArray('fk_statut > 1'); + $billsarray = $this->getBillsArray('fk_statut > 1'); if (is_array($billsarray)) { if (count($billsarray)) { - $this->error="ErrorDeletePaymentLinkedToAClosedInvoiceNotPossible"; + $this->error = "ErrorDeletePaymentLinkedToAClosedInvoiceNotPossible"; $this->db->rollback(); return -1; } @@ -507,32 +513,32 @@ class Paiement extends CommonObject { $accline = new AccountLine($this->db); - $result=$accline->fetch($bank_line_id); - if ($result == 0) $accline->rowid=$bank_line_id; // If not found, we set artificially rowid to allow delete of llx_bank_url + $result = $accline->fetch($bank_line_id); + if ($result == 0) $accline->rowid = $bank_line_id; // If not found, we set artificially rowid to allow delete of llx_bank_url // Delete bank account url lines linked to payment - $result=$accline->delete_urls($user); + $result = $accline->delete_urls($user); if ($result < 0) { - $this->error=$accline->error; + $this->error = $accline->error; $this->db->rollback(); return -3; } // Delete bank account lines linked to payment - $result=$accline->delete($user); + $result = $accline->delete($user); if ($result < 0) { - $this->error=$accline->error; + $this->error = $accline->error; $this->db->rollback(); return -4; } } - if (! $notrigger) + if (!$notrigger) { // Call triggers - $result=$this->call_trigger('PAYMENT_CUSTOMER_DELETE', $user); + $result = $this->call_trigger('PAYMENT_CUSTOMER_DELETE', $user); if ($result < 0) { $this->db->rollback(); @@ -543,18 +549,18 @@ class Paiement extends CommonObject // Delete payment (into paiement_facture and paiement) $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'paiement_facture'; - $sql.= ' WHERE fk_paiement = '.$this->id; + $sql .= ' WHERE fk_paiement = '.$this->id; dol_syslog($sql); $result = $this->db->query($sql); if ($result) { $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'paiement'; - $sql.= ' WHERE rowid = '.$this->id; + $sql .= ' WHERE rowid = '.$this->id; dol_syslog($sql); $result = $this->db->query($sql); - if (! $result) + if (!$result) { - $this->error=$this->db->lasterror(); + $this->error = $this->db->lasterror(); $this->db->rollback(); return -3; } @@ -564,7 +570,7 @@ class Paiement extends CommonObject } else { - $this->error=$this->db->error; + $this->error = $this->db->error; $this->db->rollback(); return -5; } @@ -586,46 +592,46 @@ class Paiement extends CommonObject */ public function addPaymentToBank($user, $mode, $label, $accountid, $emetteur_nom, $emetteur_banque, $notrigger = 0) { - global $conf,$langs,$user; + global $conf, $langs, $user; - $error=0; - $bank_line_id=0; + $error = 0; + $bank_line_id = 0; - if (! empty($conf->banque->enabled)) + if (!empty($conf->banque->enabled)) { if ($accountid <= 0) { - $this->error='Bad value for parameter accountid='.$accountid; + $this->error = 'Bad value for parameter accountid='.$accountid; dol_syslog(get_class($this).'::addPaymentToBank '.$this->error, LOG_ERR); return -1; } $this->db->begin(); - $this->fk_account=$accountid; + $this->fk_account = $accountid; include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; - dol_syslog("$user->id,$mode,$label,$this->fk_account,$emetteur_nom,$emetteur_banque"); + dol_syslog("$user->id, $mode, $label, $this->fk_account, $emetteur_nom, $emetteur_banque"); $acc = new Account($this->db); - $result=$acc->fetch($this->fk_account); + $result = $acc->fetch($this->fk_account); - $totalamount=$this->amount; - if (empty($totalamount)) $totalamount=$this->total; // For backward compatibility + $totalamount = $this->amount; + if (empty($totalamount)) $totalamount = $this->total; // For backward compatibility // if dolibarr currency != bank currency then we received an amount in customer currency (currently I don't manage the case : my currency is USD, the customer currency is EUR and he paid me in GBP. Seems no sense for me) - if (!empty($conf->multicurrency->enabled) && $conf->currency != $acc->currency_code) $totalamount=$this->multicurrency_amount; + if (!empty($conf->multicurrency->enabled) && $conf->currency != $acc->currency_code) $totalamount = $this->multicurrency_amount; - if ($mode == 'payment_supplier') $totalamount=-$totalamount; + if ($mode == 'payment_supplier') $totalamount = -$totalamount; // Insert payment into llx_bank $bank_line_id = $acc->addline( $this->datepaye, - $this->paiementid, // Payment mode id or code ("CHQ or VIR for example") + $this->paiementid, // Payment mode id or code ("CHQ or VIR for example") $label, - $totalamount, // Sign must be positive when we receive money (customer payment), negative when you give money (supplier invoice or credit note) - $this->num_paiement, + $totalamount, // Sign must be positive when we receive money (customer payment), negative when you give money (supplier invoice or credit note) + $this->num_payment, '', $user, $emetteur_nom, @@ -636,7 +642,7 @@ class Paiement extends CommonObject // On connait ainsi le paiement qui a genere l'ecriture bancaire if ($bank_line_id > 0) { - $result=$this->update_fk_bank($bank_line_id); + $result = $this->update_fk_bank($bank_line_id); if ($result <= 0) { $error++; @@ -644,14 +650,14 @@ class Paiement extends CommonObject } // Add link 'payment', 'payment_supplier' in bank_url between payment and bank transaction - if ( ! $error) + if (!$error) { - $url=''; - if ($mode == 'payment') $url=DOL_URL_ROOT.'/compta/paiement/card.php?id='; - if ($mode == 'payment_supplier') $url=DOL_URL_ROOT.'/fourn/paiement/card.php?id='; + $url = ''; + if ($mode == 'payment') $url = DOL_URL_ROOT.'/compta/paiement/card.php?id='; + if ($mode == 'payment_supplier') $url = DOL_URL_ROOT.'/fourn/paiement/card.php?id='; if ($url) { - $result=$acc->add_url_line($bank_line_id, $this->id, $url, '(paiement)', $mode); + $result = $acc->add_url_line($bank_line_id, $this->id, $url, '(paiement)', $mode); if ($result <= 0) { $error++; @@ -662,9 +668,9 @@ class Paiement extends CommonObject // Add link 'company' in bank_url between invoice and bank transaction (for each invoice concerned by payment) //if (! $error && $label != '(WithdrawalPayment)') - if (! $error) + if (!$error) { - $linkaddedforthirdparty=array(); + $linkaddedforthirdparty = array(); foreach ($this->amounts as $key => $value) // We should have invoices always for same third party but we loop in case of. { if ($mode == 'payment') @@ -672,9 +678,9 @@ class Paiement extends CommonObject $fac = new Facture($this->db); $fac->fetch($key); $fac->fetch_thirdparty(); - if (! in_array($fac->thirdparty->id, $linkaddedforthirdparty)) // Not yet done for this thirdparty + if (!in_array($fac->thirdparty->id, $linkaddedforthirdparty)) // Not yet done for this thirdparty { - $result=$acc->add_url_line( + $result = $acc->add_url_line( $bank_line_id, $fac->thirdparty->id, DOL_URL_ROOT.'/comm/card.php?socid=', @@ -682,7 +688,7 @@ class Paiement extends CommonObject 'company' ); if ($result <= 0) dol_syslog(get_class($this).'::addPaymentToBank '.$this->db->lasterror()); - $linkaddedforthirdparty[$fac->thirdparty->id]=$fac->thirdparty->id; // Mark as done for this thirdparty + $linkaddedforthirdparty[$fac->thirdparty->id] = $fac->thirdparty->id; // Mark as done for this thirdparty } } if ($mode == 'payment_supplier') @@ -690,9 +696,9 @@ class Paiement extends CommonObject $fac = new FactureFournisseur($this->db); $fac->fetch($key); $fac->fetch_thirdparty(); - if (! in_array($fac->thirdparty->id, $linkaddedforthirdparty)) // Not yet done for this thirdparty + if (!in_array($fac->thirdparty->id, $linkaddedforthirdparty)) // Not yet done for this thirdparty { - $result=$acc->add_url_line( + $result = $acc->add_url_line( $bank_line_id, $fac->thirdparty->id, DOL_URL_ROOT.'/fourn/card.php?socid=', @@ -700,15 +706,15 @@ class Paiement extends CommonObject 'company' ); if ($result <= 0) dol_syslog(get_class($this).'::addPaymentToBank '.$this->db->lasterror()); - $linkaddedforthirdparty[$fac->thirdparty->id]=$fac->thirdparty->id; // Mark as done for this thirdparty + $linkaddedforthirdparty[$fac->thirdparty->id] = $fac->thirdparty->id; // Mark as done for this thirdparty } } } } // Add link 'WithdrawalPayment' in bank_url - if (! $error && $label == '(WithdrawalPayment)') { - $result=$acc->add_url_line( + if (!$error && $label == '(WithdrawalPayment)') { + $result = $acc->add_url_line( $bank_line_id, $this->id_prelevement, DOL_URL_ROOT.'/compta/prelevement/card.php?id=', @@ -717,21 +723,21 @@ class Paiement extends CommonObject ); } - if (! $error && ! $notrigger) + if (!$error && !$notrigger) { // Appel des triggers - $result=$this->call_trigger('PAYMENT_ADD_TO_BANK', $user); + $result = $this->call_trigger('PAYMENT_ADD_TO_BANK', $user); if ($result < 0) { $error++; } // Fin appel triggers } } else { - $this->error=$acc->error; + $this->error = $acc->error; $error++; } - if (! $error) + if (!$error) { $this->db->commit(); } @@ -741,7 +747,7 @@ class Paiement extends CommonObject } } - if (! $error) + if (!$error) { return $bank_line_id; } @@ -763,7 +769,7 @@ class Paiement extends CommonObject { // phpcs:enable $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' set fk_bank = '.$id_bank; - $sql.= ' WHERE rowid = '.$this->id; + $sql .= ' WHERE rowid = '.$this->id; dol_syslog(get_class($this).'::update_fk_bank', LOG_DEBUG); $result = $this->db->query($sql); @@ -773,7 +779,7 @@ class Paiement extends CommonObject } else { - $this->error=$this->db->lasterror(); + $this->error = $this->db->lasterror(); dol_syslog(get_class($this).'::update_fk_bank '.$this->error); return -1; } @@ -789,7 +795,7 @@ class Paiement extends CommonObject public function update_date($date) { // phpcs:enable - $error=0; + $error = 0; if (!empty($date) && $this->statut != 1) { @@ -798,35 +804,35 @@ class Paiement extends CommonObject dol_syslog(get_class($this)."::update_date with date = ".$date, LOG_DEBUG); $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET datep = '".$this->db->idate($date)."'"; - $sql.= " WHERE rowid = ".$this->id; + $sql .= " SET datep = '".$this->db->idate($date)."'"; + $sql .= " WHERE rowid = ".$this->id; $result = $this->db->query($sql); - if (! $result) + if (!$result) { $error++; - $this->error='Error -1 '.$this->db->error(); + $this->error = 'Error -1 '.$this->db->error(); } $type = $this->element; $sql = "UPDATE ".MAIN_DB_PREFIX.'bank'; - $sql.= " SET dateo = '".$this->db->idate($date)."', datev = '".$this->db->idate($date)."'"; - $sql.= " WHERE rowid IN (SELECT fk_bank FROM ".MAIN_DB_PREFIX."bank_url WHERE type = '".$type."' AND url_id = ".$this->id.")"; - $sql.= " AND rappro = 0"; + $sql .= " SET dateo = '".$this->db->idate($date)."', datev = '".$this->db->idate($date)."'"; + $sql .= " WHERE rowid IN (SELECT fk_bank FROM ".MAIN_DB_PREFIX."bank_url WHERE type = '".$type."' AND url_id = ".$this->id.")"; + $sql .= " AND rappro = 0"; $result = $this->db->query($sql); - if (! $result) + if (!$result) { $error++; - $this->error='Error -1 '.$this->db->error(); + $this->error = 'Error -1 '.$this->db->error(); } - if (! $error) + if (!$error) { } - if (! $error) + if (!$error) { $this->datepaye = $date; $this->date = $date; @@ -853,10 +859,10 @@ class Paiement extends CommonObject public function update_num($num) { // phpcs:enable - if(!empty($num) && $this->statut!=1) { + if (!empty($num) && $this->statut != 1) { $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET num_paiement = '".$this->db->escape($num)."'"; - $sql.= " WHERE rowid = ".$this->id; + $sql .= " SET num_paiement = '".$this->db->escape($num)."'"; + $sql .= " WHERE rowid = ".$this->id; dol_syslog(get_class($this)."::update_num", LOG_DEBUG); $result = $this->db->query($sql); @@ -867,7 +873,7 @@ class Paiement extends CommonObject } else { - $this->error='Error -1 '.$this->db->error(); + $this->error = 'Error -1 '.$this->db->error(); return -2; } } @@ -892,7 +898,7 @@ class Paiement extends CommonObject } else { - $this->error=$this->db->lasterror(); + $this->error = $this->db->lasterror(); dol_syslog(get_class($this).'::valide '.$this->error); return -1; } @@ -916,7 +922,7 @@ class Paiement extends CommonObject } else { - $this->error=$this->db->lasterror(); + $this->error = $this->db->lasterror(); dol_syslog(get_class($this).'::reject '.$this->error); return -1; } @@ -931,8 +937,8 @@ class Paiement extends CommonObject public function info($id) { $sql = 'SELECT p.rowid, p.datec, p.fk_user_creat, p.fk_user_modif, p.tms'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement as p'; - $sql.= ' WHERE p.rowid = '.$id; + $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement as p'; + $sql .= ' WHERE p.rowid = '.$id; dol_syslog(get_class($this).'::info', LOG_DEBUG); $result = $this->db->query($sql); @@ -947,7 +953,7 @@ class Paiement extends CommonObject { $cuser = new User($this->db); $cuser->fetch($obj->fk_user_creat); - $this->user_creation = $cuser; + $this->user_creation = $cuser; } if ($obj->fk_user_modif) { @@ -975,20 +981,20 @@ class Paiement extends CommonObject public function getBillsArray($filter = '') { $sql = 'SELECT pf.fk_facture'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'facture as f'; // We keep link on invoice to allow use of some filters on invoice - $sql.= ' WHERE pf.fk_facture = f.rowid AND pf.fk_paiement = '.$this->id; - if ($filter) $sql.= ' AND '.$filter; + $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf, '.MAIN_DB_PREFIX.'facture as f'; // We keep link on invoice to allow use of some filters on invoice + $sql .= ' WHERE pf.fk_facture = f.rowid AND pf.fk_paiement = '.$this->id; + if ($filter) $sql .= ' AND '.$filter; $resql = $this->db->query($sql); if ($resql) { - $i=0; - $num=$this->db->num_rows($resql); - $billsarray=array(); + $i = 0; + $num = $this->db->num_rows($resql); + $billsarray = array(); while ($i < $num) { $obj = $this->db->fetch_object($resql); - $billsarray[$i]=$obj->fk_facture; + $billsarray[$i] = $obj->fk_facture; $i++; } @@ -996,7 +1002,7 @@ class Paiement extends CommonObject } else { - $this->error=$this->db->error(); + $this->error = $this->db->error(); dol_syslog(get_class($this).'::getBillsArray Error '.$this->error.' -', LOG_DEBUG); return -1; } @@ -1010,19 +1016,19 @@ class Paiement extends CommonObject public function getAmountsArray() { $sql = 'SELECT pf.fk_facture, pf.amount'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf'; - $sql.= ' WHERE pf.fk_paiement = '.$this->id; + $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf'; + $sql .= ' WHERE pf.fk_paiement = '.$this->id; $resql = $this->db->query($sql); if ($resql) { - $i=0; - $num=$this->db->num_rows($resql); + $i = 0; + $num = $this->db->num_rows($resql); $amounts = array(); while ($i < $num) { $obj = $this->db->fetch_object($resql); - $amounts[$obj->fk_facture]=$obj->amount; + $amounts[$obj->fk_facture] = $obj->amount; $i++; } @@ -1030,7 +1036,7 @@ class Paiement extends CommonObject } else { - $this->error=$this->db->error(); + $this->error = $this->db->error(); dol_syslog(get_class($this).'::getAmountsArray Error '.$this->error.' -', LOG_DEBUG); return -1; } @@ -1050,13 +1056,13 @@ class Paiement extends CommonObject $langs->load("bills"); // Clean parameters (if not defined or using deprecated value) - if (empty($conf->global->PAYMENT_ADDON)) $conf->global->PAYMENT_ADDON='mod_payment_cicada'; - elseif ($conf->global->PAYMENT_ADDON=='ant') $conf->global->PAYMENT_ADDON='mod_payment_ant'; - elseif ($conf->global->PAYMENT_ADDON=='cicada') $conf->global->PAYMENT_ADDON='mod_payment_cicada'; + if (empty($conf->global->PAYMENT_ADDON)) $conf->global->PAYMENT_ADDON = 'mod_payment_cicada'; + elseif ($conf->global->PAYMENT_ADDON == 'ant') $conf->global->PAYMENT_ADDON = 'mod_payment_ant'; + elseif ($conf->global->PAYMENT_ADDON == 'cicada') $conf->global->PAYMENT_ADDON = 'mod_payment_cicada'; - if (! empty($conf->global->PAYMENT_ADDON)) + if (!empty($conf->global->PAYMENT_ADDON)) { - $mybool=false; + $mybool = false; $file = $conf->global->PAYMENT_ADDON.".php"; $classname = $conf->global->PAYMENT_ADDON; @@ -1070,12 +1076,12 @@ class Paiement extends CommonObject // Load file with numbering class (if found) if (is_file($dir.$file) && is_readable($dir.$file)) { - $mybool |= include_once $dir . $file; + $mybool |= include_once $dir.$file; } } // For compatibility - if (! $mybool) + if (!$mybool) { $file = $conf->global->PAYMENT_ADDON.".php"; $classname = "mod_payment_".$conf->global->PAYMENT_ADDON; @@ -1087,12 +1093,12 @@ class Paiement extends CommonObject // Load file with numbering class (if found) if (is_file($dir.$file) && is_readable($dir.$file)) { - $mybool |= include_once $dir . $file; + $mybool |= include_once $dir.$file; } } } - if (! $mybool) + if (!$mybool) { dol_print_error('', "Failed to include file ".$file); return ''; @@ -1156,16 +1162,16 @@ class Paiement extends CommonObject */ public function initAsSpecimen($option = '') { - global $user,$langs,$conf; + global $user, $langs, $conf; - $now=dol_now(); - $arraynow=dol_getdate($now); - $nownotime=dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']); + $now = dol_now(); + $arraynow = dol_getdate($now); + $nownotime = dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']); // Initialize parameters - $this->id=0; + $this->id = 0; $this->ref = 'SPECIMEN'; - $this->specimen=1; + $this->specimen = 1; $this->facid = 1; $this->datepaye = $nownotime; } @@ -1184,49 +1190,49 @@ class Paiement extends CommonObject { global $conf, $langs; - if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips + if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips - $result=''; + $result = ''; $label = ''.$langs->trans("ShowPayment").'
'; - $label.= ''.$langs->trans("Ref").': '.$this->ref; - if ($this->datepaye ? $this->datepaye : $this->date) $label.= '
'.$langs->trans("Date").': '.dol_print_date($this->datepaye ? $this->datepaye : $this->date, 'dayhour'); + $label .= ''.$langs->trans("Ref").': '.$this->ref; + if ($this->datepaye ? $this->datepaye : $this->date) $label .= '
'.$langs->trans("Date").': '.dol_print_date($this->datepaye ? $this->datepaye : $this->date, 'dayhour'); if ($mode == 'withlistofinvoices') { $arraybill = $this->getBillsArray(); if (is_array($arraybill) && count($arraybill) > 0) { include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; - $facturestatic=new Facture($this->db); + $facturestatic = new Facture($this->db); foreach ($arraybill as $billid) { $facturestatic->fetch($billid); - $label .='
'.$facturestatic->getNomUrl(1).' '.$facturestatic->getLibStatut(2, 1); + $label .= '
'.$facturestatic->getNomUrl(1).' '.$facturestatic->getLibStatut(2, 1); } } } - $linkclose=''; + $linkclose = ''; if (empty($notooltip)) { - if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { - $label=$langs->trans("ShowMyObject"); - $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"'; + $label = $langs->trans("ShowMyObject"); + $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } - $linkclose.=' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose.=' class="classfortooltip'.($morecss?' '.$morecss:'').'"'; + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; } - else $linkclose = ($morecss?' class="'.$morecss.'"':''); + else $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); $url = DOL_URL_ROOT.'/compta/paiement/card.php?id='.$this->id; $linkstart = ''; - $linkend=''; + $linkstart .= $linkclose.'>'; + $linkend = ''; $result .= $linkstart; - if ($withpicto) $result.=img_object(($notooltip?'':$label), ($this->picto?$this->picto:'generic'), ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1); - if ($withpicto && $withpicto != 2) $result.= ($this->ref?$this->ref:$this->id); + if ($withpicto) $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + if ($withpicto && $withpicto != 2) $result .= ($this->ref ? $this->ref : $this->id); $result .= $linkend; return $result; @@ -1254,7 +1260,7 @@ class Paiement extends CommonObject public function LibStatut($status, $mode = 0) { // phpcs:enable - global $langs; // TODO Renvoyer le libelle anglais et faire traduction a affichage + global $langs; // TODO Renvoyer le libelle anglais et faire traduction a affichage $langs->load('compta'); /*if ($mode == 0) @@ -1305,7 +1311,7 @@ class Paiement extends CommonObject public function fetch_thirdparty($force_thirdparty_id = 0) { // phpcs:enable - include_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; + include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; if (empty($force_thirdparty_id)) { diff --git a/htdocs/compta/resultat/clientfourn.php b/htdocs/compta/resultat/clientfourn.php index ee76a29d282..93afa054f71 100644 --- a/htdocs/compta/resultat/clientfourn.php +++ b/htdocs/compta/resultat/clientfourn.php @@ -67,8 +67,7 @@ if (!$sortorder) $sortorder = 'ASC'; // Date range $year = GETPOST('year', 'int'); -if (empty($year)) -{ +if (empty($year)) { $year_current = strftime("%Y", dol_now()); $month_current = strftime("%m", dol_now()); $year_start = $year_current; @@ -114,7 +113,7 @@ $tmps = dol_getdate($date_start); $year_start = $tmps['year']; $tmpe = dol_getdate($date_end); $year_end = $tmpe['year']; -$nbofyear = ($year_end - $start_year) + 1; +$nbofyear = ($year_end - $year_start) + 1; //var_dump("year_start=".$year_start." year_end=".$year_end." nbofyear=".$nbofyear." date_start=".dol_print_date($date_start, 'dayhour')." date_end=".dol_print_date($date_end, 'dayhour')); // Define modecompta ('CREANCES-DETTES' or 'RECETTES-DEPENSES' or 'BOOKKEEPING') @@ -193,17 +192,21 @@ if (!empty($conf->accounting->enabled) && $modecompta != 'BOOKKEEPING') } // Show report array -$param = '&modecompta='.$modecompta; +$param = '&modecompta='.urlencode($modecompta).'&showaccountdetail='.urlencode($showaccountdetail); if ($date_startday) $param .= '&date_startday='.$date_startday; if ($date_startmonth) $param .= '&date_startmonth='.$date_startmonth; if ($date_startyear) $param .= '&date_startyear='.$date_startyear; if ($date_endday) $param .= '&date_endday='.$date_endday; if ($date_endmonth) $param .= '&date_endmonth='.$date_endmonth; -if ($date_endyear) $param .= '&date_endyear='.$date_startyear; +if ($date_endyear) $param .= '&date_endyear='.$date_endyear; print '
'.price($objp->total).''.price($objp->total).''.price($objp->total_vat).''.price($objp->total_vat).''.price($objp->total_ttc).''.price($objp->total_ttc).''; print ''; @@ -895,6 +921,51 @@ if ($resql) print ''; print ''; + print $form->selectMultiCurrency($search_multicurrency_code, 'search_multicurrency_code', 1); + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; @@ -936,31 +1007,38 @@ if ($resql) print "
'; print $obj->ref_client; print ''.$obj->multicurrency_code . ' - ' . $langs->trans('Currency' . $obj->multicurrency_code)."'; + $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $obj->rowid, $obj->multicurrency_tx, 'none', $obj->multicurrency_code); + print "'.price($obj->multicurrency_total_ht)."'.price($obj->multicurrency_total_vat)."'.price($obj->multicurrency_total_ttc)."'.(!empty($multicurrency_totalpay) ?price($multicurrency_totalpay, 0, $langs) : ' ').''; + print (!empty($multicurrency_remaintopay) ? price($multicurrency_remaintopay, 0, $langs) : ' '); + print '
'; diff --git a/htdocs/compta/paiement.php b/htdocs/compta/paiement.php index fb2a3edfd9c..3853847c363 100644 --- a/htdocs/compta/paiement.php +++ b/htdocs/compta/paiement.php @@ -97,6 +97,8 @@ if (empty($reshook)) $totalpayment = 0; $multicurrency_totalpayment = 0; $atleastonepaymentnotnull = 0; + $formquestion = array(); + $i = 0; // Generate payment array and check if there is payment higher than invoice and payment date before invoice date $tmpinvoice = new Facture($db); @@ -216,7 +218,7 @@ if (empty($reshook)) { $error = 0; - $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); + $datepaye = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); $db->begin(); @@ -262,8 +264,10 @@ if (empty($reshook)) $paiement->amounts = $amounts; // Array with all payments dispatching with invoice id $paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching $paiement->paiementid = dol_getIdFromCode($db, GETPOST('paiementcode'), 'c_paiement', 'code', 'id', 1); - $paiement->num_paiement = GETPOST('num_paiement', 'alpha'); - $paiement->note = GETPOST('comment', 'alpha'); + $paiement->num_payment = GETPOST('num_paiement', 'alpha'); + $paiement->note_private = GETPOST('comment', 'alpha'); + $paiement->num_paiement = $paiement->num_payment; // For bacward compatibility + $paiement->note = $paiement->note_private; // For bacward compatibility if (!$error) { diff --git a/htdocs/compta/paiement/card.php b/htdocs/compta/paiement/card.php index edc76de0698..887fe2ec570 100644 --- a/htdocs/compta/paiement/card.php +++ b/htdocs/compta/paiement/card.php @@ -222,7 +222,7 @@ print '
'.$langs->trans('PaymentMode').''.$labeltype; -print $object->num_paiement ? ' - '.$object->num_paiement : ''; +print $object->num_payment? ' - '.$object->num_payment : ''; print '
'.$langs->trans('BankTransactionLine').''; - print $bankline->getNomUrl(1, 0, 'showconciliated'); + print $bankline->getNomUrl(1, 0, 'showconciliatedandaccounted'); print '
'; print ''; -print_liste_field_titre("PredefinedGroups", $_SERVER["PHP_SELF"], 'f.thirdparty_code,f.rowid', '', $param, '', $sortfield, $sortorder, 'width200 '); +if ($modecompta == 'BOOKKEEPING') { + print_liste_field_titre("PredefinedGroups", $_SERVER["PHP_SELF"], 'f.thirdparty_code,f.rowid', '', $param, '', $sortfield, $sortorder, 'width200 '); +} else { + print_liste_field_titre("", $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'width200 '); +} print_liste_field_titre(''); if ($modecompta == 'BOOKKEEPING') { @@ -243,7 +246,7 @@ if ($modecompta == 'BOOKKEEPING') $sql .= " AND f.entity = ".$conf->entity; if (!empty($date_start) && !empty($date_end)) $sql .= " AND f.doc_date >= '".$db->idate($date_start)."' AND f.doc_date <= '".$db->idate($date_end)."'"; - $sql .= " GROUP BY pcg_type, pcg_subtype, name, socid"; + $sql .= " GROUP BY pcg_type, name, socid"; $sql .= $db->order($sortfield, $sortorder); $oldpcgtype = ''; diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php index c5e142ca7ca..69ad435c64c 100644 --- a/htdocs/compta/sociales/card.php +++ b/htdocs/compta/sociales/card.php @@ -47,6 +47,11 @@ $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm'); $projectid = (GETPOST('projectid') ? GETPOST('projectid', 'int') : 0); +$dateech = dol_mktime(GETPOST('echhour'), GETPOST('echmin'), GETPOST('echsec'), GETPOST('echmonth'), GETPOST('echday'), GETPOST('echyear')); +$dateperiod = dol_mktime(GETPOST('periodhour'), GETPOST('periodmin'), GETPOST('periodsec'), GETPOST('periodmonth'), GETPOST('periodday'), GETPOST('periodyear')); +$label = GETPOST('label', 'alpha'); +$actioncode = GETPOST('actioncode'); + // Security check $socid = GETPOST('socid', 'int'); if ($user->socid) $socid = $user->socid; @@ -134,10 +139,7 @@ if ($action == 'confirm_delete' && $confirm == 'yes') // Add social contribution if ($action == 'add' && $user->rights->tax->charges->creer) { - $dateech = dol_mktime(GETPOST('echhour'), GETPOST('echmin'), GETPOST('echsec'), GETPOST('echmonth'), GETPOST('echday'), GETPOST('echyear')); - $dateperiod = dol_mktime(GETPOST('periodhour'), GETPOST('periodmin'), GETPOST('periodsec'), GETPOST('periodmonth'), GETPOST('periodday'), GETPOST('periodyear')); $amount = price2num(GETPOST('amount')); - $actioncode = GETPOST('actioncode'); if (!$dateech) { @@ -187,8 +189,6 @@ if ($action == 'add' && $user->rights->tax->charges->creer) if ($action == 'update' && !$_POST["cancel"] && $user->rights->tax->charges->creer) { - $dateech = dol_mktime(GETPOST('echhour'), GETPOST('echmin'), GETPOST('echsec'), GETPOST('echmonth'), GETPOST('echday'), GETPOST('echyear')); - $dateperiod = dol_mktime(GETPOST('periodhour'), GETPOST('periodmin'), GETPOST('periodsec'), GETPOST('periodmonth'), GETPOST('periodday'), GETPOST('periodyear')); $amount = price2num(GETPOST('amount')); if (!$dateech) diff --git a/htdocs/compta/sociales/class/paymentsocialcontribution.class.php b/htdocs/compta/sociales/class/paymentsocialcontribution.class.php index a5279ecbeae..629a73578b2 100644 --- a/htdocs/compta/sociales/class/paymentsocialcontribution.class.php +++ b/htdocs/compta/sociales/class/paymentsocialcontribution.class.php @@ -57,7 +57,7 @@ class PaymentSocialContribution extends CommonObject /** * @deprecated - * @see amount + * @see $amount */ public $total; diff --git a/htdocs/compta/sociales/list.php b/htdocs/compta/sociales/list.php index d259fb362fd..54cfcfc37cd 100644 --- a/htdocs/compta/sociales/list.php +++ b/htdocs/compta/sociales/list.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2016 Frédéric France + * Copyright (C) 2020 Pierre Ardoin * * 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 @@ -29,6 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php' require_once DOL_DOCUMENT_ROOT.'/core/class/html.formsocialcontrib.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +if (!empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; // Load translation files required by the page $langs->loadLangs(array('compta', 'banks', 'bills')); @@ -52,6 +54,8 @@ $search_status = GETPOST('search_status', 'int'); $search_day_lim = GETPOST('search_day_lim', 'int'); $search_month_lim = GETPOST('search_month_lim', 'int'); $search_year_lim = GETPOST('search_year_lim', 'int'); +$search_project_ref = GETPOST('search_project_ref', 'alpha'); +$search_project = GETPOST('search_project', 'alpha'); $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); @@ -88,11 +92,13 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_label = ""; $search_amount = ""; $search_status = ''; - $search_typeid = ""; + $search_typeid = ""; $year = ""; $search_day_lim = ''; $search_year_lim = ''; $search_month_lim = ''; + $search_project_ref = ''; + $search_project = ''; $toselect = ''; $search_array_options = array(); } @@ -106,21 +112,25 @@ $form = new Form($db); $formother = new FormOther($db); $formsocialcontrib = new FormSocialContrib($db); $chargesociale_static = new ChargeSociales($db); +if (!empty($conf->projet->enabled)) $projectstatic = new Project($db); llxHeader('', $langs->trans("SocialContributions")); $sql = "SELECT cs.rowid as id, cs.fk_type as type, "; $sql .= " cs.amount, cs.date_ech, cs.libelle as label, cs.paye, cs.periode,"; +if (!empty($conf->projet->enabled)) $sql .= " p.rowid as project_id, p.ref as project_ref, p.title as project_label,"; $sql .= " c.libelle as type_label,"; $sql .= " SUM(pc.amount) as alreadypayed"; $sql .= " FROM ".MAIN_DB_PREFIX."c_chargesociales as c,"; $sql .= " ".MAIN_DB_PREFIX."chargesociales as cs"; +if (!empty($conf->projet->enabled)) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet as p ON p.rowid = cs.fk_projet"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiementcharge as pc ON pc.fk_charge = cs.rowid"; $sql .= " WHERE cs.fk_type = c.id"; $sql .= " AND cs.entity = ".$conf->entity; // Search criteria if ($search_ref) $sql .= " AND cs.rowid=".$db->escape($search_ref); if ($search_label) $sql .= natural_search("cs.libelle", $search_label); +if (!empty($conf->projet->enabled)) if ($search_project_ref != '') $sql .= natural_search("p.ref", $search_project_ref); if ($search_amount) $sql .= natural_search("cs.amount", $search_amount, 1); if ($search_status != '' && $search_status >= 0) $sql .= " AND cs.paye = ".$db->escape($search_status); $sql .= dolSqlDateFilter("cs.periode", $search_day_lim, $search_month_lim, $search_year_lim); @@ -163,6 +173,7 @@ if ($resql) if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit); if ($search_ref) $param .= '&search_ref='.urlencode($search_ref); if ($search_label) $param .= '&search_label='.urlencode($search_label); + if ($search_project_ref >= 0) $param .= "&search_project_ref=".urlencode($search_project_ref); if ($search_amount) $param .= '&search_amount='.urlencode($search_amount); if ($search_typeid) $param .= '&search_typeid='.urlencode($search_typeid); if ($search_status != '' && $search_status != '-1') $param .= '&search_status='.urlencode($search_status); @@ -217,6 +228,8 @@ if ($resql) print ''; + // Ref Project + if (!empty($conf->projet->enabled)) print ''; // Date print ''; // Period end date @@ -245,6 +258,7 @@ if ($resql) print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "id", "", $param, "", $sortfield, $sortorder); print_liste_field_titre("Label", $_SERVER["PHP_SELF"], "cs.libelle", "", $param, 'class="left"', $sortfield, $sortorder); print_liste_field_titre("Type", $_SERVER["PHP_SELF"], "type", "", $param, 'class="left"', $sortfield, $sortorder); + if (!empty($conf->projet->enabled)) print_liste_field_titre('ProjectRef', $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "cs.date_ech", "", $param, 'align="center"', $sortfield, $sortorder); print_liste_field_titre("PeriodEndDate", $_SERVER["PHP_SELF"], "periode", "", $param, 'align="center"', $sortfield, $sortorder); print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "cs.amount", "", $param, 'class="right"', $sortfield, $sortorder); @@ -262,6 +276,11 @@ if ($resql) $chargesociale_static->ref = $obj->id; $chargesociale_static->label = $obj->label; $chargesociale_static->type_label = $obj->type_label; + if (!empty($conf->projet->enabled)) { + $projectstatic->id = $obj->project_id; + $projectstatic->ref = $obj->project_ref; + $projectstatic->title = $obj->project_label; + } print ''; @@ -277,6 +296,17 @@ if ($resql) print "\n"; if (!$i) $totalarray['nbfield']++; + // Project Ref + if (!empty($conf->projet->enabled)) { + print ''; + if (!$i) $totalarray['nbfield']++; + } + // Date print ''; if (!$i) $totalarray['nbfield']++; diff --git a/htdocs/compta/stats/cabyprodserv.php b/htdocs/compta/stats/cabyprodserv.php index 138bff4a525..a1bdfb6678d 100644 --- a/htdocs/compta/stats/cabyprodserv.php +++ b/htdocs/compta/stats/cabyprodserv.php @@ -31,23 +31,23 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; // Load translation files required by the page -$langs->loadLangs(array("products","categories","errors",'accountancy')); +$langs->loadLangs(array("products", "categories", "errors", 'accountancy')); // Security pack (data & check) $socid = GETPOST('socid', 'int'); if ($user->socid > 0) $socid = $user->socid; -if (! empty($conf->comptabilite->enabled)) $result=restrictedArea($user, 'compta', '', '', 'resultat'); -if (! empty($conf->accounting->enabled)) $result=restrictedArea($user, 'accounting', '', '', 'comptarapport'); +if (!empty($conf->comptabilite->enabled)) $result = restrictedArea($user, 'compta', '', '', 'resultat'); +if (!empty($conf->accounting->enabled)) $result = restrictedArea($user, 'accounting', '', '', 'comptarapport'); // Define modecompta ('CREANCES-DETTES' or 'RECETTES-DEPENSES') $modecompta = $conf->global->ACCOUNTING_MODE; -if (GETPOST("modecompta")) $modecompta=GETPOST("modecompta"); +if (GETPOST("modecompta")) $modecompta = GETPOST("modecompta"); -$sortorder=isset($_GET["sortorder"])?$_GET["sortorder"]:$_POST["sortorder"]; -$sortfield=isset($_GET["sortfield"])?$_GET["sortfield"]:$_POST["sortfield"]; -if (! $sortorder) $sortorder="asc"; -if (! $sortfield) $sortfield="ref"; +$sortorder = isset($_GET["sortorder"]) ? $_GET["sortorder"] : $_POST["sortorder"]; +$sortfield = isset($_GET["sortfield"]) ? $_GET["sortfield"] : $_POST["sortfield"]; +if (!$sortorder) $sortorder = "asc"; +if (!$sortfield) $sortfield = "ref"; // Category $selected_cat = (int) GETPOST('search_categ', 'int'); @@ -58,11 +58,11 @@ if (GETPOST('subcat', 'alpha') === 'yes') { } // product/service $selected_type = GETPOST('search_type', 'int'); -if ($selected_type =='') $selected_type = -1; +if ($selected_type == '') $selected_type = -1; // Date range -$year=GETPOST("year"); -$month=GETPOST("month"); +$year = GETPOST("year"); +$month = GETPOST("month"); $date_startyear = GETPOST("date_startyear"); $date_startmonth = GETPOST("date_startmonth"); $date_startday = GETPOST("date_startday"); @@ -79,76 +79,78 @@ if (empty($year)) $month_current = strftime("%m", dol_now()); $year_start = $year; } -$date_start=dol_mktime(0, 0, 0, GETPOST("date_startmonth"), GETPOST("date_startday"), GETPOST("date_startyear")); -$date_end=dol_mktime(23, 59, 59, GETPOST("date_endmonth"), GETPOST("date_endday"), GETPOST("date_endyear")); +$date_start = dol_mktime(0, 0, 0, GETPOST("date_startmonth"), GETPOST("date_startday"), GETPOST("date_startyear")); +$date_end = dol_mktime(23, 59, 59, GETPOST("date_endmonth"), GETPOST("date_endday"), GETPOST("date_endyear")); // Quarter if (empty($date_start) || empty($date_end)) // We define date_start and date_end { - $q=GETPOST("q", "int"); + $q = GETPOST("q", "int"); if (empty($q)) { // We define date_start and date_end - $month_start=GETPOST("month")?GETPOST("month"):($conf->global->SOCIETE_FISCAL_MONTH_START?($conf->global->SOCIETE_FISCAL_MONTH_START):1); - $year_end=$year_start; - $month_end=$month_start; - if (! GETPOST("month")) // If month not forced + $month_start = GETPOST("month") ?GETPOST("month") : ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1); + $year_end = $year_start; + $month_end = $month_start; + if (!GETPOST("month")) // If month not forced { - if (! GETPOST('year') && $month_start > $month_current) + if (!GETPOST('year') && $month_start > $month_current) { $year_start--; $year_end--; } - $month_end=$month_start-1; - if ($month_end < 1) $month_end=12; + $month_end = $month_start - 1; + if ($month_end < 1) $month_end = 12; else $year_end++; } - $date_start=dol_get_first_day($year_start, $month_start, false); $date_end=dol_get_last_day($year_end, $month_end, false); + $date_start = dol_get_first_day($year_start, $month_start, false); $date_end = dol_get_last_day($year_end, $month_end, false); } else { - if ($q==1) { $date_start=dol_get_first_day($year_start, 1, false); $date_end=dol_get_last_day($year_start, 3, false); } - if ($q==2) { $date_start=dol_get_first_day($year_start, 4, false); $date_end=dol_get_last_day($year_start, 6, false); } - if ($q==3) { $date_start=dol_get_first_day($year_start, 7, false); $date_end=dol_get_last_day($year_start, 9, false); } - if ($q==4) { $date_start=dol_get_first_day($year_start, 10, false); $date_end=dol_get_last_day($year_start, 12, false); } + if ($q == 1) { $date_start = dol_get_first_day($year_start, 1, false); $date_end = dol_get_last_day($year_start, 3, false); } + if ($q == 2) { $date_start = dol_get_first_day($year_start, 4, false); $date_end = dol_get_last_day($year_start, 6, false); } + if ($q == 3) { $date_start = dol_get_first_day($year_start, 7, false); $date_end = dol_get_last_day($year_start, 9, false); } + if ($q == 4) { $date_start = dol_get_first_day($year_start, 10, false); $date_end = dol_get_last_day($year_start, 12, false); } } } else { // TODO We define q } // $date_start and $date_end are defined. We force $year_start and $nbofyear -$tmps=dol_getdate($date_start); +$tmps = dol_getdate($date_start); $year_start = $tmps['year']; -$tmpe=dol_getdate($date_end); +$tmpe = dol_getdate($date_end); $year_end = $tmpe['year']; $nbofyear = ($year_end - $year_start) + 1; -$commonparams=array(); -$commonparams['modecompta']=$modecompta; -$commonparams['sortorder'] = $sortorder; -$commonparams['sortfield'] = $sortfield; +$commonparams = array(); +if (!empty($modecompta)) $commonparams['modecompta'] = $modecompta; +if (!empty($sortorder)) $commonparams['sortorder'] = $sortorder; +if (!empty($sortfield)) $commonparams['sortfield'] = $sortfield; $headerparams = array(); -$headerparams['date_startyear'] = $date_startyear; -$headerparams['date_startmonth'] = $date_startmonth; -$headerparams['date_startday'] = $date_startday; -$headerparams['date_endyear'] = $date_endyear; -$headerparams['date_endmonth'] = $date_endmonth; -$headerparams['date_endday'] = $date_endday; +if (!empty($date_startyear)) $headerparams['date_startyear'] = $date_startyear; +if (!empty($date_startmonth)) $headerparams['date_startmonth'] = $date_startmonth; +if (!empty($date_startday)) $headerparams['date_startday'] = $date_startday; +if (!empty($date_endyear)) $headerparams['date_endyear'] = $date_endyear; +if (!empty($date_endmonth)) $headerparams['date_endmonth'] = $date_endmonth; +if (!empty($date_endday)) $headerparams['date_endday'] = $date_endday; +if (!empty($year)) $headerparams['year'] = $year; +if (!empty($month)) $headerparams['month'] = $month; $headerparams['q'] = $q; $tableparams = array(); -$tableparams['search_categ'] = $selected_cat; -$tableparams['search_soc'] = $selected_soc; -$tableparams['search_type'] = $selected_type; -$tableparams['subcat'] = ($subcat === true)?'yes':''; +if (!empty($selected_cat)) $tableparams['search_categ'] = $selected_cat; +if (!empty($selected_soc)) $tableparams['search_soc'] = $selected_soc; +if (!empty($selected_type)) $tableparams['search_type'] = $selected_type; +$tableparams['subcat'] = ($subcat === true) ? 'yes' : ''; // Adding common parameters $allparams = array_merge($commonparams, $headerparams, $tableparams); $headerparams = array_merge($commonparams, $headerparams); $tableparams = array_merge($commonparams, $tableparams); -foreach($allparams as $key => $value) { - $paramslink .= '&' . $key . '=' . $value; +foreach ($allparams as $key => $value) { + $paramslink .= '&'.$key.'='.$value; } @@ -158,127 +160,127 @@ foreach($allparams as $key => $value) { llxHeader(); -$form=new Form($db); +$form = new Form($db); $formother = new FormOther($db); // TODO Report from bookkeeping not yet available, so we switch on report on business events -if ($modecompta=="BOOKKEEPING") $modecompta="CREANCES-DETTES"; -if ($modecompta=="BOOKKEEPINGCOLLECTED") $modecompta="RECETTES-DEPENSES"; +if ($modecompta == "BOOKKEEPING") $modecompta = "CREANCES-DETTES"; +if ($modecompta == "BOOKKEEPINGCOLLECTED") $modecompta = "RECETTES-DEPENSES"; // Show report header -if ($modecompta=="CREANCES-DETTES") { - $name=$langs->trans("Turnover").', '.$langs->trans("ByProductsAndServices"); - $calcmode=$langs->trans("CalcModeDebt"); +if ($modecompta == "CREANCES-DETTES") { + $name = $langs->trans("Turnover").', '.$langs->trans("ByProductsAndServices"); + $calcmode = $langs->trans("CalcModeDebt"); //$calcmode.='
('.$langs->trans("SeeReportInInputOutputMode",'','').')'; - $description=$langs->trans("RulesCADue"); - if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { - $description.= $langs->trans("DepositsAreNotIncluded"); + $description = $langs->trans("RulesCADue"); + if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $description .= $langs->trans("DepositsAreNotIncluded"); } else { - $description.= $langs->trans("DepositsAreIncluded"); + $description .= $langs->trans("DepositsAreIncluded"); } - $builddate=dol_now(); + $builddate = dol_now(); } -elseif ($modecompta=="RECETTES-DEPENSES") +elseif ($modecompta == "RECETTES-DEPENSES") { - $name=$langs->trans("TurnoverCollected").', '.$langs->trans("ByProductsAndServices"); - $calcmode=$langs->trans("CalcModeEngagement"); + $name = $langs->trans("TurnoverCollected").', '.$langs->trans("ByProductsAndServices"); + $calcmode = $langs->trans("CalcModeEngagement"); //$calcmode.='
('.$langs->trans("SeeReportInDueDebtMode",'','').')'; - $description=$langs->trans("RulesCAIn"); - $description.= $langs->trans("DepositsAreIncluded"); + $description = $langs->trans("RulesCAIn"); + $description .= $langs->trans("DepositsAreIncluded"); - $builddate=dol_now(); + $builddate = dol_now(); } -elseif ($modecompta=="BOOKKEEPING") +elseif ($modecompta == "BOOKKEEPING") { } -elseif ($modecompta=="BOOKKEEPINGCOLLECTED") +elseif ($modecompta == "BOOKKEEPINGCOLLECTED") { } -$period=$form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0); -if ($date_end == dol_time_plus_duree($date_start, 1, 'y') - 1) $periodlink=''.img_previous().''.img_next().''; +$period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0); +if ($date_end == dol_time_plus_duree($date_start, 1, 'y') - 1) $periodlink = ''.img_previous().''.img_next().''; else $periodlink = ''; report_header($name, $namelink, $period, $periodlink, $description, $builddate, $exportlink, $tableparams, $calcmode); -if (! empty($conf->accounting->enabled) && $modecompta != 'BOOKKEEPING') +if (!empty($conf->accounting->enabled) && $modecompta != 'BOOKKEEPING') { print info_admin($langs->trans("WarningReportNotReliable"), 0, 0, 1); } -$name=array(); +$name = array(); // SQL request -$catotal=0; -$catotal_ht=0; -$qtytotal=0; +$catotal = 0; +$catotal_ht = 0; +$qtytotal = 0; if ($modecompta == 'CREANCES-DETTES') { $sql = "SELECT DISTINCT p.rowid as rowid, p.ref as ref, p.label as label, p.fk_product_type as product_type,"; - $sql.= " SUM(l.total_ht) as amount, SUM(l.total_ttc) as amount_ttc,"; - $sql.= " SUM(CASE WHEN f.type = 2 THEN -l.qty ELSE l.qty END) as qty"; - $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; - if($selected_soc > 0) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as soc ON (soc.rowid = f.fk_soc)"; - $sql.= ",".MAIN_DB_PREFIX."facturedet as l"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON l.fk_product = p.rowid"; + $sql .= " SUM(l.total_ht) as amount, SUM(l.total_ttc) as amount_ttc,"; + $sql .= " SUM(CASE WHEN f.type = 2 THEN -l.qty ELSE l.qty END) as qty"; + $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; + if ($selected_soc > 0) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as soc ON (soc.rowid = f.fk_soc)"; + $sql .= ",".MAIN_DB_PREFIX."facturedet as l"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON l.fk_product = p.rowid"; if ($selected_cat === -2) // Without any category { - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product"; } elseif ($selected_cat) // Into a specific category { - $sql.= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_product as cp"; + $sql .= ", ".MAIN_DB_PREFIX."categorie as c, ".MAIN_DB_PREFIX."categorie_product as cp"; } - $sql.= " WHERE l.fk_facture = f.rowid"; - $sql.= " AND f.fk_statut in (1,2)"; - if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { - $sql.= " AND f.type IN (0,1,2,5)"; + $sql .= " WHERE l.fk_facture = f.rowid"; + $sql .= " AND f.fk_statut in (1,2)"; + if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $sql .= " AND f.type IN (0,1,2,5)"; } else { - $sql.= " AND f.type IN (0,1,2,3,5)"; + $sql .= " AND f.type IN (0,1,2,3,5)"; } if ($date_start && $date_end) { - $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; + $sql .= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'"; } - if ($selected_type >=0) + if ($selected_type >= 0) { - $sql.= " AND l.product_type = ".$selected_type; + $sql .= " AND l.product_type = ".$selected_type; } if ($selected_cat === -2) // Without any category { - $sql.=" AND cp.fk_product is null"; + $sql .= " AND cp.fk_product is null"; } elseif ($selected_cat) { // Into a specific category - $sql.= " AND (c.rowid = ".$selected_cat; - if ($subcat) $sql.=" OR c.fk_parent = " . $selected_cat; - $sql.= ")"; - $sql.= " AND cp.fk_categorie = c.rowid AND cp.fk_product = p.rowid"; + $sql .= " AND (c.rowid = ".$selected_cat; + if ($subcat) $sql .= " OR c.fk_parent = ".$selected_cat; + $sql .= ")"; + $sql .= " AND cp.fk_categorie = c.rowid AND cp.fk_product = p.rowid"; } - if($selected_soc > 0) $sql .= " AND soc.rowid=".$selected_soc; - $sql.= " AND f.entity IN (".getEntity('invoice').")"; - $sql.= " GROUP BY p.rowid, p.ref, p.label, p.fk_product_type"; - $sql.= $db->order($sortfield, $sortorder); + if ($selected_soc > 0) $sql .= " AND soc.rowid=".$selected_soc; + $sql .= " AND f.entity IN (".getEntity('invoice').")"; + $sql .= " GROUP BY p.rowid, p.ref, p.label, p.fk_product_type"; + $sql .= $db->order($sortfield, $sortorder); dol_syslog("cabyprodserv", LOG_DEBUG); $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); - $i=0; + $i = 0; while ($i < $num) { $obj = $db->fetch_object($result); $amount_ht[$obj->rowid] = $obj->amount; $amount[$obj->rowid] = $obj->amount_ttc; $qty[$obj->rowid] = $obj->qty; - $name[$obj->rowid] = $obj->ref . ' - ' . $obj->label; + $name[$obj->rowid] = $obj->ref.' - '.$obj->label; $type[$obj->rowid] = $obj->product_type; - $catotal_ht+=$obj->amount; - $catotal+=$obj->amount_ttc; - $qtytotal+=$obj->qty; + $catotal_ht += $obj->amount; + $catotal += $obj->amount_ttc; + $qtytotal += $obj->qty; $i++; } } else { @@ -286,25 +288,25 @@ if ($modecompta == 'CREANCES-DETTES') } // Show Array - $i=0; + $i = 0; print ''; // Extra parameters management - foreach($headerparams as $key => $value) + foreach ($headerparams as $key => $value) { print ''; } - $moreforfilter=''; + $moreforfilter = ''; print '
'; - print '
'; $formsocialcontrib->select_type_socialcontrib($search_typeid, 'search_typeid', 1, 0, 0, 'maxwidth100onsmartphone'); print ' 
".$obj->type_label."'; + if ($obj->project_id > 0) + { + print $projectstatic->getNomUrl(1); + } + print ''.dol_print_date($db->jdate($obj->date_ech), 'day').'
'."\n"; + print '
'."\n"; // Category filter print ''; print ''; print '\n"; if (count($name)) { - foreach($name as $key=>$value) { + foreach ($name as $key=>$value) { print ''; // Product print "\n"; @@ -463,7 +465,7 @@ if ($modecompta == 'CREANCES-DETTES') // "Calculation of part of each product for accountancy in this mode is not possible. When a partial payment (for example 5 euros) is done on an // invoice with 2 product (product A for 10 euros and product B for 20 euros), what is part of paiment for product A and part of paiment for product B ? // Because there is no way to know this, this report is not relevant. - print '
'.$langs->trans("TurnoverPerProductInCommitmentAccountingNotRelevant") . '
'; + print '
'.$langs->trans("TurnoverPerProductInCommitmentAccountingNotRelevant").'
'; } // End of page diff --git a/htdocs/compta/stats/index.php b/htdocs/compta/stats/index.php index 684ef337fcd..9be5607b62d 100644 --- a/htdocs/compta/stats/index.php +++ b/htdocs/compta/stats/index.php @@ -407,7 +407,7 @@ for ($mois = 1 + $nb_mois_decalage; $mois <= 12 + $nb_mois_decalage; $mois++) print ""; for ($annee = $year_start ; $annee <= $year_end ; $annee++) { - $casenow = dol_print_date(mktime(),"%Y-%m"); + $casenow = dol_print_date(dol_now(),"%Y-%m"); $case = dol_print_date(dol_mktime(1,1,1,$mois,1,$annee),"%Y-%m"); $caseprev = dol_print_date(dol_mktime(1,1,1,$mois,1,$annee-1),"%Y-%m"); diff --git a/htdocs/compta/tva/card.php b/htdocs/compta/tva/card.php index 174da6b5869..86fb598fb8b 100644 --- a/htdocs/compta/tva/card.php +++ b/htdocs/compta/tva/card.php @@ -38,6 +38,10 @@ $action=GETPOST("action", "alpha"); $refund=GETPOST("refund", "int"); if (empty($refund)) $refund=0; +$datev=dol_mktime(12, 0, 0, GETPOST("datevmonth", 'int'), GETPOST("datevday", 'int'), GETPOST("datevyear", 'int')); +$datep=dol_mktime(12, 0, 0, GETPOST("datepmonth", 'int'), GETPOST("datepday", 'int'), GETPOST("datepyear", 'int')); + + // Security check $socid = GETPOST('socid', 'int'); if ($user->socid) $socid=$user->socid; @@ -70,7 +74,7 @@ if ($action == 'setlib' && $user->rights->tax->charges->creer) if ($action == 'setdatev' && $user->rights->tax->charges->creer) { $object->fetch($id); - $object->datev=dol_mktime(12, 0, 0, GETPOST('datevmonth', 'int'), GETPOST('datevday', 'int'), GETPOST('datevyear', 'int')); + $object->datev = $datev; $result=$object->update($user); if ($result < 0) dol_print_error($db, $object->error); @@ -81,14 +85,12 @@ if ($action == 'add' && $_POST["cancel"] <> $langs->trans("Cancel")) { $error=0; - $datev=dol_mktime(12, 0, 0, $_POST["datevmonth"], $_POST["datevday"], $_POST["datevyear"]); - $datep=dol_mktime(12, 0, 0, $_POST["datepmonth"], $_POST["datepday"], $_POST["datepyear"]); + $object->accountid = GETPOST("accountid", 'int'); + $object->type_payment = GETPOST("type_payment", 'alphanohtml'); + $object->num_payment = GETPOST("num_payment", 'alphanohtml'); - $object->accountid=GETPOST("accountid"); - $object->type_payment=GETPOST("type_payment"); - $object->num_payment=GETPOST("num_payment"); - $object->datev=$datev; - $object->datep=$datep; + $object->datev = $datev; + $object->datep = $datep; $amount = price2num(GETPOST("amount", 'alpha')); if ($refund == 1) { @@ -277,7 +279,7 @@ if ($action == 'create') if (! empty($conf->banque->enabled)) { print ''; } diff --git a/htdocs/compta/tva/document.php b/htdocs/compta/tva/document.php index 7f860491a8d..2f15044f808 100644 --- a/htdocs/compta/tva/document.php +++ b/htdocs/compta/tva/document.php @@ -70,8 +70,8 @@ if (!$sortfield) $sortfield = "name"; $object = new Tva($db); if ($id > 0) $object->fetch($id); -$upload_dir = $conf->tax->dir_output.'/'.dol_sanitizeFileName($object->ref); -$modulepart = 'tax'; +$upload_dir = $conf->tax->dir_output.'/vat/'.dol_sanitizeFileName($object->ref); +$modulepart = 'tax-vat'; /* @@ -144,7 +144,6 @@ if ($object->id) dol_fiche_end(); - $modulepart = 'tax'; $permission = $user->rights->tax->charges->creer; $permtoedit = $user->rights->fournisseur->facture->creer; $param = '&id='.$object->id; diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index f1491d73bf4..73862b65b2e 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -218,6 +218,8 @@ if (empty($reshook)) $object->priv = GETPOST("priv", 'int'); $object->note_public = GETPOST("note_public", 'none'); $object->note_private = GETPOST("note_private", 'none'); + $object->roles = GETPOST("roles", 'array'); + $object->statut = 1; //Defult status to Actif // Note: Correct date should be completed with location to have exact GM time of birth. @@ -552,6 +554,8 @@ else setEventMessages($object->error, $object->errors, 'errors'); } + $object->fetchRoles(); + // Show tabs $head = contact_prepare_head($object); @@ -578,7 +582,7 @@ else $object->country = $tmparray['label']; } - $title = $addcontact = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("AddContact") : $langs->trans("AddContactAddress")); + $title = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("AddContact") : $langs->trans("AddContactAddress")); $linkback = ''; print load_fiche_titre($title, $linkback, 'address'); @@ -652,7 +656,7 @@ else // Civility print ''; print ''; @@ -681,13 +685,13 @@ else if (($objsoc->typent_code == 'TE_PRIVATE' || !empty($conf->global->CONTACT_USE_COMPANY_ADDRESS)) && dol_strlen(trim($object->zip)) == 0) $object->zip = $objsoc->zip; // Predefined with third party if (($objsoc->typent_code == 'TE_PRIVATE' || !empty($conf->global->CONTACT_USE_COMPANY_ADDRESS)) && dol_strlen(trim($object->town)) == 0) $object->town = $objsoc->town; // Predefined with third party print ''; // Country print ''; @@ -705,7 +709,7 @@ else if ($object->country_id) { - print $formcompany->select_state(GETPOST("state_id", 'alpha') ?GETPOST("state_id", 'alpha') : $object->state_id, $object->country_code, 'state_id'); + print $formcompany->select_state(GETPOST("state_id", 'alpha') ? GETPOST("state_id", 'alpha') : $object->state_id, $object->country_code, 'state_id'); } else { @@ -719,23 +723,23 @@ else // Phone / Fax print ''; - print ''; + print ''; if ($conf->browser->layout == 'phone') print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; if ($conf->browser->layout == 'phone') print ''; print ''; - print ''; + print ''; print ''; if (($objsoc->typent_code == 'TE_PRIVATE' || !empty($conf->global->CONTACT_USE_COMPANY_ADDRESS)) && dol_strlen(trim($object->email)) == 0) $object->email = $objsoc->email; // Predefined with third party // Email print ''; - print ''; + print ''; print ''; if (!empty($conf->mailing->enabled)) @@ -755,7 +759,7 @@ else print ''; print ''; - print ''; + print ''; print ''; } print ''; diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index f56d03ceeb3..8d880226ff4 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -64,7 +64,7 @@ class Contact extends CommonObject /** * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. */ - public $fields=array( + public $fields = array( 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>15), 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>20), @@ -86,9 +86,9 @@ class Contact extends CommonObject 'phone_mobile' =>array('type'=>'varchar(30)', 'label'=>'Phone mobile', 'enabled'=>1, 'visible'=>-1, 'position'=>100), 'fax' =>array('type'=>'varchar(30)', 'label'=>'Fax', 'enabled'=>1, 'visible'=>-1, 'position'=>105), 'email' =>array('type'=>'varchar(255)', 'label'=>'Email', 'enabled'=>1, 'visible'=>-1, 'position'=>110), - 'socialnetworks' =>array('type'=>'text', 'label'=>'Socialnetworks', 'enabled'=>1, 'visible'=>-1, 'position'=>115), + 'socialnetworks' =>array('type'=>'text', 'label'=>'SocialNetworks', 'enabled'=>1, 'visible'=>-1, 'position'=>115), 'photo' =>array('type'=>'varchar(255)', 'label'=>'Photo', 'enabled'=>1, 'visible'=>-1, 'position'=>170), - 'priv' =>array('type'=>'smallint(6)', 'label'=>'Priv', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>175), + 'priv' =>array('type'=>'smallint(6)', 'label'=>'Private', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>175), 'no_email' =>array('type'=>'smallint(6)', 'label'=>'No email', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>180), 'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>185), 'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-1, 'position'=>190), @@ -314,9 +314,9 @@ class Contact extends CommonObject // Clean parameters $this->lastname = $this->lastname ?trim($this->lastname) : trim($this->name); $this->firstname = trim($this->firstname); - if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname = ucwords($this->lastname); + if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname = ucwords(strtolower($this->lastname)); if (!empty($conf->global->MAIN_ALL_TO_UPPER)) $this->lastname = strtoupper($this->lastname); - if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname = ucwords($this->firstname); + if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname = ucwords(strtolower($this->firstname)); if (empty($this->socid)) $this->socid = 0; if (empty($this->priv)) $this->priv = 0; if (empty($this->statut)) $this->statut = 0; // This is to convert '' into '0' to avoid bad sql request @@ -358,7 +358,7 @@ class Contact extends CommonObject if (!$error) { - $result = $this->update($this->id, $user, 1, 'add'); + $result = $this->update($this->id, $user, 1, 'add'); // This include updateRoles(), ... if ($result < 0) { $error++; @@ -427,9 +427,9 @@ class Contact extends CommonObject $this->entity = ((isset($this->entity) && is_numeric($this->entity)) ? $this->entity : $conf->entity); // Clean parameters - if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname = ucwords($this->lastname); + if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname = ucwords(strtolower($this->lastname)); if (!empty($conf->global->MAIN_ALL_TO_UPPER)) $this->lastname = strtoupper($this->lastname); - if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname = ucwords($this->firstname); + if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname = ucwords(strtolower($this->firstname)); $this->lastname = trim($this->lastname) ?trim($this->lastname) : trim($this->lastname); $this->firstname = trim($this->firstname); @@ -802,20 +802,19 @@ class Contact extends CommonObject /** - * Load object contact + * Load object contact. * - * @param int $id id du contact - * @param User $user Utilisateur (abonnes aux alertes) qui veut les alertes de ce contact - * @param string $ref_ext External reference, not given by Dolibarr - * @param string $email Email - * @return int -1 if KO, 0 if OK but not found, 1 if OK + * @param int $id Id of contact + * @param User $user Load also alerts of this user (subscribing to alerts) that want alerts about this contact + * @param string $ref_ext External reference, not given by Dolibarr + * @param string $email Email + * @param int $loadalsoroles Load also roles + * @return int >0 if OK, <0 if KO or if two records found for same ref or idprof, 0 if not found. */ - public function fetch($id, $user = null, $ref_ext = '', $email = '') + public function fetch($id, $user = null, $ref_ext = '', $email = '', $loadalsoroles = 0) { global $langs; - $langs->load("dict"); - dol_syslog(get_class($this)."::fetch id=".$id." ref_ext=".$ref_ext." email=".$email, LOG_DEBUG); if (empty($id) && empty($ref_ext) && empty($email)) @@ -824,7 +823,7 @@ class Contact extends CommonObject return -1; } - $langs->load("companies"); + $langs->loadLangs(array("dict", "companies")); $sql = "SELECT c.rowid, c.entity, c.fk_soc, c.ref_ext, c.civility as civility_code, c.lastname, c.firstname,"; $sql .= " c.address, c.statut, c.zip, c.town,"; @@ -861,7 +860,15 @@ class Contact extends CommonObject $resql = $this->db->query($sql); if ($resql) { - if ($this->db->num_rows($resql)) + $num = $this->db->num_rows($resql); + if ($num > 1) + { + $this->error = 'Fetch found several records. Rename one of contact to avoid duplicate.'; + dol_syslog($this->error, LOG_ERR); + + return 2; + } + elseif ($num) // $num = 1 { $obj = $this->db->fetch_object($resql); @@ -942,7 +949,11 @@ class Contact extends CommonObject return -1; } - // Charge alertes du user + // Retreive all extrafield + // fetch optionals attributes and labels + $this->fetch_optionals(); + + // Load also alerts of this user if ($user) { $sql = "SELECT fk_user"; @@ -967,13 +978,12 @@ class Contact extends CommonObject } } - // Retreive all extrafield - // fetch optionals attributes and labels - $this->fetch_optionals(); - - $resultRole = $this->fetchRoles(); - if ($resultRole < 0) { - return $resultRole; + // Load also roles of this address + if ($loadalsoroles) { + $resultRole = $this->fetchRoles(); + if ($resultRole < 0) { + return $resultRole; + } } return 1; @@ -992,19 +1002,25 @@ class Contact extends CommonObject } + /** - * Set property ->gender from property ->civility_id + * Set the property "gender" of this class, based on the property "civility_id" + * or use property "civility_code" as fallback, when "civility_id" is not available. * * @return void */ public function setGenderFromCivility() { - unset($this->gender); - if (in_array($this->civility_id, array('MR'))) { - $this->gender = 'man'; - } elseif (in_array($this->civility_id, array('MME', 'MLE'))) { - $this->gender = 'woman'; - } + unset($this->gender); + + if (in_array($this->civility_id, array('MR')) || in_array($this->civility_code, array('MR'))) + { + $this->gender = 'man'; + } + elseif (in_array($this->civility_id, array('MME', 'MLE')) || in_array($this->civility_code, array('MME', 'MLE'))) + { + $this->gender = 'woman'; + } } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -1270,9 +1286,16 @@ class Contact extends CommonObject { global $conf, $langs, $hookmanager; - $result = ''; + $result = ''; $label = ''; - $label = ''.$langs->trans("ShowContact").''; + if (!empty($this->photo) && class_exists('Form')) + { + $label .= '
'; + $label .= Form::showphoto('contact', $this, 0, 40, 0, '', 'mini', 0); // Important, we must force height so image will have height tags and if image is inside a tooltip, the tooltip manager can calculate height and position correctly the tooltip. + $label .= '
'; + } + + $label .= ''.$langs->trans("ShowContact").''; $label .= '
'.$langs->trans("Name").': '.$this->getFullName($langs); //if ($this->civility_id) $label.= '
' . $langs->trans("Civility") . ': '.$this->civility_id; // TODO Translate cibilty_id code if (!empty($this->poste)) $label .= '
'.$langs->trans("Poste").': '.$this->poste; @@ -1574,7 +1597,7 @@ class Contact extends CommonObject } /** - * Fetch Role for a contact + * Fetch Roles for a contact * * @return float|int * @throws Exception @@ -1586,14 +1609,14 @@ class Contact extends CommonObject $num = 0; $sql = "SELECT tc.rowid, tc.element, tc.source, tc.code, tc.libelle, sc.rowid as contactroleid"; - $sql .= " FROM ".MAIN_DB_PREFIX."societe_contacts as sc "; + $sql .= " FROM ".MAIN_DB_PREFIX."societe_contacts as sc"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."c_type_contact as tc"; $sql .= " ON tc.rowid = sc.fk_c_type_contact"; $sql .= " AND sc.fk_socpeople = ".$this->id; $sql .= " AND tc.source = 'external' AND tc.active=1"; $sql .= " AND sc.entity IN (".getEntity('societe').')'; - dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG); + dol_syslog(__METHOD__, LOG_DEBUG); $this->roles = array(); $resql = $this->db->query($sql); @@ -1630,6 +1653,10 @@ class Contact extends CommonObject { $tab = array(); + if ($element == 'action') { + $element = 'agenda'; + } + $sql = "SELECT sc.fk_socpeople as id, sc.fk_c_type_contact"; $sql .= " FROM ".MAIN_DB_PREFIX."c_type_contact tc"; $sql .= ", ".MAIN_DB_PREFIX."societe_contacts sc"; @@ -1638,7 +1665,7 @@ class Contact extends CommonObject $sql .= " AND tc.element='".$element."'"; $sql .= " AND tc.active=1"; - dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG); + dol_syslog(__METHOD__, LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { @@ -1678,7 +1705,7 @@ class Contact extends CommonObject $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_contacts WHERE fk_soc=".$this->socid." AND fk_socpeople=".$this->id; ; - dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG); + dol_syslog(__METHOD__, LOG_DEBUG); $result = $this->db->query($sql); if (!$result) { $this->errors[] = $this->db->lasterror().' sql='.$sql; @@ -1698,7 +1725,7 @@ class Contact extends CommonObject $sql .= $valRoles." , "; $sql .= $this->id; $sql .= ")"; - dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG); + dol_syslog(__METHOD__, LOG_DEBUG); $result = $this->db->query($sql); if (!$result) diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 1d0c3839f4f..9903e37cd5e 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -290,7 +290,7 @@ $title = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("C $sql = "SELECT s.rowid as socid, s.nom as name,"; $sql .= " p.rowid, p.lastname as lastname, p.statut, p.firstname, p.zip, p.town, p.poste, p.email, p.no_email,"; -$sql .= " p.socialnetworks,"; +$sql .= " p.socialnetworks, p.photo,"; $sql .= " p.phone as phone_pro, p.phone_mobile, p.phone_perso, p.fax, p.fk_pays, p.priv, p.datec as date_creation, p.tms as date_update,"; $sql .= " co.label as country, co.code as country_code"; // Add fields from extrafields @@ -786,7 +786,6 @@ while ($i < min($num, $limit)) { $obj = $db->fetch_object($result); - print ''; $arraysocialnetworks = (array) json_decode($obj->socialnetworks, true); $contactstatic->lastname = $obj->lastname; $contactstatic->firstname = ''; @@ -802,6 +801,9 @@ while ($i < min($num, $limit)) $contactstatic->socialnetworks = $arraysocialnetworks; $contactstatic->country = $obj->country; $contactstatic->country_code = $obj->country_code; + $contactstatic->photo = $obj->photo; + + print ''; // ID if (!empty($arrayfields['p.rowid']['checked'])) diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 1fc63769af3..4e0e5cb5865 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -1704,7 +1704,7 @@ else if (is_array($extralabelslines) && count($extralabelslines) > 0) { $line = new ContratLigne($db); $line->fetch_optionals($objp->rowid); - print $line->showOptionals($extrafields, 'view', array('style'=>'class="oddeven"', 'colspan'=>$colspan), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1); + print $line->showOptionals($extrafields, 'view', array('style'=>'class="oddeven"', 'colspan'=>$colspan), '', '', 1); } } // Line in mode update @@ -1794,7 +1794,7 @@ else if (is_array($extralabelslines) && count($extralabelslines) > 0) { $line = new ContratLigne($db); $line->fetch_optionals($objp->rowid); - print $line->showOptionals($extrafields, 'edit', array('style'=>'class="oddeven"', 'colspan'=>$colspan), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1); + print $line->showOptionals($extrafields, 'edit', array('style'=>'class="oddeven"', 'colspan'=>$colspan), '', '', 1); } } diff --git a/htdocs/contrat/class/api_contracts.class.php b/htdocs/contrat/class/api_contracts.class.php index 9d201d6fef1..71458e76050 100644 --- a/htdocs/contrat/class/api_contracts.class.php +++ b/htdocs/contrat/class/api_contracts.class.php @@ -439,8 +439,9 @@ class Contracts extends DolibarrApi * @url DELETE {id}/lines/{lineid} * * @return int - * @throws 401 - * @throws 404 + * + * @throws RestException 401 + * @throws RestException 404 */ public function deleteLine($id, $lineid) { diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index ecf12e11484..0aee2ed876d 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -165,12 +165,6 @@ class Contrat extends CommonObject */ public $date_contrat; - /** - * @var integer|string Date of contract closure - * @deprecated we close contract lines, not a contract - */ - public $date_cloture; - public $commercial_signature_id; public $commercial_suivi_id; @@ -231,17 +225,11 @@ class Contrat extends CommonObject 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35), 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>40), 'date_contrat' =>array('type'=>'datetime', 'label'=>'Date contrat', 'enabled'=>1, 'visible'=>-1, 'position'=>45), - 'statut' =>array('type'=>'smallint(6)', 'label'=>'Statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Closed')), - 'mise_en_service' =>array('type'=>'datetime', 'label'=>'Mise en service', 'enabled'=>1, 'visible'=>-1, 'position'=>55), - 'fin_validite' =>array('type'=>'datetime', 'label'=>'Fin validite', 'enabled'=>1, 'visible'=>-1, 'position'=>60), - 'date_cloture' =>array('type'=>'datetime', 'label'=>'Date cloture', 'enabled'=>1, 'visible'=>-1, 'position'=>65), 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>70), 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>75), 'fk_commercial_signature' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk commercial signature', 'enabled'=>1, 'visible'=>-1, 'position'=>80), 'fk_commercial_suivi' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk commercial suivi', 'enabled'=>1, 'visible'=>-1, 'position'=>85), 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>90), - 'fk_user_mise_en_service' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user mise en service', 'enabled'=>1, 'visible'=>-1, 'position'=>95), - 'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user cloture', 'enabled'=>1, 'visible'=>-1, 'position'=>100), 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>105), 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>110), 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>115), @@ -250,6 +238,7 @@ class Contrat extends CommonObject 'ref_customer' =>array('type'=>'varchar(50)', 'label'=>'Ref customer', 'enabled'=>1, 'visible'=>-1, 'position'=>130), 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135), 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>140), + 'statut' =>array('type'=>'smallint(6)', 'label'=>'Statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Closed')) ); // END MODULEBUILDER PROPERTIES @@ -528,7 +517,7 @@ class Contrat extends CommonObject { $num = $this->ref; } - $this->newref = $num; + $this->newref = dol_sanitizeFileName($num); if ($num) { @@ -696,12 +685,12 @@ class Contrat extends CommonObject */ public function fetch($id, $ref = '', $ref_customer = '', $ref_supplier = '') { - $sql = "SELECT rowid, statut, ref, fk_soc, mise_en_service as datemise,"; + $sql = "SELECT rowid, statut, ref, fk_soc,"; $sql .= " ref_supplier, ref_customer,"; $sql .= " ref_ext,"; $sql .= " entity,"; - $sql .= " fk_user_mise_en_service, date_contrat as datecontrat,"; - $sql .= " fk_user_author, fin_validite, date_cloture,"; + $sql .= " date_contrat as datecontrat,"; + $sql .= " fk_user_author,"; $sql .= " fk_projet as fk_project,"; $sql .= " fk_commercial_signature, fk_commercial_suivi,"; $sql .= " note_private, note_public, model_pdf, extraparams"; @@ -744,15 +733,10 @@ class Contrat extends CommonObject $this->ref_ext = $obj->ref_ext; $this->entity = $obj->entity; $this->statut = $obj->statut; - $this->mise_en_service = $this->db->jdate($obj->datemise); $this->date_contrat = $this->db->jdate($obj->datecontrat); $this->date_creation = $this->db->jdate($obj->datecontrat); - $this->fin_validite = $this->db->jdate($obj->fin_validite); - $this->date_cloture = $this->db->jdate($obj->date_cloture); - - $this->user_author_id = $obj->fk_user_author; $this->commercial_signature_id = $obj->fk_commercial_signature; @@ -1367,8 +1351,6 @@ class Contrat extends CommonObject if (isset($this->fk_soc)) $this->fk_soc = (int) $this->fk_soc; if (isset($this->fk_commercial_signature)) $this->fk_commercial_signature = trim($this->fk_commercial_signature); if (isset($this->fk_commercial_suivi)) $this->fk_commercial_suivi = trim($this->fk_commercial_suivi); - if (isset($this->fk_user_mise_en_service)) $this->fk_user_mise_en_service = (int) $this->fk_user_mise_en_service; - if (isset($this->fk_user_cloture)) $this->fk_user_cloture = (int) $this->fk_user_cloture; if (isset($this->note_private)) $this->note_private = trim($this->note_private); if (isset($this->note_public)) $this->note_public = trim($this->note_public); if (isset($this->import_key)) $this->import_key = trim($this->import_key); @@ -1386,15 +1368,10 @@ class Contrat extends CommonObject $sql .= " entity=".$conf->entity.","; $sql .= " date_contrat=".(dol_strlen($this->date_contrat) != 0 ? "'".$this->db->idate($this->date_contrat)."'" : 'null').","; $sql .= " statut=".(isset($this->statut) ? $this->statut : "null").","; - $sql .= " mise_en_service=".(dol_strlen($this->mise_en_service) != 0 ? "'".$this->db->idate($this->mise_en_service)."'" : 'null').","; - $sql .= " fin_validite=".(dol_strlen($this->fin_validite) != 0 ? "'".$this->db->idate($this->fin_validite)."'" : 'null').","; - $sql .= " date_cloture=".(dol_strlen($this->date_cloture) != 0 ? "'".$this->db->idate($this->date_cloture)."'" : 'null').","; $sql .= " fk_soc=".($this->fk_soc > 0 ? $this->fk_soc : "null").","; $sql .= " fk_projet=".($this->fk_project > 0 ? $this->fk_project : "null").","; $sql .= " fk_commercial_signature=".(isset($this->fk_commercial_signature) ? $this->fk_commercial_signature : "null").","; $sql .= " fk_commercial_suivi=".(isset($this->fk_commercial_suivi) ? $this->fk_commercial_suivi : "null").","; - $sql .= " fk_user_mise_en_service=".(isset($this->fk_user_mise_en_service) ? $this->fk_user_mise_en_service : "null").","; - $sql .= " fk_user_cloture=".(isset($this->fk_user_cloture) ? $this->fk_user_cloture : "null").","; $sql .= " note_private=".(isset($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : "null").","; $sql .= " note_public=".(isset($this->note_public) ? "'".$this->db->escape($this->note_public)."'" : "null").","; $sql .= " import_key=".(isset($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : "null").""; @@ -2096,9 +2073,9 @@ class Contrat extends CommonObject */ public function info($id) { - $sql = "SELECT c.rowid, c.ref, c.datec, c.date_cloture,"; + $sql = "SELECT c.rowid, c.ref, c.datec,"; $sql .= " c.tms as date_modification,"; - $sql .= " fk_user_author, fk_user_cloture"; + $sql .= " fk_user_author"; $sql .= " FROM ".MAIN_DB_PREFIX."contrat as c"; $sql .= " WHERE c.rowid = ".$id; @@ -2117,15 +2094,9 @@ class Contrat extends CommonObject $this->user_creation = $cuser; } - if ($obj->fk_user_cloture) { - $cuser = new User($this->db); - $cuser->fetch($obj->fk_user_cloture); - $this->user_cloture = $cuser; - } $this->ref = (!$obj->ref) ? $obj->rowid : $obj->ref; $this->date_creation = $this->db->jdate($obj->datec); $this->date_modification = $this->db->jdate($obj->date_modification); - $this->date_cloture = $this->db->jdate($obj->date_cloture); } $this->db->free($result); @@ -2783,8 +2754,8 @@ class ContratLigne extends CommonObjectLine /** * Return label of this contract line status * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Libelle + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status */ public function getLibStatut($mode) { @@ -2796,10 +2767,10 @@ class ContratLigne extends CommonObjectLine * Return label of a contract line status * * @param int $status Id status - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto * @param int $expired 0=Not expired, 1=Expired, -1=Both or unknown * @param string $moreatt More attribute - * @return string Libelle + * @return string Label of status */ public static function LibStatut($status, $mode, $expired = -1, $moreatt = '') { diff --git a/htdocs/contrat/index.php b/htdocs/contrat/index.php index 6dd6fc56e17..614743bbc46 100644 --- a/htdocs/contrat/index.php +++ b/htdocs/contrat/index.php @@ -209,10 +209,10 @@ if (!empty($conf->use_javascript_ajax)) include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; $dolgraph = new DolGraph(); $dolgraph->SetData($dataseries); - $dolgraph->setShowLegend(1); + $dolgraph->setShowLegend(2); $dolgraph->setShowPercent(1); $dolgraph->SetType(array('pie')); - $dolgraph->setWidth('100%'); + $dolgraph->setHeight('200'); $dolgraph->draw('idgraphstatus'); print $dolgraph->show($total ? 0 : 1); @@ -363,10 +363,10 @@ if ($result) print ''; print ''; //print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; print "\n"; $i++; } diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index 328507f6722..c32e45c1b42 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -705,9 +705,7 @@ while ($i < min($num, $limit)) $nbofsalesrepresentative = count($listsalesrepresentatives); if ($nbofsalesrepresentative > 3) { // We print only number - print ''; print $nbofsalesrepresentative; - print ''; } elseif ($nbofsalesrepresentative > 0) { @@ -741,7 +739,7 @@ while ($i < min($num, $limit)) // Date if (!empty($arrayfields['c.date_contrat']['checked'])) { - print ''; + print ''; } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; diff --git a/htdocs/contrat/tpl/linkedobjectblock.tpl.php b/htdocs/contrat/tpl/linkedobjectblock.tpl.php index b7ec9574ccb..b200baef726 100644 --- a/htdocs/contrat/tpl/linkedobjectblock.tpl.php +++ b/htdocs/contrat/tpl/linkedobjectblock.tpl.php @@ -63,7 +63,7 @@ foreach($linkedObjectBlock as $key => $objectlink) echo price($totalcontrat); } ?> - + fields[$key]['type'])) { $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } else { - $value = GETPOST($key, 'alpha'); + $value = GETPOST($key, 'alphanohtml'); } if (preg_match('/^integer:/i', $object->fields[$key]['type']) && $value == '-1') $value = ''; // This is an implicit foreign key field if (!empty($object->fields[$key]['foreignkey']) && $value == '-1') $value = ''; // This is an explicit foreign key field @@ -128,6 +128,13 @@ if ($action == 'update' && !empty($permissiontoadd)) if ($object->fields[$key]['type'] == 'duration') { if (!GETPOSTISSET($key.'hour') || !GETPOSTISSET($key.'min')) continue; // The field was not submited to be edited } + elseif ($object->fields[$key]['type'] == 'boolean') { + if (!GETPOSTISSET($key)) { + $object->$key = 0; // use 0 instead null if the field is defined as not null + continue; + } + } + else { if (!GETPOSTISSET($key)) continue; // The field was not submited to be edited } diff --git a/htdocs/core/actions_extrafields.inc.php b/htdocs/core/actions_extrafields.inc.php index ca2499ab145..5c8fc84a843 100644 --- a/htdocs/core/actions_extrafields.inc.php +++ b/htdocs/core/actions_extrafields.inc.php @@ -183,7 +183,8 @@ if ($action == 'add') (GETPOST('entitycurrentorall', 'alpha')?0:''), GETPOST('langfile', 'alpha'), 1, - (GETPOST('totalizable', 'alpha')?1:0) + (GETPOST('totalizable', 'alpha')?1:0), + GETPOST('printable', 'alpha') ); if ($result > 0) { @@ -352,7 +353,8 @@ if ($action == 'update') (GETPOST('entitycurrentorall', 'alpha')?0:''), GETPOST('langfile'), 1, - (GETPOST('totalizable', 'alpha')?1:0) + (GETPOST('totalizable', 'alpha')?1:0), + GETPOST('printable', 'alpha') ); if ($result > 0) { diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 4a00412f800..c3f046431b0 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -691,11 +691,11 @@ if ($massaction == 'confirm_createbills') // Create bills from orders for ($i = 0; $i < $num; $i++) { - $desc = ($lines[$i]->desc ? $lines[$i]->desc : $lines[$i]->libelle); + $desc = ($lines[$i]->desc ? $lines[$i]->desc : ''); // If we build one invoice for several order, we must put the invoice of order on the line if (!empty($createbills_onebythird)) { - $desc = dol_concatdesc($desc, $langs->trans("Order").' '.$cmd->ref.' - '.dol_print_date($cmd->date, 'day', $langs)); + $desc = dol_concatdesc($desc, $langs->trans("Order").' '.$cmd->ref.' - '.dol_print_date($cmd->date, 'day')); } if ($lines[$i]->subprice < 0) diff --git a/htdocs/core/actions_setmoduleoptions.inc.php b/htdocs/core/actions_setmoduleoptions.inc.php index 9ade3c148a4..313375d1aa1 100644 --- a/htdocs/core/actions_setmoduleoptions.inc.php +++ b/htdocs/core/actions_setmoduleoptions.inc.php @@ -68,6 +68,7 @@ if ($action == 'setModuleOptions') { foreach ($_POST as $key => $val) { + $reg = array(); if (preg_match('/^param(\d*)$/', $key, $reg)) // Works for POST['param'], POST['param1'], POST['param2'], ... { $param = GETPOST("param".$reg[1], 'alpha'); diff --git a/htdocs/core/boxes/box_boms.php b/htdocs/core/boxes/box_boms.php index 8f27ff739e0..44102f0aab1 100644 --- a/htdocs/core/boxes/box_boms.php +++ b/htdocs/core/boxes/box_boms.php @@ -86,7 +86,7 @@ class box_boms extends ModeleBoxes if ($user->rights->bom->read) { - $sql = "SELECT p.ref as product_ref"; + $sql = "SELECT p.ref as product_ref, p.tobuy, p.tosell"; $sql.= ", c.rowid"; $sql.= ", c.date_creation"; $sql.= ", c.tms"; @@ -109,11 +109,15 @@ class box_boms extends ModeleBoxes while ($line < $num) { $objp = $this->db->fetch_object($result); $datem=$this->db->jdate($objp->tms); + $bomstatic->id = $objp->rowid; $bomstatic->ref = $objp->ref; $bomstatic->id = $objp->socid; $bomstatic->status = $objp->status; + $productstatic->ref = $objp->product_ref; + $productstatic->status = $objp->tobuy; + $productstatic->status_buy = $objp->tosell; $this->info_box_contents[$line][] = array( 'td' => 'class="nowraponall"', diff --git a/htdocs/core/boxes/box_clients.php b/htdocs/core/boxes/box_clients.php index feb7564cdaf..d82a4aee71e 100644 --- a/htdocs/core/boxes/box_clients.php +++ b/htdocs/core/boxes/box_clients.php @@ -32,9 +32,9 @@ include_once DOL_DOCUMENT_ROOT.'/core/boxes/modules_boxes.php'; */ class box_clients extends ModeleBoxes { - public $boxcode="lastcustomers"; - public $boximg="object_company"; - public $boxlabel="BoxLastCustomers"; + public $boxcode = "lastcustomers"; + public $boximg = "object_company"; + public $boxlabel = "BoxLastCustomers"; public $depends = array("societe"); /** @@ -61,9 +61,9 @@ class box_clients extends ModeleBoxes $this->db = $db; // disable box for such cases - if (! empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) $this->enabled=0; // disabled by this option + if (!empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) $this->enabled = 0; // disabled by this option - $this->hidden = ! ($user->rights->societe->lire && empty($user->socid)); + $this->hidden = !($user->rights->societe->lire && empty($user->socid)); } /** @@ -77,33 +77,33 @@ class box_clients extends ModeleBoxes global $user, $langs, $conf; $langs->load("boxes"); - $this->max=$max; + $this->max = $max; include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; - $thirdpartystatic=new Societe($this->db); + $thirdpartystatic = new Societe($this->db); $this->info_box_head = array('text' => $langs->trans("BoxTitleLastModifiedCustomers", $max)); if ($user->rights->societe->lire) { $sql = "SELECT s.nom as name, s.rowid as socid"; - $sql.= ", s.code_client"; - $sql.= ", s.client"; - $sql.= ", s.code_fournisseur"; - $sql.= ", s.fournisseur"; - $sql.= ", s.code_compta"; - $sql.= ", s.code_compta_fournisseur"; - $sql.= ", s.logo"; - $sql.= ", s.email"; - $sql.= ", s.datec, s.tms, s.status"; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$user->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE s.client IN (1, 3)"; - $sql.= " AND s.entity IN (".getEntity('societe').")"; - if (!$user->rights->societe->client->voir && !$user->socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if ($user->socid) $sql.= " AND s.rowid = $user->socid"; - $sql.= " ORDER BY s.tms DESC"; - $sql.= $this->db->plimit($max, 0); + $sql .= ", s.code_client"; + $sql .= ", s.client"; + $sql .= ", s.code_fournisseur"; + $sql .= ", s.fournisseur"; + $sql .= ", s.code_compta"; + $sql .= ", s.code_compta_fournisseur"; + $sql .= ", s.logo"; + $sql .= ", s.email"; + $sql .= ", s.datec, s.tms, s.status, s.entity"; + $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; + if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " WHERE s.client IN (1, 3)"; + $sql .= " AND s.entity IN (".getEntity('societe').")"; + if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; + if ($user->socid) $sql .= " AND s.rowid = $user->socid"; + $sql .= " ORDER BY s.tms DESC"; + $sql .= $this->db->plimit($max, 0); dol_syslog(get_class($this)."::loadBox", LOG_DEBUG); $result = $this->db->query($sql); @@ -115,8 +115,8 @@ class box_clients extends ModeleBoxes while ($line < $num) { $objp = $this->db->fetch_object($result); - $datec=$this->db->jdate($objp->datec); - $datem=$this->db->jdate($objp->tms); + $datec = $this->db->jdate($objp->datec); + $datem = $this->db->jdate($objp->tms); $thirdpartystatic->id = $objp->socid; $thirdpartystatic->name = $objp->name; $thirdpartystatic->code_client = $objp->code_client; @@ -127,6 +127,7 @@ class box_clients extends ModeleBoxes $thirdpartystatic->fournisseur = $objp->fournisseur; $thirdpartystatic->logo = $objp->logo; $thirdpartystatic->email = $objp->email; + $thirdpartystatic->entity = $objp->entity; $this->info_box_contents[$line][] = array( 'td' => '', @@ -147,7 +148,7 @@ class box_clients extends ModeleBoxes $line++; } - if ($num==0) $this->info_box_contents[$line][0] = array('td' => 'class="center"','text'=>$langs->trans("NoRecordedCustomers")); + if ($num == 0) $this->info_box_contents[$line][0] = array('td' => 'class="center"', 'text'=>$langs->trans("NoRecordedCustomers")); $this->db->free($result); } diff --git a/htdocs/core/boxes/box_commandes.php b/htdocs/core/boxes/box_commandes.php index c8a050ea1d4..10b9c52acb0 100644 --- a/htdocs/core/boxes/box_commandes.php +++ b/htdocs/core/boxes/box_commandes.php @@ -72,6 +72,7 @@ class box_commandes extends ModeleBoxes public function loadBox($max = 5) { global $user, $langs, $conf; + $langs->load('orders'); $this->max = $max; diff --git a/htdocs/core/boxes/box_contacts.php b/htdocs/core/boxes/box_contacts.php index 91c6ab23910..caea252c571 100644 --- a/htdocs/core/boxes/box_contacts.php +++ b/htdocs/core/boxes/box_contacts.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2015 Frederic France * Copyright (C) 2018 Josep Lluís Amador + * Copyright (C) 2020 Ferran Marcet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -83,6 +84,7 @@ class box_contacts extends ModeleBoxes if ($user->rights->societe->lire && $user->rights->societe->contact->lire) { $sql = "SELECT sp.rowid as id, sp.lastname, sp.firstname, sp.civility as civility_id, sp.datec, sp.tms, sp.fk_soc, sp.statut as status"; + $sql .= ", sp.address, sp.zip, sp.town, sp.phone, sp.phone_perso, sp.phone_mobile, sp.email as spemail"; $sql .= ", s.nom as socname, s.name_alias, s.email as semail"; $sql .= ", s.client, s.fournisseur, s.code_client, s.code_fournisseur"; diff --git a/htdocs/core/boxes/box_fournisseurs.php b/htdocs/core/boxes/box_fournisseurs.php index 5f26351affe..2f55a379362 100644 --- a/htdocs/core/boxes/box_fournisseurs.php +++ b/htdocs/core/boxes/box_fournisseurs.php @@ -2,6 +2,7 @@ /* Copyright (C) 2004-2006 Destailleur Laurent * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2015-2019 Frederic France + * Copyright (C) 2020 Pierre Ardoin * * 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,9 +32,9 @@ include_once DOL_DOCUMENT_ROOT.'/core/boxes/modules_boxes.php'; */ class box_fournisseurs extends ModeleBoxes { - public $boxcode="lastsuppliers"; - public $boximg="object_company"; - public $boxlabel="BoxLastSuppliers"; + public $boxcode = "lastsuppliers"; + public $boximg = "object_company"; + public $boxlabel = "BoxLastSuppliers"; public $depends = array("fournisseur"); /** @@ -59,7 +60,7 @@ class box_fournisseurs extends ModeleBoxes $this->db = $db; - $this->hidden = ! ($user->rights->societe->lire && empty($user->socid)); + $this->hidden = !($user->rights->societe->lire && empty($user->socid)); } /** @@ -73,28 +74,28 @@ class box_fournisseurs extends ModeleBoxes global $conf, $user, $langs; $langs->load("boxes"); - $this->max=$max; + $this->max = $max; include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; - $thirdpartystatic=new Societe($this->db); + $thirdpartystatic = new Societe($this->db); include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php'; - $thirdpartytmp=new Fournisseur($this->db); + $thirdpartytmp = new Fournisseur($this->db); $this->info_box_head = array('text' => $langs->trans("BoxTitleLastModifiedSuppliers", $max)); if ($user->rights->societe->lire) { $sql = "SELECT s.nom as name, s.rowid as socid, s.datec, s.tms, s.status,"; - $sql.= " s.code_fournisseur, s.email as semail,"; - $sql.= " s.logo"; + $sql .= " s.code_fournisseur, s.email as semail,"; + $sql .= " s.logo, s.code_compta_fournisseur, s.entity"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$user->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE s.fournisseur = 1"; - $sql.= " AND s.entity IN (".getEntity('societe').")"; - if (!$user->rights->societe->client->voir && !$user->socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if ($user->socid) $sql.= " AND s.rowid = ".$user->socid; - $sql.= " ORDER BY s.tms DESC "; - $sql.= $this->db->plimit($max, 0); + if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " WHERE s.fournisseur = 1"; + $sql .= " AND s.entity IN (".getEntity('societe').")"; + if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; + if ($user->socid) $sql .= " AND s.rowid = ".$user->socid; + $sql .= " ORDER BY s.tms DESC "; + $sql .= $this->db->plimit($max, 0); $result = $this->db->query($sql); if ($result) @@ -105,13 +106,15 @@ class box_fournisseurs extends ModeleBoxes while ($line < $num) { $objp = $this->db->fetch_object($result); - $datec=$this->db->jdate($objp->datec); - $datem=$this->db->jdate($objp->tms); + $datec = $this->db->jdate($objp->datec); + $datem = $this->db->jdate($objp->tms); $thirdpartytmp->id = $objp->socid; $thirdpartytmp->name = $objp->name; $thirdpartytmp->email = $objp->semail; $thirdpartytmp->code_client = $objp->code_client; $thirdpartytmp->logo = $objp->logo; + $thirdpartytmp->code_compta_fournisseur = $objp->code_compta_fournisseur; + $thirdpartytmp->entity = $objp->entity; $this->info_box_contents[$line][] = array( 'td' => '', @@ -132,7 +135,7 @@ class box_fournisseurs extends ModeleBoxes $line++; } - if ($num==0) $this->info_box_contents[$line][0] = array( + if ($num == 0) $this->info_box_contents[$line][0] = array( 'td' => 'class="center"', 'text'=>$langs->trans("NoRecordedSuppliers"), ); diff --git a/htdocs/core/boxes/box_graph_invoices_permonth.php b/htdocs/core/boxes/box_graph_invoices_permonth.php index 6c0a20bc6db..e78b6e235b1 100644 --- a/htdocs/core/boxes/box_graph_invoices_permonth.php +++ b/htdocs/core/boxes/box_graph_invoices_permonth.php @@ -160,6 +160,7 @@ class box_graph_invoices_permonth extends ModeleBoxes } $i++; } + $px1->SetLegend($legend); $px1->SetMaxValue($px1->GetCeilMaxValue()); $px1->SetWidth($WIDTH); diff --git a/htdocs/core/boxes/box_graph_product_distribution.php b/htdocs/core/boxes/box_graph_product_distribution.php index c61bc2569be..3447b76a2b7 100644 --- a/htdocs/core/boxes/box_graph_product_distribution.php +++ b/htdocs/core/boxes/box_graph_product_distribution.php @@ -75,6 +75,7 @@ class box_graph_product_distribution extends ModeleBoxes global $conf, $user, $langs; $this->max = $max; + $dir = $conf->user->dir_temp; $refreshaction = 'refresh_'.$this->boxcode; @@ -145,7 +146,8 @@ class box_graph_product_distribution extends ModeleBoxes $showpointvalue = 1; $nocolor = 0; $mode = 'customer'; $stats_invoice = new FactureStats($this->db, $socid, $mode, ($userid > 0 ? $userid : 0)); - $data1 = $stats_invoice->getAllByProductEntry($year, (GETPOST('action', 'aZ09') == $refreshaction ?-1 : (3600 * 24))); + $data1 = $stats_invoice->getAllByProductEntry($year, (GETPOST('action', 'aZ09') == $refreshaction ?-1 : (3600 * 24)), 5); + if (empty($data1)) { $showpointvalue = 0; @@ -159,11 +161,12 @@ class box_graph_product_distribution extends ModeleBoxes $mesg = $px1->isGraphKo(); if (!$mesg) { - $i = 0; $tot = count($data1); $legend = array(); - while ($i <= $tot) + $i = 0; $legend = array(); + + foreach($data1 as $key => $val) { - $data1[$i][0] = dol_trunc($data1[$i][0], 5); // Required to avoid error "Could not draw pie with labels contained inside canvas" - $legend[] = $data1[$i][0]; + $data1[$key][0] = dol_trunc($data1[$key][0], 32); + $legend[] = $data1[$key][0]; $i++; } @@ -172,11 +175,11 @@ class box_graph_product_distribution extends ModeleBoxes if ($nocolor) $px1->SetDataColor(array(array(220, 220, 220))); $px1->SetLegend($legend); - $px1->setShowLegend(0); + $px1->setShowLegend(2); $px1->setShowPointValue($showpointvalue); $px1->setShowPercent(0); $px1->SetMaxValue($px1->GetCeilMaxValue()); - $px1->SetWidth($WIDTH); + //$px1->SetWidth($WIDTH); $px1->SetHeight($HEIGHT); //$px1->SetYLabel($langs->trans("NumberOfBills")); $px1->SetShading(3); @@ -202,7 +205,7 @@ class box_graph_product_distribution extends ModeleBoxes $showpointvalue = 1; $nocolor = 0; $stats_proposal = new PropaleStats($this->db, $socid, ($userid > 0 ? $userid : 0)); - $data2 = $stats_proposal->getAllByProductEntry($year, (GETPOST('action', 'aZ09') == $refreshaction ?-1 : (3600 * 24))); + $data2 = $stats_proposal->getAllByProductEntry($year, (GETPOST('action', 'aZ09') == $refreshaction ?-1 : (3600 * 24)), 5); if (empty($data2)) { $showpointvalue = 0; @@ -217,11 +220,12 @@ class box_graph_product_distribution extends ModeleBoxes $mesg = $px2->isGraphKo(); if (!$mesg) { - $i = 0; $tot = count($data2); $legend = array(); - while ($i <= $tot) + $i = 0; $legend = array(); + + foreach($data2 as $key => $val) { - $data2[$i][0] = dol_trunc($data2[$i][0], 5); // Required to avoid error "Could not draw pie with labels contained inside canvas" - $legend[] = $data2[$i][0]; + $data2[$key][0] = dol_trunc($data2[$key][0], 32); + $legend[] = $data2[$key][0]; $i++; } @@ -230,11 +234,11 @@ class box_graph_product_distribution extends ModeleBoxes if ($nocolor) $px2->SetDataColor(array(array(220, 220, 220))); $px2->SetLegend($legend); - $px2->setShowLegend(0); + $px2->setShowLegend(2); $px2->setShowPointValue($showpointvalue); $px2->setShowPercent(0); $px2->SetMaxValue($px2->GetCeilMaxValue()); - $px2->SetWidth($WIDTH); + //$px2->SetWidth($WIDTH); $px2->SetHeight($HEIGHT); //$px2->SetYLabel($langs->trans("AmountOfBillsHT")); $px2->SetShading(3); @@ -261,7 +265,7 @@ class box_graph_product_distribution extends ModeleBoxes $showpointvalue = 1; $nocolor = 0; $mode = 'customer'; $stats_order = new CommandeStats($this->db, $socid, $mode, ($userid > 0 ? $userid : 0)); - $data3 = $stats_order->getAllByProductEntry($year, (GETPOST('action', 'aZ09') == $refreshaction ?-1 : (3600 * 24))); + $data3 = $stats_order->getAllByProductEntry($year, (GETPOST('action', 'aZ09') == $refreshaction ?-1 : (3600 * 24)), 5); if (empty($data3)) { $showpointvalue = 0; @@ -276,11 +280,12 @@ class box_graph_product_distribution extends ModeleBoxes $mesg = $px3->isGraphKo(); if (!$mesg) { - $i = 0; $tot = count($data3); $legend = array(); - while ($i <= $tot) + $i = 0; $legend = array(); + + foreach($data3 as $key => $val) { - $data3[$i][0] = dol_trunc($data3[$i][0], 5); // Required to avoid error "Could not draw pie with labels contained inside canvas" - $legend[] = $data3[$i][0]; + $data3[$key][0] = dol_trunc($data3[$key][0], 32); + $legend[] = $data3[$key][0]; $i++; } @@ -289,11 +294,11 @@ class box_graph_product_distribution extends ModeleBoxes if ($nocolor) $px3->SetDataColor(array(array(220, 220, 220))); $px3->SetLegend($legend); - $px3->setShowLegend(0); + $px3->setShowLegend(2); $px3->setShowPointValue($showpointvalue); $px3->setShowPercent(0); $px3->SetMaxValue($px3->GetCeilMaxValue()); - $px3->SetWidth($WIDTH); + //$px3->SetWidth($WIDTH); $px3->SetHeight($HEIGHT); //$px3->SetYLabel($langs->trans("AmountOfBillsHT")); $px3->SetShading(3); diff --git a/htdocs/core/boxes/box_project.php b/htdocs/core/boxes/box_project.php index 68095eaec31..9fffc92963f 100644 --- a/htdocs/core/boxes/box_project.php +++ b/htdocs/core/boxes/box_project.php @@ -3,6 +3,7 @@ * Copyright (C) 2014 Marcos García * Copyright (C) 2015 Frederic France * Copyright (C) 2016 Juan José Menent + * Copyright (C) 2020 Pierre Ardoin * * 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 @@ -95,9 +96,10 @@ class box_project extends ModeleBoxes $projectsListId=''; if (! $user->rights->projet->all->lire) $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, $socid); - $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut, p.public"; + $sql = "SELECT p.rowid, p.ref, p.title, p.fk_statut as status, p.public"; $sql.= " FROM ".MAIN_DB_PREFIX."projet as p"; - $sql.= " WHERE p.fk_statut = 1"; // Only open projects + $sql.= " WHERE p.entity IN (".getEntity('project').")"; // Only current entity or severals if permission ok + $sql.= " AND p.fk_statut = 1"; // Only open projects if (! $user->rights->projet->all->lire) $sql.= " AND p.rowid IN (".$projectsListId.")"; // public and assigned to, or restricted to company for external users $sql.= " ORDER BY p.datec DESC"; @@ -115,6 +117,7 @@ class box_project extends ModeleBoxes $projectstatic->ref = $objp->ref; $projectstatic->title = $objp->title; $projectstatic->public = $objp->public; + $projectstatic->statut = $objp->status; $this->info_box_contents[$i][] = array( 'td' => 'class="nowraponall"', @@ -150,6 +153,7 @@ class box_project extends ModeleBoxes $this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => round(0)); $this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => "N/A "); } + $this->info_box_contents[$i][] = array('td' => 'class="right"', 'text' => $projectstatic->getLibStatut(3)); $i++; } @@ -164,22 +168,26 @@ class box_project extends ModeleBoxes // Add the sum à the bottom of the boxes $this->info_box_contents[$i][] = array( - 'td' => '', + 'td' => 'class="liste_total"', 'text' => $langs->trans("Total")." ".$textHead, 'text' => " ", ); $this->info_box_contents[$i][] = array( - 'td' => 'class="right" ', + 'td' => 'class="right liste_total" ', 'text' => round($num, 0)." ".$langs->trans("Projects"), ); $this->info_box_contents[$i][] = array( - 'td' => 'class="right" ', + 'td' => 'class="right liste_total" ', 'text' => (($max < $num) ? '' : (round($totalnbTask, 0)." ".$langs->trans("Tasks"))), ); $this->info_box_contents[$i][] = array( - 'td' => '', + 'td' => 'class="liste_total"', 'text' => " ", ); + $this->info_box_contents[$i][] = array( + 'td' => 'class="liste_total"', + 'text' => " ", + ); } /** diff --git a/htdocs/core/boxes/box_propales.php b/htdocs/core/boxes/box_propales.php index 3cbd9f45514..979723753a0 100644 --- a/htdocs/core/boxes/box_propales.php +++ b/htdocs/core/boxes/box_propales.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2007 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2015-2019 Frederic France + * Copyright (C) 2020 Pierre Ardoin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,10 +33,10 @@ include_once DOL_DOCUMENT_ROOT.'/core/boxes/modules_boxes.php'; */ class box_propales extends ModeleBoxes { - public $boxcode="lastpropals"; - public $boximg="object_propal"; - public $boxlabel="BoxLastProposals"; - public $depends = array("propal"); // conf->propal->enabled + public $boxcode = "lastpropals"; + public $boximg = "object_propal"; + public $boxlabel = "BoxLastProposals"; + public $depends = array("propal"); // conf->propal->enabled /** * @var DoliDB Database handler. @@ -60,7 +61,7 @@ class box_propales extends ModeleBoxes $this->db = $db; - $this->hidden = ! ($user->rights->propale->lire); + $this->hidden = !($user->rights->propale->lire); } /** @@ -73,45 +74,45 @@ class box_propales extends ModeleBoxes { global $user, $langs, $conf; - $this->max=$max; + $this->max = $max; include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; - $propalstatic=new Propal($this->db); + $propalstatic = new Propal($this->db); $societestatic = new Societe($this->db); - $this->info_box_head = array('text' => $langs->trans("BoxTitleLast".($conf->global->MAIN_LASTBOX_ON_OBJECT_DATE?"":"Modified")."Propals", $max)); + $this->info_box_head = array('text' => $langs->trans("BoxTitleLast".($conf->global->MAIN_LASTBOX_ON_OBJECT_DATE ? "" : "Modified")."Propals", $max)); if ($user->rights->propale->lire) { - $sql = "SELECT s.nom as name, s.rowid as socid, s.code_client, s.logo, s.email,"; - $sql.= " p.rowid, p.ref, p.fk_statut, p.datep as dp, p.datec, p.fin_validite, p.date_cloture, p.total_ht, p.tva as total_tva, p.total as total_ttc, p.tms"; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; - $sql.= ", ".MAIN_DB_PREFIX."propal as p"; - if (!$user->rights->societe->client->voir && !$user->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE p.fk_soc = s.rowid"; - $sql.= " AND p.entity = ".$conf->entity; - if (!$user->rights->societe->client->voir && !$user->socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if($user->socid) $sql.= " AND s.rowid = ".$user->socid; - if ($conf->global->MAIN_LASTBOX_ON_OBJECT_DATE) $sql.= " ORDER BY p.datep DESC, p.ref DESC "; - else $sql.= " ORDER BY p.tms DESC, p.ref DESC "; - $sql.= $this->db->plimit($max, 0); + $sql = "SELECT s.nom as name, s.rowid as socid, s.code_client, s.logo, s.entity, s.email,"; + $sql .= " p.rowid, p.ref, p.fk_statut, p.datep as dp, p.datec, p.fin_validite, p.date_cloture, p.total_ht, p.tva as total_tva, p.total as total_ttc, p.tms"; + $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; + $sql .= ", ".MAIN_DB_PREFIX."propal as p"; + if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql .= " WHERE p.fk_soc = s.rowid"; + $sql .= " AND p.entity = ".$conf->entity; + if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; + if ($user->socid) $sql .= " AND s.rowid = ".$user->socid; + if ($conf->global->MAIN_LASTBOX_ON_OBJECT_DATE) $sql .= " ORDER BY p.datep DESC, p.ref DESC "; + else $sql .= " ORDER BY p.tms DESC, p.ref DESC "; + $sql .= $this->db->plimit($max, 0); $result = $this->db->query($sql); if ($result) { $num = $this->db->num_rows($result); - $now=dol_now(); + $now = dol_now(); $line = 0; while ($line < $num) { $objp = $this->db->fetch_object($result); - $date=$this->db->jdate($objp->dp); - $datec=$this->db->jdate($objp->datec); - $datem=$this->db->jdate($objp->tms); - $dateterm=$this->db->jdate($objp->fin_validite); - $dateclose=$this->db->jdate($objp->date_cloture); + $date = $this->db->jdate($objp->dp); + $datec = $this->db->jdate($objp->datec); + $datem = $this->db->jdate($objp->tms); + $dateterm = $this->db->jdate($objp->fin_validite); + $dateclose = $this->db->jdate($objp->date_cloture); $propalstatic->id = $objp->rowid; $propalstatic->ref = $objp->ref; $propalstatic->total_ht = $objp->total_ht; @@ -122,6 +123,7 @@ class box_propales extends ModeleBoxes $societestatic->code_client = $objp->code_client; $societestatic->logo = $objp->logo; $societestatic->email = $objp->email; + $societestatic->entity = $objp->entity; $late = ''; if ($objp->fk_statut == 1 && $dateterm < ($now - $conf->propal->cloture->warning_delay)) { @@ -159,7 +161,7 @@ class box_propales extends ModeleBoxes $line++; } - if ($num==0) + if ($num == 0) $this->info_box_contents[$line][0] = array( 'td' => 'class="center"', 'text'=>$langs->trans("NoRecordedProposals"), diff --git a/htdocs/core/boxes/box_services_contracts.php b/htdocs/core/boxes/box_services_contracts.php index dbb26408b6f..5b40fc61436 100644 --- a/htdocs/core/boxes/box_services_contracts.php +++ b/htdocs/core/boxes/box_services_contracts.php @@ -91,7 +91,7 @@ class box_services_contracts extends ModeleBoxes $sql = "SELECT s.nom as name, s.rowid as socid, s.email, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,"; $sql.= " c.rowid, c.ref, c.statut as contract_status, c.ref_customer, c.ref_supplier,"; $sql.= " cd.rowid as cdid, cd.label, cd.description, cd.tms as datem, cd.statut, cd.product_type as type,"; - $sql.= " p.rowid as product_id, p.ref as product_ref, p.label as plabel, p.fk_product_type as ptype, p.entity"; + $sql.= " p.rowid as product_id, p.ref as product_ref, p.label as plabel, p.fk_product_type as ptype, p.entity, p.tobuy, p.tosell"; $sql.= " FROM (".MAIN_DB_PREFIX."societe as s"; $sql.= " INNER JOIN ".MAIN_DB_PREFIX."contrat as c ON s.rowid = c.fk_soc"; $sql.= " INNER JOIN ".MAIN_DB_PREFIX."contratdet as cd ON c.rowid = cd.fk_contrat"; @@ -165,6 +165,9 @@ class box_services_contracts extends ModeleBoxes $productstatic->ref=$objp->product_ref; $productstatic->entity=$objp->pentity; $productstatic->label=$objp->plabel; + $productstatic->status = $objp->tosell; + $productstatic->status_buy = $objp->tobuy; + $text = $productstatic->getNomUrl(1, '', 20); if ($objp->plabel) { diff --git a/htdocs/core/boxes/box_task.php b/htdocs/core/boxes/box_task.php index 2ae0ede3c21..94983ef6bff 100644 --- a/htdocs/core/boxes/box_task.php +++ b/htdocs/core/boxes/box_task.php @@ -86,6 +86,7 @@ class box_task extends ModeleBoxes $form = new Form($this->db); $cookie_name = 'boxfilter_task'; $boxcontent = ''; + $socid = $user->socid; $textHead = $langs->trans("CurentlyOpenedTasks"); @@ -97,7 +98,6 @@ class box_task extends ModeleBoxes $filterValue = $_COOKIE[$cookie_name]; } - if ($filterValue == 'im_task_contact') { $textHead .= ' : '.$langs->trans("WhichIamLinkedTo"); } @@ -127,15 +127,17 @@ class box_task extends ModeleBoxes $boxcontent .= ''; $boxcontent .= ''."\n"; $boxcontent .= ''."\n"; - $boxcontent .= ''; - // set cookie by js - $boxcontent .= ''; + '; + // set cookie by js + $boxcontent .= ''; + } $this->info_box_contents[0][] = array( 'tr'=>'class="nohover showiffilter'.$this->boxcode.' hideobject"', 'td' => 'class="nohover"', @@ -143,6 +145,10 @@ class box_task extends ModeleBoxes ); + // Get list of project id allowed to user (in a string list separated by coma) + $projectsListId = ''; + if (!$user->rights->projet->all->lire) $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, $socid); + $sql = "SELECT pt.rowid, pt.ref, pt.fk_projet, pt.fk_task_parent, pt.datec, pt.dateo, pt.datee, pt.datev, pt.label, pt.description, pt.duration_effective, pt.planned_workload, pt.progress"; $sql .= ", p.rowid project_id, p.ref project_ref, p.title project_title"; @@ -163,7 +169,7 @@ class box_task extends ModeleBoxes $sql .= " AND p.fk_statut = ".Project::STATUS_VALIDATED; $sql .= " AND (pt.progress < 100 OR pt.progress IS NULL ) "; // 100% is done and not displayed $sql .= " AND p.usage_task = 1 "; - + if (!$user->rights->projet->all->lire) $sql .= " AND p.rowid IN (".$projectsListId.")"; // public and assigned to, or restricted to company for external users $sql .= " ORDER BY pt.datee ASC, pt.dateo ASC"; $sql .= $this->db->plimit($max, 0); diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index e0a1fd35092..bba38bddb30 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -82,15 +82,15 @@ class CMailFile public $headers; public $message; /** - * @var array fullfilenames list + * @var array fullfilenames list (full path of filename on file system) */ public $filename_list = array(); /** - * @var array mimetypes of files list + * @var array mimetypes of files list (List of MIME type of attached files) */ public $mimetype_list = array(); /** - * @var array filenames list + * @var array filenames list (List of attached file name in message) */ public $mimefilename_list = array(); @@ -137,6 +137,16 @@ class CMailFile { global $conf, $dolibarr_main_data_root; + // Clean values of $mimefilename_list + if (is_array($mimefilename_list)) { + foreach($mimefilename_list as $key => $val) { + $mimefilename_list[$key] = dol_string_unaccent($mimefilename_list[$key]); + } + } + + // Add autocopy to (Note: Adding bcc for specific modules are also done from pages) + if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) $addr_bcc .= ($addr_bcc ? ', ' : '').$conf->global->MAIN_MAIL_AUTOCOPY_TO; + $this->subject = $subject; $this->addr_to = $to; $this->addr_from = $from; @@ -156,7 +166,6 @@ class CMailFile $this->mimetype_list = $mimetype_list; $this->mimefilename_list = $mimefilename_list; - // Define this->sendmode $this->sendmode = ''; if ($this->sendcontext == 'emailing' && !empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default') @@ -198,7 +207,7 @@ class CMailFile if (empty($msg)) { dol_syslog("CMailFile::CMailfile: Try to send an email with empty body"); - $msg = '.'; // Avoid empty message (with empty message conten show a multipart structure) + $msg = '.'; // Avoid empty message (with empty message content, you will see a multipart structure) } // Detect if message is HTML (use fast method) @@ -220,7 +229,7 @@ class CMailFile //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current // Replace relative /viewimage to absolute path - $msg = preg_replace('/src="'.preg_quote(DOL_URL_ROOT, '/').'\/viewimage\.php/ims', 'src="'.$urlwithroot.'/viewimage.php', $msg, -1, $nbrep); + $msg = preg_replace('/src="'.preg_quote(DOL_URL_ROOT, '/').'\/viewimage\.php/ims', 'src="'.$urlwithroot.'/viewimage.php', $msg, -1); if (!empty($conf->global->MAIN_MAIL_FORCE_CONTENT_TYPE_TO_HTML)) $this->msgishtml = 1; // To force to send everything with content type html. @@ -261,9 +270,6 @@ class CMailFile } } - // Add autocopy to (Note: Adding bcc for specific modules are also done from pages) - if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) $addr_bcc .= ($addr_bcc ? ', ' : '').$conf->global->MAIN_MAIL_AUTOCOPY_TO; - // We set all data according to choosed sending method. // We also set a value for ->msgid if ($this->sendmode == 'mail') @@ -323,7 +329,13 @@ class CMailFile $smtps = new SMTPs(); $smtps->setCharSet($conf->file->character_set_client); - $smtps->setSubject($this->encodetorfc2822($subject)); + // Encode subject if required. + $subjecttouse = $subject; + if (! ascii_check($subjecttouse)) { + $subjecttouse = $this->encodetorfc2822($subjecttouse); + } + + $smtps->setSubject($subjecttouse); $smtps->setTO($this->getValidAddress($to, 0, 1)); $smtps->setFrom($this->getValidAddress($from, 0, 1)); $smtps->setTrackId($trackid); @@ -342,6 +354,9 @@ class CMailFile $msg = $this->checkIfHTML($msg); } + // Replace . alone on a new line with .. to avoid to have SMTP interpret this as end of message + $msg = preg_replace('/(\r|\n)\.(\r|\n)/ims', '\1..\2', $msg); + if ($this->msgishtml) $smtps->setBodyContent($msg, 'html'); else $smtps->setBodyContent($msg, 'plain'); @@ -669,8 +684,14 @@ class CMailFile if (!empty($conf->global->MAIN_MAIL_DEBUG)) $this->dump_mail(); - if (!empty($additionnalparam)) $res = mail($dest, $this->encodetorfc2822($this->subject), $this->message, $this->headers, $additionnalparam); - else $res = mail($dest, $this->encodetorfc2822($this->subject), $this->message, $this->headers); + // Encode subject if required. + $subjecttouse = $this->subject; + if (! ascii_check($subjecttouse)) { + $subjecttouse = $this->encodetorfc2822($subjecttouse); + } + + if (!empty($additionnalparam)) $res = mail($dest, $subjecttouse, $this->message, $this->headers, $additionnalparam); + else $res = mail($dest, $subjecttouse, $this->message, $this->headers); if (!$res) { diff --git a/htdocs/core/class/canvas.class.php b/htdocs/core/class/canvas.class.php index cfdb09c527e..68f2e9b1ba8 100644 --- a/htdocs/core/class/canvas.class.php +++ b/htdocs/core/class/canvas.class.php @@ -176,6 +176,7 @@ class Canvas global $db, $conf, $langs, $user, $canvas; global $form, $formfile; + //var_dump($this->card.'-'.$action); include $this->template_dir.(!empty($this->card)?$this->card.'_':'').$this->_cleanaction($action).'.tpl.php'; // Include native PHP template } diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 9d08480246b..b0001a695b8 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -49,6 +49,10 @@ abstract class CommonDocGenerator */ protected $db; + /** + * @var Extrafields object + */ + public $extrafieldsCache; /** * Constructor @@ -532,14 +536,16 @@ abstract class CommonDocGenerator * * @param Object $line Object line * @param Translate $outputlangs Lang object to use for output + * @param int $linenumber The number of the line for the substitution of "object_line_pos" * @return array Return a substitution array */ - public function get_substitutionarray_lines($line, $outputlangs) + public function get_substitutionarray_lines($line, $outputlangs, $linenumber = 0) { // phpcs:enable global $conf; $resarray = array( + 'line_pos' => $linenumber, 'line_fulldesc'=>doc_getlinedesc($line, $outputlangs), 'line_product_ref'=>$line->product_ref, 'line_product_ref_fourn'=>$line->ref_fourn, // for supplier doc lines @@ -562,12 +568,12 @@ abstract class CommonDocGenerator 'line_price_ttc_locale'=>price($line->total_ttc, 0, $outputlangs), 'line_price_vat_locale'=>price($line->total_tva, 0, $outputlangs), // Dates - 'line_date_start'=>dol_print_date($line->date_start, 'day', 'tzuser'), - 'line_date_start_locale'=>dol_print_date($line->date_start, 'day', 'tzuser', $outputlangs), - 'line_date_start_rfc'=>dol_print_date($line->date_start, 'dayrfc', 'tzuser'), - 'line_date_end'=>dol_print_date($line->date_end, 'day', 'tzuser'), - 'line_date_end_locale'=>dol_print_date($line->date_end, 'day', 'tzuser', $outputlangs), - 'line_date_end_rfc'=>dol_print_date($line->date_end, 'dayrfc', 'tzuser'), + 'line_date_start'=>dol_print_date($line->date_start, 'day'), + 'line_date_start_locale'=>dol_print_date($line->date_start, 'day', 'tzserver', $outputlangs), + 'line_date_start_rfc'=>dol_print_date($line->date_start, 'dayrfc'), + 'line_date_end'=>dol_print_date($line->date_end, 'day'), + 'line_date_end_locale'=>dol_print_date($line->date_end, 'day', 'tzserver', $outputlangs), + 'line_date_end_rfc'=>dol_print_date($line->date_end, 'dayrfc'), 'line_multicurrency_code' => price2num($line->multicurrency_code), 'line_multicurrency_subprice' => price2num($line->multicurrency_subprice), @@ -603,21 +609,32 @@ abstract class CommonDocGenerator // Add the product supplier extrafields to the substitutions $extrafields->fetch_name_optionals_label("product_fournisseur_price"); $extralabels=$extrafields->attributes["product_fournisseur_price"]['label']; - $columns = ""; - foreach ($extralabels as $key => $value) - $columns .= "$key, "; - if ($columns != "") - { - $columns = substr($columns, 0, strlen($columns) - 2); - $resql = $this->db->query("SELECT $columns FROM " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields AS ex INNER JOIN " . MAIN_DB_PREFIX . "product_fournisseur_price AS f ON ex.fk_object = f.rowid WHERE f.ref_fourn = '" . $line->ref_supplier . "'"); - if ($this->db->num_rows($resql) > 0) { - $resql = $this->db->fetch_object($resql); + if (!empty($extralabels) && is_array($extralabels)) + { + $columns = ""; - foreach ($extralabels as $key => $value) - $resarray['line_product_supplier_'.$key] = $resql->{$key}; - } - } + foreach ($extralabels as $key) + { + $columns .= "$key, "; + } + + if ($columns != "") + { + $columns = substr($columns, 0, strlen($columns) - 2); + $resql = $this->db->query("SELECT $columns FROM " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields AS ex INNER JOIN " . MAIN_DB_PREFIX . "product_fournisseur_price AS f ON ex.fk_object = f.rowid WHERE f.ref_fourn = '" . $line->ref_supplier . "'"); + + if ($this->db->num_rows($resql) > 0) + { + $resql = $this->db->fetch_object($resql); + + foreach ($extralabels as $key) + { + $resarray['line_product_supplier_'.$key] = $resql->{$key}; + } + } + } + } } // Load product data optional fields to the line -> enables to use "line_options_{extrafield}" @@ -788,81 +805,84 @@ abstract class CommonDocGenerator { // phpcs:enable global $conf; - foreach($extrafields->attributes[$object->table_element]['label'] as $key=>$label) - { - if($extrafields->attributes[$object->table_element]['type'][$key] == 'price') + + if (is_array($extrafields->attributes[$object->table_element]['label'])) { + foreach($extrafields->attributes[$object->table_element]['label'] as $key=>$label) { - $object->array_options['options_'.$key] = price2num($object->array_options['options_'.$key]); - $object->array_options['options_'.$key.'_currency'] = price($object->array_options['options_'.$key], 0, $outputlangs, 0, 0, -1, $conf->currency); - //Add value to store price with currency - $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_currency' => $object->array_options['options_'.$key.'_currency'])); - } - elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'select') - { - $object->array_options['options_'.$key] = $extrafields->attributes[$object->table_element]['param'][$key]['options'][$object->array_options['options_'.$key]]; - } - elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'checkbox') { - $valArray=explode(',', $object->array_options['options_'.$key]); - $output=array(); - foreach($extrafields->attributes[$object->table_element]['param'][$key]['options'] as $keyopt=>$valopt) { - if (in_array($keyopt, $valArray)) { - $output[]=$valopt; + if($extrafields->attributes[$object->table_element]['type'][$key] == 'price') + { + $object->array_options['options_'.$key] = price2num($object->array_options['options_'.$key]); + $object->array_options['options_'.$key.'_currency'] = price($object->array_options['options_'.$key], 0, $outputlangs, 0, 0, -1, $conf->currency); + //Add value to store price with currency + $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_currency' => $object->array_options['options_'.$key.'_currency'])); + } + elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'select') + { + $object->array_options['options_'.$key] = $extrafields->attributes[$object->table_element]['param'][$key]['options'][$object->array_options['options_'.$key]]; + } + elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'checkbox') { + $valArray=explode(',', $object->array_options['options_'.$key]); + $output=array(); + foreach($extrafields->attributes[$object->table_element]['param'][$key]['options'] as $keyopt=>$valopt) { + if (in_array($keyopt, $valArray)) { + $output[]=$valopt; + } } + $object->array_options['options_'.$key] = implode(', ', $output); } - $object->array_options['options_'.$key] = implode(', ', $output); - } - elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'date') - { - if (strlen($object->array_options['options_'.$key])>0) + elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'date') { - $date = $object->array_options['options_'.$key]; - $object->array_options['options_'.$key] = dol_print_date($date, 'day'); // using company output language - $object->array_options['options_'.$key.'_locale'] = dol_print_date($date, 'day', 'tzserver', $outputlangs); // using output language format - $object->array_options['options_'.$key.'_rfc'] = dol_print_date($date, 'dayrfc'); // international format - } - else - { - $object->array_options['options_'.$key] = ''; - $object->array_options['options_'.$key.'_locale'] = ''; - $object->array_options['options_'.$key.'_rfc'] = ''; - } - $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale'])); - $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc'])); - } - elseif($extrafields->attributes[$object->table_element]['label'][$key] == 'datetime') - { - $datetime = $object->array_options['options_'.$key]; - $object->array_options['options_'.$key] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhour'):''); // using company output language - $object->array_options['options_'.$key.'_locale'] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhour', 'tzserver', $outputlangs):''); // using output language format - $object->array_options['options_'.$key.'_rfc'] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhourrfc'):''); // international format - $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale'])); - $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc'])); - } - elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'link') - { - $id = $object->array_options['options_'.$key]; - if ($id != "") - { - $param = $extrafields->attributes[$object->table_element]['param'][$key]; - $param_list=array_keys($param['options']); // $param_list='ObjectName:classPath' - $InfoFieldList = explode(":", $param_list[0]); - $classname=$InfoFieldList[0]; - $classpath=$InfoFieldList[1]; - if (! empty($classpath)) + if (strlen($object->array_options['options_'.$key])>0) { - dol_include_once($InfoFieldList[1]); - if ($classname && class_exists($classname)) + $date = $object->array_options['options_'.$key]; + $object->array_options['options_'.$key] = dol_print_date($date, 'day'); // using company output language + $object->array_options['options_'.$key.'_locale'] = dol_print_date($date, 'day', 'tzserver', $outputlangs); // using output language format + $object->array_options['options_'.$key.'_rfc'] = dol_print_date($date, 'dayrfc'); // international format + } + else + { + $object->array_options['options_'.$key] = ''; + $object->array_options['options_'.$key.'_locale'] = ''; + $object->array_options['options_'.$key.'_rfc'] = ''; + } + $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale'])); + $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc'])); + } + elseif($extrafields->attributes[$object->table_element]['label'][$key] == 'datetime') + { + $datetime = $object->array_options['options_'.$key]; + $object->array_options['options_'.$key] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhour'):''); // using company output language + $object->array_options['options_'.$key.'_locale'] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhour', 'tzserver', $outputlangs):''); // using output language format + $object->array_options['options_'.$key.'_rfc'] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key], 'dayhourrfc'):''); // international format + $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale'])); + $array_to_fill=array_merge($array_to_fill, array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc'])); + } + elseif($extrafields->attributes[$object->table_element]['type'][$key] == 'link') + { + $id = $object->array_options['options_'.$key]; + if ($id != "") + { + $param = $extrafields->attributes[$object->table_element]['param'][$key]; + $param_list=array_keys($param['options']); // $param_list='ObjectName:classPath' + $InfoFieldList = explode(":", $param_list[0]); + $classname=$InfoFieldList[0]; + $classpath=$InfoFieldList[1]; + if (! empty($classpath)) { - $tmpobject = new $classname($this->db); - $tmpobject->fetch($id); - // completely replace the id with the linked object name - $object->array_options['options_'.$key] = $tmpobject->name; + dol_include_once($InfoFieldList[1]); + if ($classname && class_exists($classname)) + { + $tmpobject = new $classname($this->db); + $tmpobject->fetch($id); + // completely replace the id with the linked object name + $object->array_options['options_'.$key] = $tmpobject->name; + } } } } - } - $array_to_fill = array_merge($array_to_fill, array($array_key.'_options_'.$key => $object->array_options['options_'.$key])); + $array_to_fill = array_merge($array_to_fill, array($array_key.'_options_'.$key => $object->array_options['options_'.$key])); + } } return $array_to_fill; @@ -1070,11 +1090,11 @@ abstract class CommonDocGenerator /** * print standard column content * - * @param PDF $pdf pdf object + * @param TCPDF $pdf pdf object * @param float $curY curent Y position * @param string $colKey the column key * @param string $columnText column text - * @return int new rank on success and -1 on error + * @return null */ public function printStdColumnContent($pdf, &$curY, $colKey, $columnText = '') { @@ -1092,11 +1112,293 @@ abstract class CommonDocGenerator if (empty($columnText)) return; $pdf->SetXY($this->getColumnContentXStart($colKey), $curY); // Set curent position $colDef = $this->cols[$colKey]; - $pdf->writeHTMLCell($this->getColumnContentWidth($colKey), 2, $this->getColumnContentXStart($colKey), $curY, $columnText, 0, 0, 0, true, $colDef['content']['align']); + // save curent cell padding + $curentCellPaddinds = $pdf->getCellPaddings(); + // set cell padding with column content definition + $pdf->setCellPaddings($colDef['content']['padding'][3], $colDef['content']['padding'][0], $colDef['content']['padding'][1], $colDef['content']['padding'][2]); + $pdf->writeHTMLCell($colDef['width'], 2, $colDef['xStartPos'], $curY, $columnText, 0, 1, 0, true, $colDef['content']['align']); + + // restore cell padding + $pdf->setCellPaddings($curentCellPaddinds['L'], $curentCellPaddinds['T'], $curentCellPaddinds['R'], $curentCellPaddinds['B']); } } + /** + * print description column content + * + * @param TCPDF $pdf pdf object + * @param float $curY curent Y position + * @param string $colKey the column key + * @param object $object CommonObject + * @param int $i the $object->lines array key + * @param Translate $outputlangs Output language + * @param int $hideref hide ref + * @param int $hidedesc hide desc + * @param int $issupplierline if object need supplier product + * @return null + */ + public function printColDescContent($pdf, &$curY, $colKey, $object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, $issupplierline = 0) + { + // load desc col params + $colDef = $this->cols[$colKey]; + // save curent cell padding + $curentCellPaddinds = $pdf->getCellPaddings(); + // set cell padding with column content definition + $pdf->setCellPaddings($colDef['content']['padding'][3], $colDef['content']['padding'][0], $colDef['content']['padding'][1], $colDef['content']['padding'][2]); + + // line description + pdf_writelinedesc($pdf, $object, $i, $outputlangs, $colDef['width'], 3, $colDef['xStartPos'], $curY, $hideref, $hidedesc, $issupplierline); + $posYAfterDescription = $pdf->GetY() - $colDef['content']['padding'][0]; + + // restore cell padding + $pdf->setCellPaddings($curentCellPaddinds['L'], $curentCellPaddinds['T'], $curentCellPaddinds['R'], $curentCellPaddinds['B']); + + // Display extrafield if needed + $params = array( + 'display' => 'list', + 'printableEnable' => array(3), + 'printableEnableNotEmpty' => array(4) + ); + $extrafieldDesc = $this->getExtrafieldsInHtml($object->lines[$i], $outputlangs, $params); + if(!empty($extrafieldDesc)){ + $this->printStdColumnContent($pdf, $posYAfterDescription, $colKey, $extrafieldDesc); + } + } + + /** + * get extrafield content for pdf writeHtmlCell compatibility + * usage for PDF line columns and object note block + * + * @param object $object common object + * @param string $extrafieldKey the extrafield key + * @return string + */ + public function getExtrafieldContent($object, $extrafieldKey) + { + global $hookmanager; + + if(empty($object->table_element)){ return; } + + $extrafieldsKeyPrefix = "options_"; + + // Cleanup extrafield key to remove prefix if present + $pos = strpos($extrafieldKey, $extrafieldsKeyPrefix); + if($pos===0){ + $extrafieldKey = substr($extrafieldKey, strlen($extrafieldsKeyPrefix)); + } + + $extrafieldOptionsKey = $extrafieldsKeyPrefix.$extrafieldKey; + + + // Load extrafiels if not allready does + if(empty($this->extrafieldsCache)){ $this->extrafieldsCache = new ExtraFields($this->db); } + if(empty($this->extrafieldsCache->attributes[$object->table_element])){ $this->extrafieldsCache->fetch_name_optionals_label($object->table_element); } + $extrafields = $this->extrafieldsCache; + + $extrafieldOutputContent = $extrafields->showOutputField($extrafieldKey, $object->array_options[$extrafieldOptionsKey], '', $object->table_element); + + // TODO : allow showOutputField to be pdf public friendly, ex: in a link to object, clean getNomUrl to remove link and images... like a getName methode ... + if($extrafields->attributes[$object->table_element]['type'][$extrafieldKey] == 'link'){ + // for lack of anything better we cleanup all html tags + $extrafieldOutputContent = dol_string_nohtmltag($extrafieldOutputContent); + } + + $parameters = array( + 'object' => $object, + 'extrafields' => $extrafields, + 'extrafieldKey' => $extrafieldKey, + 'extrafieldOutputContent' =>& $extrafieldOutputContent + ); + $reshook = $hookmanager->executeHooks('getPDFExtrafieldContent', $parameters, $this); // Note that $action and $object may have been modified by hook + if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + if ($reshook) + { + $extrafieldOutputContent = $hookmanager->resPrint; + } + + return $extrafieldOutputContent; + } + + + /** + * display extrafields columns content + * + * @param object $object line of common object + * @param Translate $outputlangs Output language + * @param array $params array of additionals parameters + * @return double max y value + */ + public function getExtrafieldsInHtml($object, $outputlangs, $params = array()) + { + global $hookmanager; + + if(empty($object->table_element)){ + return; + } + + // Load extrafiels if not allready does + if(empty($this->extrafieldsCache)){ $this->extrafieldsCache = new ExtraFields($this->db); } + if(empty($this->extrafieldsCache->attributes[$object->table_element])){ $this->extrafieldsCache->fetch_name_optionals_label($object->table_element); } + $extrafields = $this->extrafieldsCache; + + $defaultParams = array( + 'style' => '', + 'display' => 'auto', // auto, table, list + 'printableEnable' => array(1), + 'printableEnableNotEmpty' => array(2), + + 'table' => array( + 'maxItemsInRow' => 2, + 'cellspacing' => 0, + 'cellpadding' => 0, + 'border' => 0, + 'labelcolwidth' => '25%', + 'arrayOfLineBreakType' => array('text', 'html') + ), + + 'list' => array( + 'separator' => '
' + ), + + 'auto' => array( + 'list' => 0, // 0 for default + 'table' => 4 // if there more than x extrafield to display + ), + ); + + $params = $params + $defaultParams; + + + /** + * @var $extrafields ExtraFields + */ + + $html = ''; + $fields = array(); + + if (is_array($extrafields->attributes[$object->table_element]['label'])) { + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) + { + // Enable extrafield ? + $enabled = 0; + $disableOnEmpty = 0; + if(!empty($extrafields->attributes[$object->table_element]['printable'][$key])) { + $printable = intval($extrafields->attributes[$object->table_element]['printable'][$key]); + if(in_array($printable, $params['printableEnable']) || in_array($printable, $params['printableEnableNotEmpty']) ) { + $enabled = 1; + } + + if (in_array($printable, $params['printableEnableNotEmpty'])) { + $disableOnEmpty = 1; + } + } + + if(empty($enabled)){ + continue; + } + + $field = new stdClass(); + $field->rank = intval($extrafields->attributes[$object->table_element]['pos'][$key]); + $field->content = $this->getExtrafieldContent($object, $key); + $field->label = $outputlangs->transnoentities($label); + $field->type = $extrafields->attributes[$object->table_element]['type'][$key]; + + // dont display if empty + if($disableOnEmpty && empty($field->content)) { + continue; + } + + $fields[] = $field; + } + } + + if(!empty($fields)) + { + // Sort extrafields by rank + uasort($fields, function ($a, $b) { + return ($a->rank > $b->rank) ? -1 : 1; + }); + + // define some HTML content with style + $html.= !empty($params['style'])?'':''; + + // auto select display format + if($params['display'] == 'auto') { + $lastNnumbItems = 0; + foreach ($params['auto'] as $display => $numbItems){ + if($lastNnumbItems <= $numbItems && count($fields) > $numbItems){ + $lastNnumbItems = $numbItems; + $params['display'] = $display; + } + } + } + + if($params['display'] == 'list') { + // Display in list format + $i=0; + foreach ($fields as $field) { + $html .= !empty($i)?$params['list']['separator']:''; + $html .= '' . $field->label . ' : '; + $html .= $field->content; + $i++; + } + } + elseif($params['display'] == 'table') { + // Display in table format + $html .= '
'; - print $langs->trans("Category") . ': ' . $formother->select_categories(Categorie::TYPE_PRODUCT, $selected_cat, 'search_categ', true); + print $langs->trans("Category").': '.$formother->select_categories(Categorie::TYPE_PRODUCT, $selected_cat, 'search_categ', true); print ' '; - print $langs->trans("SubCats") . '? '; + print $langs->trans("SubCats").'? '; print ''; // type filter (produit/service) print ' '; - print $langs->trans("Type"). ': '; - $form->select_type_of_lines(isset($selected_type)?$selected_type:-1, 'search_type', 1, 1, 1); + print $langs->trans("Type").': '; + $form->select_type_of_lines(isset($selected_type) ? $selected_type : -1, 'search_type', 1, 1, 1); //select thirdparty print '
'; - print $langs->trans("ThirdParty") . ': ' . $form->select_thirdparty_list($selected_soc, 'search_soc', '', 1); + print $langs->trans("ThirdParty").': '.$form->select_thirdparty_list($selected_soc, 'search_soc', '', 1); print '
'; @@ -389,16 +391,16 @@ if ($modecompta == 'CREANCES-DETTES') print "
"; - $fullname=$name[$key]; + $fullname = $name[$key]; if ($key > 0) { - $linkname=''.img_object($langs->trans("ShowProduct"), $type[$key]==0?'product':'service').' '.$fullname.''; + $linkname = ''.img_object($langs->trans("ShowProduct"), $type[$key] == 0 ? 'product' : 'service').' '.$fullname.''; } else { - $linkname=$langs->trans("PaymentsNotLinkedToProduct"); + $linkname = $langs->trans("PaymentsNotLinkedToProduct"); } print $linkname; print "".dol_print_date(dol_mktime(12,0,0,$mois,1,2000),"%B")."
'.$langs->trans("BankAccount").''; - $form->select_comptes($_POST["accountid"], "accountid", 0, "courant=1", 1); // Affiche liste des comptes courant + $form->select_comptes(GETPOST("accountid", 'int'), "accountid", 0, "courant=1", 2); // List of bank account available print '
'; - print $formcompany->select_civility(GETPOSTISSET("civility_code") ?GETPOST("civility_code", 'alpha') : $object->civility_code, 'civility_code'); + print $formcompany->select_civility(GETPOSTISSET("civility_code") ? GETPOST("civility_code", 'alpha') : $object->civility_code, 'civility_code'); print '
/ '; - print $formcompany->select_ziptown((GETPOST("zipcode", 'alpha') ?GETPOST("zipcode", 'alpha') : $object->zip), 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6).' '; - print $formcompany->select_ziptown((GETPOST("town", 'alpha') ?GETPOST("town", 'alpha') : $object->town), 'town', array('zipcode', 'selectcountry_id', 'state_id')); + print $formcompany->select_ziptown((GETPOST("zipcode", 'alpha') ? GETPOST("zipcode", 'alpha') : $object->zip), 'zipcode', array('town', 'selectcountry_id', 'state_id'), 6).' '; + print $formcompany->select_ziptown((GETPOST("town", 'alpha') ? GETPOST("town", 'alpha') : $object->town), 'town', array('zipcode', 'selectcountry_id', 'state_id')); print '
'; - print $form->select_country((GETPOST("country_id", 'alpha') ?GETPOST("country_id", 'alpha') : $object->country_id), 'country_id'); + print $form->select_country((GETPOST("country_id", 'alpha') ? GETPOST("country_id", 'alpha') : $object->country_id), 'country_id'); if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); print '
'.img_picto('', 'object_phoning').' '.$form->editfieldkey('PhonePro', 'phone_pro', '', $object, 0).'
'.img_picto('', 'object_phoning').' '.$form->editfieldkey('PhonePerso', 'phone_perso', '', $object, 0).'
'.img_picto('', 'object_phoning_mobile').' '.$form->editfieldkey('PhoneMobile', 'phone_mobile', '', $object, 0).'
'.img_picto('', 'object_phoning_fax').' '.$form->editfieldkey('Fax', 'fax', '', $object, 0).'
'.img_picto('', 'object_email').' '.$form->editfieldkey('EMail', 'email', '', $object, 0, 'string', '').'
'.$form->selectyesno('no_email', (GETPOSTISSET("no_email") ?GETPOST("no_email", 'alpha') : $noemail), 1).''.$form->selectyesno('no_email', (GETPOSTISSET("no_email") ? GETPOST("no_email", 'alpha') : $noemail), 1).'
'.dol_print_date($db->jdate($obj->tms), 'dayhour').''.$staticcontrat->LibStatut($obj->statut,2).''.($obj->nb_initial > 0 ? $obj->nb_initial.$staticcontratligne->LibStatut(0, 3) : '').''.($obj->nb_running > 0 ? $obj->nb_running.$staticcontratligne->LibStatut(4, 3, 0) : '').''.($obj->nb_expired > 0 ? $obj->nb_expired.$staticcontratligne->LibStatut(4, 3, 1) : '').''.($obj->nb_closed > 0 ? $obj->nb_closed.$staticcontratligne->LibStatut(5, 3) : '').''.($obj->nb_initial > 0 ? ''.$obj->nb_initial.''.$staticcontratligne->LibStatut(0, 3, -1, 'class="paddingleft"') : '').''.($obj->nb_running > 0 ? ''.$obj->nb_running.''.$staticcontratligne->LibStatut(4, 3, 0, 'class="marginleft"') : '').''.($obj->nb_expired > 0 ? ''.$obj->nb_expired.''.$staticcontratligne->LibStatut(4, 3, 1, 'class="paddingleft"') : '').''.($obj->nb_closed > 0 ? ''.$obj->nb_closed.''.$staticcontratligne->LibStatut(5, 3, -1, 'class="paddingleft"') : '').'
'.dol_print_date($db->jdate($obj->date_contrat), 'day', 'tzuser').''.dol_print_date($db->jdate($obj->date_contrat), 'day', 'tzserver').' getLibStatut(7); ?>'.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink'); ?>">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?>
'; + + $html .= ""; + $itemsInRow = 0; + $maxItemsInRow = $params['table']['maxItemsInRow']; + foreach ($fields as $field) { + //$html.= !empty($html)?'
':''; + if ($itemsInRow >= $maxItemsInRow) { + // start a new line + $html .= ""; + $itemsInRow = 0; + } + + // for some type we need line break + if (in_array($field->type, $params['table']['arrayOfLineBreakType'])) { + if ($itemsInRow > 0) { + // close table row and empty cols + for ($i = $itemsInRow; $i <= $maxItemsInRow; $i++) { + $html .= ""; + } + $html .= ""; + + // start a new line + $html .= ""; + } + + $itemsInRow = $maxItemsInRow; + $html .= '"; + } else { + $itemsInRow++; + $html .= '"; + + + $html .= '"; + } + } + $html .= ""; + + $html .= '
'; + $html .= '' . $field->label . ' : '; + $html .= $field->content; + $html .= "'; + $html .= '' . $field->label . ' :'; + $html .= "'; + $html .= $field->content; + $html .= "
'; + } + } + + return $html; + } + + /** * get column status from column key * @@ -1114,7 +1416,7 @@ abstract class CommonDocGenerator /** * Print standard column content * - * @param PDF $pdf Pdf object + * @param TCPDI $pdf Pdf object * @param float $tab_top Tab top position * @param float $tab_height Default tab height * @param Translate $outputlangs Output language @@ -1150,21 +1452,123 @@ abstract class CommonDocGenerator } if (empty($hidetop)) { - $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0]); - $textWidth = $colDef['width'] - $colDef['title']['padding'][3] - $colDef['title']['padding'][1]; - $pdf->MultiCell($textWidth, 2, $colDef['title']['label'], '', $colDef['title']['align']); + // save curent cell padding + $curentCellPaddinds = $pdf->getCellPaddings(); global $outputlangsbis; if (is_object($outputlangsbis)) { - $pdf->SetXY($colDef['xStartPos'] + $colDef['title']['padding'][3], $tab_top + $colDef['title']['padding'][0] + 4); + // set cell padding with column title definition + $pdf->setCellPaddings($colDef['title']['padding'][3], $colDef['title']['padding'][0], $colDef['title']['padding'][1], 0.5); + } + else{ + // set cell padding with column title definition + $pdf->setCellPaddings($colDef['title']['padding'][3], $colDef['title']['padding'][0], $colDef['title']['padding'][1], $colDef['title']['padding'][2]); + } + + $pdf->SetXY($colDef['xStartPos'], $tab_top); + $textWidth = $colDef['width']; + $pdf->MultiCell($textWidth, 2, $colDef['title']['label'], '', $colDef['title']['align']); + + + if (is_object($outputlangsbis)) { + $pdf->setCellPaddings($colDef['title']['padding'][3], 0, $colDef['title']['padding'][1], $colDef['title']['padding'][2]); + $pdf->SetXY($colDef['xStartPos'], $pdf->GetY()); $textbis = $outputlangsbis->transnoentities($colDef['title']['textkey']); $pdf->MultiCell($textWidth, 2, $textbis, '', $colDef['title']['align']); } - $this->tabTitleHeight = max($pdf->GetY() - $tab_top + $colDef['title']['padding'][2], $this->tabTitleHeight); + $this->tabTitleHeight = max($pdf->GetY() - $tab_top, $this->tabTitleHeight); + + // restore cell padding + $pdf->setCellPaddings($curentCellPaddinds['L'], $curentCellPaddinds['T'], $curentCellPaddinds['R'], $curentCellPaddinds['B']); } } } return $this->tabTitleHeight; } + + + + /** + * Define Array Column Field for extrafields + * + * @param object $object common object det + * @param Translate $outputlangs langs + * @param int $hidedetails Do not show line details + * @return null + */ + public function defineColumnExtrafield($object, $outputlangs, $hidedetails = 0) + { + global $conf; + + if(!empty($hidedetails)){ + return; + } + + if(empty($object->table_element)){ + return; + } + + // Load extrafiels if not allready does + if(empty($this->extrafieldsCache)){ $this->extrafieldsCache = new ExtraFields($this->db); } + if(empty($this->extrafieldsCache->attributes[$object->table_element])){ $this->extrafieldsCache->fetch_name_optionals_label($object->table_element); } + $extrafields = $this->extrafieldsCache; + + + if (!empty($extrafields->attributes[$object->table_element]) && is_array($extrafields->attributes[$object->table_element]['label'])) { + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) + { + // Dont display separator yet even is set to be displayed (not compatible yet) + if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') + { + continue; + } + + // Enable extrafield ? + $enabled = 0; + if(!empty($extrafields->attributes[$object->table_element]['printable'][$key])) { + $printable = intval($extrafields->attributes[$object->table_element]['printable'][$key]); + if($printable === 1 || $printable === 2) { + $enabled = 1; + } + // Note : if $printable === 3 or 4 so, it's displayed after line description not in cols + } + + if (!$enabled){ continue; } // don't wast resourses if we don't need them... + + // Load language if required + if (!empty($extrafields->attributes[$object->table_element]['langfile'][$key])) $outputlangs->load($extrafields->attributes[$object->table_element]['langfile'][$key]); + + // TODO : add more extrafield customisation capacities for PDF like width, rank... + + // set column definition + $def = array( + 'rank' => intval($extrafields->attributes[$object->table_element]['pos'][$key]), + 'width' => 25, // in mm + 'status' => boolval($enabled), + 'title' => array( + 'label' => $outputlangs->transnoentities($label) + ), + 'content' => array( + 'align' => 'C' + ), + 'border-left' => true, // add left line separator + ); + + $alignTypeRight = array('double', 'int', 'price'); + if(in_array($extrafields->attributes[$object->table_element]['type'][$key], $alignTypeRight)){ + $def['content']['align'] = 'R'; + } + + $alignTypeLeft = array('text', 'html'); + if(in_array($extrafields->attributes[$object->table_element]['type'][$key], $alignTypeLeft)){ + $def['content']['align'] = 'L'; + } + + + // for extrafields we use rank of extrafield to place it on PDF + $this->insertNewColumnDef("options_".$key, $def); + } + } + } } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 39bdc678fc4..da30b714db0 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -337,7 +337,7 @@ abstract class CommonObject /** * @deprecated - * @see $note_public + * @see $note_private */ public $note; @@ -491,6 +491,7 @@ abstract class CommonObject return $this->error.(is_array($this->errors) ? (($this->error != '' ? ', ' : '').join(', ', $this->errors)) : ''); } + /** * Return customer ref for screen output. * @@ -559,6 +560,28 @@ abstract class CommonObject return dol_trunc($ret, $maxlen); } + /** + * Return clicable link of object (with eventually picto) + * + * @param string $option Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link) + * @return string HTML Code for Kanban thumb. + */ + public function getKanbanView($option = '') + { + $return = '
'; + $return .= '
'; + $return .= ''; + $return .= ''; // Can be image + $return .= ''; + $return .= '
'; + $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= '
'; + $return .= '
'; + $return .= '
'; + + return $return; + } + /** * Return full address of contact * @@ -1080,7 +1103,7 @@ abstract class CommonObject * Get array of all contacts for an object * * @param int $status Status of links to get (-1=all) - * @param string $source Source of contact: external or thirdparty (llx_socpeople) or internal (llx_user) + * @param string $source Source of contact: 'external' or 'thirdparty' (llx_socpeople) or 'internal' (llx_user) * @param int $list 0:Return array contains all properties, 1:Return array contains just id * @param string $code Filter on this code of contact type ('SHIPPING', 'BILLING', ...) * @return array|int Array of contacts, -1 if error @@ -1242,14 +1265,15 @@ abstract class CommonObject /** * Return array with list of possible values for type of contacts * - * @param string $source 'internal', 'external' or 'all' - * @param int $option 0=Return array id->label, 1=Return array code->label - * @param int $activeonly 0=all status of contact, 1=only the active - * @param string $code Type of contact (Example: 'CUSTOMER', 'SERVICE') - * @param string $element Filter Element Type - * @return array Array list of type of contacts (id->label if option=0, code->label if option=1) + * @param string $source 'internal', 'external' or 'all' + * @param int $option 0=Return array id->label, 1=Return array code->label + * @param int $activeonly 0=all status of contact, 1=only the active + * @param string $code Type of contact (Example: 'CUSTOMER', 'SERVICE') + * @param string $element Filter on 1 element type + * @param string $excludeelement Exclude 1 element type. Example: 'agenda' + * @return array Array list of type of contacts (id->label if option=0, code->label if option=1) */ - public function listeTypeContacts($source = 'internal', $option = 0, $activeonly = 0, $code = '', $element = '') + public function listeTypeContacts($source = 'internal', $option = 0, $activeonly = 0, $code = '', $element = '', $excludeelement = '') { // phpcs:enable global $langs, $conf; @@ -1260,8 +1284,12 @@ abstract class CommonObject $sql .= " FROM ".MAIN_DB_PREFIX."c_type_contact as tc"; $sqlWhere = array(); - if (!empty($element)) + if (!empty($element)) { $sqlWhere[] = " tc.element='".$this->db->escape($element)."'"; + } + if (!empty($excludeelement)) { + $sqlWhere[] = " tc.element <> '".$this->db->escape($excludeelement)."'"; + } if ($activeonly == 1) $sqlWhere[] = " tc.active=1"; // only the active types @@ -1278,24 +1306,25 @@ abstract class CommonObject $sql .= $this->db->order('tc.element, tc.position', 'ASC'); - dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG); + dol_syslog(__METHOD__, LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); if ($num > 0) { while ($obj = $this->db->fetch_object($resql)) { + $modulename = $obj->element; if (strpos($obj->element, 'project') !== false) { - $element = 'projet'; + $modulename = 'projet'; } elseif ($obj->element == 'contrat') { $element = 'contract'; + } elseif ($obj->element == 'action') { + $modulename = 'agenda'; } elseif (strpos($obj->element, 'supplier') !== false && $obj->element != 'supplier_proposal') { - $element = 'fournisseur'; + $modulename = 'fournisseur'; } elseif (strpos($obj->element, 'supplier') !== false && $obj->element != 'supplier_proposal') { - $element = 'fournisseur'; - } else { - $element = $obj->element; + $modulename = 'fournisseur'; } - if ($conf->{$element}->enabled) { + if ($conf->{$modulename}->enabled) { $libelle_element = $langs->trans('ContactDefault_'.$obj->element); $transkey = "TypeContact_".$this->element."_".$source."_".$obj->code; $libelle_type = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->libelle); @@ -1701,7 +1730,7 @@ abstract class CommonObject $sql .= " WHERE ".$id_field." = ".$id; - dol_syslog(get_class($this)."::".__FUNCTION__."", LOG_DEBUG); + dol_syslog(__METHOD__."", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { @@ -1766,19 +1795,22 @@ abstract class CommonObject if ($user->socid > 0) $socid = $user->socid; // this->ismultientitymanaged contains - // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe - $alias = 's'; - if ($this->element == 'societe') $alias = 'te'; + // 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table + $aliastablesociete = 's'; + if ($this->element == 'societe') $aliastablesociete = 'te'; // te as table_element $sql = "SELECT MAX(te.".$fieldid.")"; $sql .= " FROM ".(empty($nodbprefix) ?MAIN_DB_PREFIX:'').$this->table_element." as te"; if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { $sql .= ",".MAIN_DB_PREFIX."usergroup_user as ug"; } - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2) $sql .= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to entity + if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) { + $tmparray = explode('@', $this->ismultientitymanaged); + $sql .= ", ".MAIN_DB_PREFIX.$tmparray[1]." as ".($tmparray[1] == 'societe' ? 's' : 'parenttable'); // If we need to link to this table to limit select to entity + } elseif ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to socid elseif ($this->restrictiononfksoc == 2 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON te.fk_soc = s.rowid"; // If we need to link to societe to limit select to socid - if ($this->restrictiononfksoc && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$alias.".rowid = sc.fk_soc"; + if ($this->restrictiononfksoc && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$aliastablesociete.".rowid = sc.fk_soc"; $sql .= " WHERE te.".$fieldid." < '".$this->db->escape($this->ref)."'"; // ->ref must always be defined (set to id if field does not exists) if ($this->restrictiononfksoc == 1 && !$user->rights->societe->client->voir && !$socid) $sql .= " AND sc.fk_user = ".$user->id; if ($this->restrictiononfksoc == 2 && !$user->rights->societe->client->voir && !$socid) $sql .= " AND (sc.fk_user = ".$user->id.' OR te.fk_soc IS NULL)'; @@ -1787,7 +1819,10 @@ abstract class CommonObject if (!preg_match('/^\s*AND/i', $filter)) $sql .= " AND "; // For backward compatibility $sql .= $filter; } - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2) $sql .= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to entity + if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) { + $tmparray = explode('@', $this->ismultientitymanaged); + $sql .= ' AND te.'.$tmparray[0].' = '.($tmparray[1] == 'societe' ? 's' : 'parenttable').'.rowid'; // If we need to link to this table to limit select to entity + } elseif ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to socid if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) { if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { @@ -1801,6 +1836,10 @@ abstract class CommonObject $sql .= ' AND te.entity IN ('.getEntity($this->element).')'; } } + if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged) && $this->element != 'societe') { + $tmparray = explode('@', $this->ismultientitymanaged); + $sql .= ' AND parenttable.entity IN ('.getEntity($tmparray[1]).')'; + } if ($this->restrictiononfksoc == 1 && $socid && $this->element != 'societe') $sql .= ' AND te.fk_soc = '.$socid; if ($this->restrictiononfksoc == 2 && $socid && $this->element != 'societe') $sql .= ' AND (te.fk_soc = '.$socid.' OR te.fk_soc IS NULL)'; if ($this->restrictiononfksoc && $socid && $this->element == 'societe') $sql .= ' AND te.rowid = '.$socid; @@ -1821,10 +1860,10 @@ abstract class CommonObject if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { $sql .= ",".MAIN_DB_PREFIX."usergroup_user as ug"; } - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2) $sql .= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to entity + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 'fk_soc@societe') $sql .= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to entity elseif ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to socid elseif ($this->restrictiononfksoc == 2 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON te.fk_soc = s.rowid"; // If we need to link to societe to limit select to socid - if ($this->restrictiononfksoc && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$alias.".rowid = sc.fk_soc"; + if ($this->restrictiononfksoc && !$user->rights->societe->client->voir && !$socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$aliastablesociete.".rowid = sc.fk_soc"; $sql .= " WHERE te.".$fieldid." > '".$this->db->escape($this->ref)."'"; // ->ref must always be defined (set to id if field does not exists) if ($this->restrictiononfksoc == 1 && !$user->rights->societe->client->voir && !$socid) $sql .= " AND sc.fk_user = ".$user->id; if ($this->restrictiononfksoc == 2 && !$user->rights->societe->client->voir && !$socid) $sql .= " AND (sc.fk_user = ".$user->id.' OR te.fk_soc IS NULL)'; @@ -1833,7 +1872,7 @@ abstract class CommonObject if (!preg_match('/^\s*AND/i', $filter)) $sql .= " AND "; // For backward compatibility $sql .= $filter; } - if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 2) $sql .= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to entity + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 'fk_soc@societe') $sql .= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to entity elseif ($this->restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) $sql .= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to socid if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) { if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { @@ -3330,6 +3369,9 @@ abstract class CommonObject elseif ($objecttype == 'subscription') { $classpath = 'adherents/class'; $module = 'adherent'; } + elseif ($objecttype == 'contact') { + $module = 'societe'; + } // Set classfile $classfile = strtolower($subelement); $classname = ucfirst($subelement); @@ -3352,6 +3394,9 @@ abstract class CommonObject elseif ($objecttype == 'subscription') { $classfile = 'subscription'; $classname = 'Subscription'; } + elseif ($objecttype == 'project' || $objecttype == 'projet') { + $classpath = 'projet/class'; $classfile = 'project'; $classname = 'Project'; + } // Here $module, $classfile and $classname are set if ($conf->$module->enabled && (($element != $this->element) || $alsosametype)) @@ -4734,6 +4779,7 @@ abstract class CommonObject { if (!dol_is_file($srctemplatepath)) { + dol_syslog("Failed to locate template file ".$srctemplatepath, LOG_WARNING); $this->error = 'ErrorGenerationAskedForOdtTemplateWithSrcFileNotFound'; return -1; } @@ -4934,7 +4980,7 @@ abstract class CommonObject global $conf, $_POST; // If param here has been posted, we use this value first. - if (isset($_POST[$fieldname])) return GETPOST($fieldname, 2); + if (GETPOSTISSET($fieldname)) return GETPOST($fieldname, 'alphanohtml', 3); if (isset($alternatevalue)) return $alternatevalue; @@ -5374,7 +5420,7 @@ abstract class CommonObject // Add field of attribute if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] != 'separate') // Only for other type than separator) { - if ($new_array_options[$key] != '') + if ($new_array_options[$key] != '' || $new_array_options[$key] == '0') { $sql .= ",'".$this->db->escape($new_array_options[$key])."'"; } @@ -5476,7 +5522,7 @@ abstract class CommonObject $this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel); return -1; } - elseif ($value == '') + elseif ($value === '') { $this->array_options["options_".$key] = null; } @@ -5489,7 +5535,7 @@ abstract class CommonObject $this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel); return -1; } - elseif ($value == '') + elseif ($value === '') { $this->array_options["options_".$key] = null; } @@ -5547,7 +5593,7 @@ abstract class CommonObject if ($error) { - dol_syslog(get_class($this)."::".__METHOD__.$this->error, LOG_ERR); + dol_syslog(__METHOD__.$this->error, LOG_ERR); $this->db->rollback(); return -1; } @@ -5585,7 +5631,7 @@ abstract class CommonObject $form = new Form($this->db); } - if (! empty($this->fields)) { + if (!empty($this->fields)) { $val = $this->fields[$key]; } @@ -6614,7 +6660,12 @@ abstract class CommonObject if (is_array($params) && array_key_exists('onlykey', $params) && $key != $params['onlykey']) continue; // @todo Add test also on 'enabled' (different than 'list' that is 'visibility') - //$enabled = 1; + $enabled = 1; + if ($enabled && isset($extrafields->attributes[$this->table_element]['enabled'][$key])) + { + $enabled = dol_eval($extrafields->attributes[$this->table_element]['enabled'][$key], 1); + } + if (empty($enabled)) continue; $visibility = 1; if ($visibility && isset($extrafields->attributes[$this->table_element]['list'][$key])) @@ -6747,7 +6798,8 @@ abstract class CommonObject if ($mode != 'view' && !empty($extrafields->attributes[$this->table_element]['required'][$key])) $out .= ' *'; } else { if ($mode != 'view' && !empty($extrafields->attributes[$this->table_element]['required'][$key])) $out .= ' fieldrequired'; - $out .= '">'; + $out .= '"'; + $out .= '>'; if (!empty($extrafields->attributes[$this->table_element]['help'][$key])) $out .= $form->textwithpicto($labeltoshow, $extrafields->attributes[$this->table_element]['help'][$key]); else $out .= $labeltoshow; } diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 4136cef1be5..c715f53194a 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -289,6 +289,8 @@ class Conf { $rootfordata .= '/'.$this->entity; } + // Set standard temporary folder name or global override + $rootfortemp = empty($this->global->MAIN_TEMP_DIR) ? $rootfordata : $this->global->MAIN_TEMP_DIR; // Define default dir_output and dir_temp for directories of modules foreach ($this->modules as $module) @@ -296,10 +298,10 @@ class Conf //var_dump($module); // For multicompany sharings $this->$module->multidir_output = array($this->entity => $rootfordata."/".$module); - $this->$module->multidir_temp = array($this->entity => $rootfordata."/".$module."/temp"); + $this->$module->multidir_temp = array($this->entity => $rootfortemp."/".$module."/temp"); // For backward compatibility $this->$module->dir_output = $rootfordata."/".$module; - $this->$module->dir_temp = $rootfordata."/".$module."/temp"; + $this->$module->dir_temp = $rootfortemp."/".$module."/temp"; } // External modules storage @@ -311,56 +313,59 @@ class Conf { foreach ($dirs as $type => $name) // $type is 'output' or 'temp' { - $subdir = ($type == 'temp' ? '/temp' : ''); - // For multicompany sharings - $varname = 'multidir_'.$type; - $this->$module->$varname = array($this->entity => $rootfordata."/".$name.$subdir); - // For backward compatibility - $varname = 'dir_'.$type; - $this->$module->$varname = $rootfordata."/".$name.$subdir; + $multidirname = 'multidir_'.$type; + $dirname = 'dir_'.$type; + + if ($type != 'temp') + { + // For multicompany sharings + $this->$module->$multidirname = array($this->entity => $rootfordata."/".$name); + + // For backward compatibility + $this->$module->$dirname = $rootfordata."/".$name; + } + else + { + // For multicompany sharings + $this->$module->$multidirname = array($this->entity => $rootfortemp."/".$name."/temp"); + + // For backward compatibility + $this->$module->$dirname = $rootfortemp."/".$name."/temp"; + } } } } } // For mycompany storage - $this->mycompany->multidir_output = array($this->entity => $rootfordata."/mycompany"); - $this->mycompany->multidir_temp = array($this->entity => $rootfordata."/mycompany/temp"); - // For backward compatibility $this->mycompany->dir_output = $rootfordata."/mycompany"; - $this->mycompany->dir_temp = $rootfordata."/mycompany/temp"; + $this->mycompany->dir_temp = $rootfortemp."/mycompany/temp"; // For admin storage $this->admin->dir_output = $rootfordata.'/admin'; - $this->admin->dir_temp = $rootfordata.'/admin/temp'; + $this->admin->dir_temp = $rootfortemp.'/admin/temp'; // For user storage $this->user->multidir_output = array($this->entity => $rootfordata."/users"); - $this->user->multidir_temp = array($this->entity => $rootfordata."/users/temp"); + $this->user->multidir_temp = array($this->entity => $rootfortemp."/users/temp"); // For backward compatibility $this->user->dir_output = $rootforuser."/users"; - $this->user->dir_temp = $rootforuser."/users/temp"; + $this->user->dir_temp = $rootfortemp."/users/temp"; // For usergroup storage $this->usergroup->dir_output = $rootforuser."/usergroups"; - $this->usergroup->dir_temp = $rootforuser."/usergroups/temp"; + $this->usergroup->dir_temp = $rootfortemp."/usergroups/temp"; // For proposal storage $this->propal->multidir_output = array($this->entity => $rootfordata."/propale"); - $this->propal->multidir_temp = array($this->entity => $rootfordata."/propale/temp"); + $this->propal->multidir_temp = array($this->entity => $rootfortemp."/propale/temp"); // For backward compatibility $this->propal->dir_output = $rootfordata."/propale"; - $this->propal->dir_temp = $rootfordata."/propale/temp"; - - // For bank storage - $this->bank->multidir_output = array($this->entity => $rootfordata."/bank"); - $this->bank->multidir_temp = array($this->entity => $rootfordata."/bank/temp"); - $this->bank->dir_output = $rootfordata."/bank"; - $this->bank->dir_temp = $rootfordata."/bank/temp"; + $this->propal->dir_temp = $rootfortemp."/propale/temp"; // For medias storage $this->medias->multidir_output = array($this->entity => $rootfordata."/medias"); - $this->medias->multidir_temp = array($this->entity => $rootfordata."/medias/temp"); + $this->medias->multidir_temp = array($this->entity => $rootfortemp."/medias/temp"); // Exception: Some dir are not the name of module. So we keep exception here for backward compatibility. @@ -370,77 +375,85 @@ class Conf $this->livraison_bon->enabled = (!empty($this->global->MAIN_SUBMODULE_LIVRAISON) ? $this->global->MAIN_SUBMODULE_LIVRAISON : 0); // Module fournisseur - // TODO To split into module supplier_invoice and supplier_order if (!empty($this->fournisseur)) { $this->fournisseur->commande = new stdClass(); $this->fournisseur->commande->multidir_output = array($this->entity => $rootfordata."/fournisseur/commande"); - $this->fournisseur->commande->multidir_temp = array($this->entity => $rootfordata."/fournisseur/commande/temp"); + $this->fournisseur->commande->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/commande/temp"); $this->fournisseur->commande->dir_output = $rootfordata."/fournisseur/commande"; // For backward compatibility - $this->fournisseur->commande->dir_temp = $rootfordata."/fournisseur/commande/temp"; // For backward compatibility + $this->fournisseur->commande->dir_temp = $rootfortemp."/fournisseur/commande/temp"; // For backward compatibility + $this->fournisseur->facture = new stdClass(); $this->fournisseur->facture->multidir_output = array($this->entity => $rootfordata."/fournisseur/facture"); - $this->fournisseur->facture->multidir_temp = array($this->entity => $rootfordata."/fournisseur/facture/temp"); + $this->fournisseur->facture->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/facture/temp"); $this->fournisseur->facture->dir_output = $rootfordata."/fournisseur/facture"; // For backward compatibility - $this->fournisseur->facture->dir_temp = $rootfordata."/fournisseur/facture/temp"; // For backward compatibility + $this->fournisseur->facture->dir_temp = $rootfortemp."/fournisseur/facture/temp"; // For backward compatibility + + $this->supplierproposal = new stdClass(); + $this->supplierproposal->multidir_output = array($this->entity => $rootfordata."/supplier_proposal"); + $this->supplierproposal->multidir_temp = array($this->entity => $rootfortemp."/supplier_proposal/temp"); + $this->supplierproposal->dir_output = $rootfordata."/supplier_proposal"; // For backward compatibility + $this->supplierproposal->dir_temp = $rootfortemp."/supplier_proposal/temp"; // For backward compatibility $this->fournisseur->payment = new stdClass(); $this->fournisseur->payment->multidir_output = array($this->entity => $rootfordata."/fournisseur/payment"); - $this->fournisseur->payment->multidir_temp = array($this->entity => $rootfordata."/fournisseur/payment/temp"); + $this->fournisseur->payment->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/payment/temp"); $this->fournisseur->payment->dir_output = $rootfordata."/fournisseur/payment"; // For backward compatibility - $this->fournisseur->payment->dir_temp = $rootfordata."/fournisseur/payment/temp"; // For backward compatibility + $this->fournisseur->payment->dir_temp = $rootfortemp."/fournisseur/payment/temp"; // For backward compatibility - // To prepare split of module vendor(fournisseur) into vendor + supplier_order + supplier_invoice + supplierproposal - if (!empty($this->fournisseur->enabled)) // By default, if module supplier is on, we set new properties + // To prepare split of module fournisseur into fournisseur + supplier_order + supplier_invoice + if (!empty($this->fournisseur->enabled) && empty($this->global->MAIN_USE_NEW_SUPPLIERMOD)) // By default, if module supplier is on, we set new properties { if (empty($this->global->MAIN_USE_NEW_SUPPLIERMOD)) // This can be set to 1 once modules purchase order and supplier invoice exists { - $this->supplier_order = new stdClass(); - $this->supplier_order->enabled = 1; - $this->supplier_order->multidir_output = array($this->entity => $rootfordata."/fournisseur/commande"); - $this->supplier_order->multidir_temp = array($this->entity => $rootfordata."/fournisseur/commande/temp"); - $this->supplier_order->dir_output = $rootfordata."/fournisseur/commande"; // For backward compatibility - $this->supplier_order->dir_temp = $rootfordata."/fournisseur/commande/temp"; // For backward compatibility + $this->supplier_order = new stdClass(); + $this->supplier_order->enabled = 1; + $this->supplier_order->multidir_output = array($this->entity => $rootfordata."/fournisseur/commande"); + $this->supplier_order->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/commande/temp"); + $this->supplier_order->dir_output = $rootfordata."/fournisseur/commande"; // For backward compatibility + $this->supplier_order->dir_temp = $rootfortemp."/fournisseur/commande/temp"; // For backward compatibility } if (empty($this->global->MAIN_USE_NEW_SUPPLIERMOD)) // This can be set to 1 once modules purchase order and supplier invoice exists { $this->supplier_invoice = new stdClass(); - $this->supplier_invoice->enabled = 1; - $this->supplier_invoice->multidir_output = array($this->entity => $rootfordata."/fournisseur/facture"); - $this->supplier_invoice->multidir_temp = array($this->entity => $rootfordata."/fournisseur/facture/temp"); - $this->supplier_invoice->dir_output = $rootfordata."/fournisseur/facture"; // For backward compatibility - $this->supplier_invoice->dir_temp = $rootfordata."/fournisseur/facture/temp"; // For backward compatibility + $this->supplier_invoice->enabled = 1; + $this->supplier_invoice->multidir_output = array($this->entity => $rootfordata."/fournisseur/facture"); + $this->supplier_invoice->multidir_temp = array($this->entity => $rootfortemp."/fournisseur/facture/temp"); + $this->supplier_invoice->dir_output = $rootfordata."/fournisseur/facture"; // For backward compatibility + $this->supplier_invoice->dir_temp = $rootfortemp."/fournisseur/facture/temp"; // For backward compatibility } } } // Module product/service - $this->product->multidir_output = array($this->entity => $rootfordata."/produit"); - $this->product->multidir_temp = array($this->entity => $rootfordata."/produit/temp"); - $this->service->multidir_output = array($this->entity => $rootfordata."/produit"); - $this->service->multidir_temp = array($this->entity => $rootfordata."/produit/temp"); + $this->product->multidir_output = array($this->entity => $rootfordata."/produit"); + $this->product->multidir_temp = array($this->entity => $rootfortemp."/produit/temp"); + $this->service->multidir_output = array($this->entity => $rootfordata."/produit"); + $this->service->multidir_temp = array($this->entity => $rootfortemp."/produit/temp"); // For backward compatibility - $this->product->dir_output = $rootfordata."/produit"; - $this->product->dir_temp = $rootfordata."/produit/temp"; - $this->service->dir_output = $rootfordata."/produit"; - $this->service->dir_temp = $rootfordata."/produit/temp"; + $this->product->dir_output = $rootfordata."/produit"; + $this->product->dir_temp = $rootfortemp."/produit/temp"; + $this->service->dir_output = $rootfordata."/produit"; + $this->service->dir_temp = $rootfortemp."/produit/temp"; // Module productbatch $this->productbatch->multidir_output = array($this->entity => $rootfordata."/produitlot"); - $this->productbatch->multidir_temp = array($this->entity => $rootfordata."/produitlot/temp"); + $this->productbatch->multidir_temp = array($this->entity => $rootfortemp."/produitlot/temp"); // Module contrat $this->contrat->multidir_output = array($this->entity => $rootfordata."/contract"); - $this->contrat->multidir_temp = array($this->entity => $rootfordata."/contract/temp"); + $this->contrat->multidir_temp = array($this->entity => $rootfortemp."/contract/temp"); // For backward compatibility $this->contrat->dir_output = $rootfordata."/contract"; - $this->contrat->dir_temp = $rootfordata."/contract/temp"; + $this->contrat->dir_temp = $rootfortemp."/contract/temp"; // Module bank + $this->bank->multidir_output = array($this->entity => $rootfordata."/bank"); + $this->bank->multidir_temp = array($this->entity => $rootfortemp."/bank/temp"); + // For backward compatibility $this->bank->dir_output = $rootfordata."/bank"; - $this->bank->dir_temp = $rootfordata."/bank/temp"; - + $this->bank->dir_temp = $rootfortemp."/bank/temp"; // Set some default values //$this->global->MAIN_LIST_FILTER_ON_DAY=1; // On filter that show date, we must show input field for day before or after month @@ -514,7 +527,7 @@ class Conf if (empty($this->global->MAIN_THEME)) $this->global->MAIN_THEME = "eldy"; if (!empty($this->global->MAIN_FORCETHEME)) $this->global->MAIN_THEME = $this->global->MAIN_FORCETHEME; $this->theme = $this->global->MAIN_THEME; - $this->css = "/theme/".$this->theme."/style.css.php"; + $this->css = "/theme/".$this->theme."/style.css.php"; // conf->email_from = email pour envoi par dolibarr des mails automatiques $this->email_from = "robot@example.com"; @@ -668,10 +681,10 @@ class Conf $this->global->AGENDA_DEFAULT_FILTER_TYPE = '0'; // 'AC_NON_AUTO' does not exists when AGENDA_DEFAULT_FILTER_TYPE is not on. } - if (!isset($this->global->MAIN_EXTRAFIELDS_IN_ONE_TD)) $this->global->MAIN_EXTRAFIELDS_IN_ONE_TD = 1; - if (!isset($this->global->MAIN_USE_OLD_TITLE_BUTTON)) $this->global->MAIN_USE_OLD_TITLE_BUTTON = 0; + if (!isset($this->global->MAIN_JS_GRAPH)) $this->global->MAIN_JS_GRAPH = 'chart'; // Use chart.js library + if (empty($this->global->MAIN_MODULE_DOLISTORE_API_SRV)) $this->global->MAIN_MODULE_DOLISTORE_API_SRV = 'https://www.dolistore.com'; if (empty($this->global->MAIN_MODULE_DOLISTORE_API_KEY)) $this->global->MAIN_MODULE_DOLISTORE_API_KEY = 'dolistorecatalogpublickey1234567'; diff --git a/htdocs/core/class/coreobject.class.php b/htdocs/core/class/coreobject.class.php index 672697cd0a3..999b01341f0 100644 --- a/htdocs/core/class/coreobject.class.php +++ b/htdocs/core/class/coreobject.class.php @@ -36,7 +36,7 @@ class CoreObject extends CommonObject /** * @var Array $_fields Fields to synchronize with Database */ - protected $fields=array(); + protected $fields = array(); /** * Constructor @@ -70,8 +70,8 @@ class CoreObject extends CommonObject else $this->{$field} = ''; } - $this->to_delete=false; - $this->is_clone=false; + $this->to_delete = false; + $this->is_clone = false; return true; } @@ -110,7 +110,7 @@ class CoreObject extends CommonObject public function fetch($id, $loadChild = true) { $res = $this->fetchCommon($id); - if($res>0) { + if ($res > 0) { if ($loadChild) $this->fetchChild(); } @@ -129,11 +129,11 @@ class CoreObject extends CommonObject */ public function addChild($tabName, $id = 0, $key = 'id', $try_to_load = false) { - if(!empty($id)) + if (!empty($id)) { - foreach($this->{$tabName} as $k=>&$object) + foreach ($this->{$tabName} as $k=>&$object) { - if($object->{$key} === $id) return $k; + if ($object->{$key} === $id) return $k; } } @@ -141,7 +141,7 @@ class CoreObject extends CommonObject $className = ucfirst($tabName); $this->{$tabName}[$k] = new $className($this->db); - if($id>0 && $key==='id' && $try_to_load) + if ($id > 0 && $key === 'id' && $try_to_load) { $this->{$tabName}[$k]->fetch($id); } @@ -181,20 +181,20 @@ class CoreObject extends CommonObject { if ($this->withChild && !empty($this->childtables) && !empty($this->fk_element)) { - foreach($this->childtables as &$childTable) + foreach ($this->childtables as &$childTable) { $className = ucfirst($childTable); - $this->{$className}=array(); + $this->{$className} = array(); $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$childTable.' WHERE '.$this->fk_element.' = '.$this->id; $res = $this->db->query($sql); - if($res) + if ($res) { - while($obj = $this->db->fetch_object($res)) + while ($obj = $this->db->fetch_object($res)) { - $o=new $className($this->db); + $o = new $className($this->db); $o->fetch($obj->rowid); $this->{$className}[] = $o; @@ -216,19 +216,19 @@ class CoreObject extends CommonObject */ public function saveChild(User &$user) { - if($this->withChild && !empty($this->childtables) && !empty($this->fk_element)) + if ($this->withChild && !empty($this->childtables) && !empty($this->fk_element)) { - foreach($this->childtables as &$childTable) + foreach ($this->childtables as &$childTable) { $className = ucfirst($childTable); - if(!empty($this->{$className})) + if (!empty($this->{$className})) { - foreach($this->{$className} as $i => &$object) + foreach ($this->{$className} as $i => &$object) { $object->{$this->fk_element} = $this->id; $object->update($user); - if($this->unsetChildDeleted && isset($object->to_delete) && $object->to_delete==true) unset($this->{$className}[$i]); + if ($this->unsetChildDeleted && isset($object->to_delete) && $object->to_delete == true) unset($this->{$className}[$i]); } } } @@ -245,7 +245,7 @@ class CoreObject extends CommonObject public function update(User &$user) { if (empty($this->id)) return $this->create($user); // To test, with that, no need to test on high level object, the core decide it, update just needed - elseif (isset($this->to_delete) && $this->to_delete==true) return $this->delete($user); + elseif (isset($this->to_delete) && $this->to_delete == true) return $this->delete($user); $error = 0; $this->db->begin(); @@ -253,7 +253,7 @@ class CoreObject extends CommonObject $res = $this->updateCommon($user); if ($res) { - $result = $this->call_trigger(strtoupper($this->element). '_UPDATE', $user); + $result = $this->call_trigger(strtoupper($this->element).'_UPDATE', $user); if ($result < 0) $error++; else $this->saveChild($user); } @@ -284,17 +284,17 @@ class CoreObject extends CommonObject */ public function create(User &$user) { - if($this->id > 0) return $this->update($user); + if ($this->id > 0) return $this->update($user); $error = 0; $this->db->begin(); $res = $this->createCommon($user); - if($res) + if ($res) { $this->id = $this->db->last_insert_id($this->table_element); - $result = $this->call_trigger(strtoupper($this->element). '_CREATE', $user); + $result = $this->call_trigger(strtoupper($this->element).'_CREATE', $user); if ($result < 0) $error++; else $this->saveChild($user); } @@ -330,20 +330,20 @@ class CoreObject extends CommonObject $error = 0; $this->db->begin(); - $result = $this->call_trigger(strtoupper($this->element). '_DELETE', $user); + $result = $this->call_trigger(strtoupper($this->element).'_DELETE', $user); if ($result < 0) $error++; if (!$error) { $this->deleteCommon($user); - if($this->withChild && !empty($this->childtables)) + if ($this->withChild && !empty($this->childtables)) { - foreach($this->childtables as &$childTable) + foreach ($this->childtables as &$childTable) { $className = ucfirst($childTable); if (!empty($this->{$className})) { - foreach($this->{$className} as &$object) + foreach ($this->{$className} as &$object) { $object->delete($user); } @@ -376,7 +376,7 @@ class CoreObject extends CommonObject */ public function getDate($field, $format = '') { - if(empty($this->{$field})) return ''; + if (empty($this->{$field})) return ''; else { return dol_print_date($this->{$field}, $format); @@ -416,24 +416,20 @@ class CoreObject extends CommonObject { foreach ($Tab as $key => $value) { - if($this->checkFieldType($key, 'date')) + if ($this->checkFieldType($key, 'date')) { $this->setDate($key, $value); } - elseif( $this->checkFieldType($key, 'array')) - { - $this->{$key} = $value; - } - elseif( $this->checkFieldType($key, 'float') ) + elseif ($this->checkFieldType($key, 'float')) { $this->{$key} = (double) price2num($value); } - elseif( $this->checkFieldType($key, 'int') ) { + elseif ($this->checkFieldType($key, 'int')) { $this->{$key} = (int) price2num($value); } else { - $this->{$key} = $value; + $this->{$key} = dol_string_nohtmltag($value); } } diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index ca40910aacd..c3707b18972 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -504,15 +504,16 @@ class DiscountAbsolute * @param string $filter Filtre autre * @param int $maxvalue Filter on max value for discount * @param int $discount_type 0 => customer discount, 1 => supplier discount + * @param int $multicurrency Return multicurrency_amount instead of amount * @return int <0 if KO, amount otherwise */ - public function getAvailableDiscounts($company = '', $user = '', $filter = '', $maxvalue = 0, $discount_type = 0) + public function getAvailableDiscounts($company = '', $user = '', $filter = '', $maxvalue = 0, $discount_type = 0, $multicurrency = 0) { global $conf; dol_syslog(get_class($this)."::getAvailableDiscounts discount_type=".$discount_type, LOG_DEBUG); - $sql = "SELECT SUM(rc.amount_ttc) as amount"; + $sql = "SELECT SUM(rc.amount_ttc) as amount, SUM(rc.multicurrency_amount_ttc) as multicurrency_amount"; $sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as rc"; $sql .= " WHERE rc.entity = ".$conf->entity; $sql .= " AND rc.discount_type=".intval($discount_type); @@ -535,6 +536,11 @@ class DiscountAbsolute //print 'zz'.$obj->amount; //$obj = $this->db->fetch_object($resql); //} + if ($multicurrency) + { + return $obj->amount_multicurrency; + } + return $obj->amount; } return -1; @@ -604,14 +610,14 @@ class DiscountAbsolute $sql = 'SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount'; $sql .= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except as rc, '.MAIN_DB_PREFIX.'facture as f'; $sql .= ' WHERE rc.fk_facture_source=f.rowid AND rc.fk_facture = '.$invoice->id; - $sql .= ' AND (f.type = 2 OR f.type = 0)'; // Find discount coming from credit note or excess received + $sql .= ' AND f.type IN (' . $invoice::TYPE_STANDARD . ', ' . $invoice::TYPE_CREDIT_NOTE . ', ' . $invoice::TYPE_SITUATION . ')'; // Find discount coming from credit note or excess received } elseif ($invoice->element == 'invoice_supplier') { $sql = 'SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount'; $sql .= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except as rc, '.MAIN_DB_PREFIX.'facture_fourn as f'; $sql .= ' WHERE rc.fk_invoice_supplier_source=f.rowid AND rc.fk_invoice_supplier = '.$invoice->id; - $sql .= ' AND (f.type = 2 OR f.type = 0)'; // Find discount coming from credit note or excess paid + $sql .= ' AND f.type IN (' . $invoice::TYPE_STANDARD . ', ' . $invoice::TYPE_CREDIT_NOTE . ')'; // Find discount coming from credit note or excess paid } else { diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php index 06b6ec2d949..a38c25f7614 100644 --- a/htdocs/core/class/doleditor.class.php +++ b/htdocs/core/class/doleditor.class.php @@ -90,7 +90,7 @@ class DolEditor { $content = dol_htmlentitiesbr($content); // If content is not HTML, we convert to HTML. } - if ($this->tool == 'fckeditor') + /*if ($this->tool == 'fckeditor') { require_once DOL_DOCUMENT_ROOT.'/includes/fckeditor/fckeditor.php'; @@ -121,7 +121,7 @@ class DolEditor $this->editor->Config['CustomConfigurationsPath'] = DOL_URL_ROOT.'/theme/'.$conf->theme.'/fckeditor/fckconfig.js'; $this->editor->Config['SkinPath'] = DOL_URL_ROOT.'/theme/'.$conf->theme.'/fckeditor/'; } - } + }*/ // Define some properties if (in_array($this->tool, array('textarea', 'ckeditor', 'ace'))) diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index 9aa54498edc..3f3f905166e 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -30,10 +30,10 @@ * $dolgraph->SetTitle($langs->transnoentities('MyTitle').'
'.$langs->transnoentities('MyTitlePercent').'%'); * $dolgraph->SetMaxValue(50); * $dolgraph->SetData($data); - * $dolgraph->setShowLegend(1); + * $dolgraph->setShowLegend(2); * $dolgraph->setShowPercent(1); * $dolgraph->SetType(array('pie')); - * $dolgraph->setWidth('100%'); + * $dolgraph->setHeight('200'); * $dolgraph->draw('idofgraph'); * print $dolgraph->show($total?0:1); */ @@ -92,31 +92,13 @@ class DolGraph /** * Constructor * - * @param string $library 'jflot' (default) or 'artichow' (no more supported) + * @param string $library 'auto' (default) */ - public function __construct($library = 'jflot') + public function __construct($library = 'auto') { global $conf; global $theme_bordercolor, $theme_datacolor, $theme_bgcolor; - // To use old feature - if ($library == 'artichow') - { - $this->_library = 'artichow'; - - // Test if module GD present - $modules_list = get_loaded_extensions(); - $isgdinstalled = 0; - foreach ($modules_list as $module) - { - if ($module == 'gd') $isgdinstalled = 1; - } - if (!$isgdinstalled) - { - $this->error = "Error: PHP GD module is not available. It is required to build graphics."; - } - } - $this->bordercolor = array(235, 235, 224); $this->datacolor = array(array(120, 130, 150), array(160, 160, 180), array(190, 190, 220)); $this->bgcolor = array(235, 235, 224); @@ -130,23 +112,14 @@ class DolGraph if (isset($theme_bgcolor)) $this->bgcolor = $theme_bgcolor; } //print 'bgcolor: '.join(',',$this->bgcolor).'
'; + + $this->_library = $library; + if ($this->_library == 'auto') { + $this->_library = (empty($conf->global->MAIN_JS_GRAPH) ? 'jflot': $conf->global->MAIN_JS_GRAPH); + } } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Set Y precision - * - * @param float $which_prec Precision - * @return boolean - * @deprecated - */ - public function SetPrecisionY($which_prec) - { - // phpcs:enable - return true; - } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Utiliser SetNumTicks ou SetHorizTickIncrement mais pas les 2 @@ -287,7 +260,8 @@ class DolGraph /** * Set type * - * @param array $type Array with type for each serie. Example: array('pie'), array('lines',...,'bars') + * @param array $type Array with type for each serie. Example: array('type1', 'type2', ...) where type can be: + * 'pie', 'piesemicircle', 'polar', 'lines', 'linesnopoint', 'bars', ... * @return void */ public function SetType($type) @@ -448,7 +422,7 @@ class DolGraph /** * Show legend or not * - * @param int $showlegend 1=Show legend (default), 0=Hide legend + * @param int $showlegend 1=Show legend (default), 0=Hide legend, 2=Show legend on right * @return void */ public function setShowLegend($showlegend) @@ -561,6 +535,8 @@ class DolGraph public function GetMaxValueInData() { // phpcs:enable + if (! is_array($this->data)) return 0; + $k = 0; $vals = array(); @@ -588,6 +564,8 @@ class DolGraph public function GetMinValueInData() { // phpcs:enable + if (! is_array($this->data)) return 0; + $k = 0; $vals = array(); @@ -686,188 +664,6 @@ class DolGraph call_user_func_array(array($this, $call), array($file, $fileurl)); } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Build a graph onto disk using Artichow library and return img string to it - * - * @param string $file Image file name to use if we save onto disk - * @param string $fileurl Url path to show image if saved onto disk - * @return void - */ - private function draw_artichow($file, $fileurl) - { - // phpcs:enable - global $artichow_defaultfont; - - dol_syslog(get_class($this)."::draw_artichow this->type=".join(',', $this->type)); - - if (!defined('SHADOW_RIGHT_TOP')) define('SHADOW_RIGHT_TOP', 3); - if (!defined('LEGEND_BACKGROUND')) define('LEGEND_BACKGROUND', 2); - if (!defined('LEGEND_LINE')) define('LEGEND_LINE', 1); - - // Create graph - $classname = ''; - if (!isset($this->type[0]) || $this->type[0] == 'bars') $classname = 'BarPlot'; // Only one type (first one) is supported by artichow - elseif ($this->type[0] == 'lines' || $this->type[0] == 'linesnopoint') $classname = 'LinePlot'; - else $classname = 'TypeUnknown'; - include_once ARTICHOW_PATH.$classname.'.class.php'; - - // Definition de couleurs - $bgcolor = new Color($this->bgcolor[0], $this->bgcolor[1], $this->bgcolor[2]); - $bgcolorgrid = new Color($this->bgcolorgrid[0], $this->bgcolorgrid[1], $this->bgcolorgrid[2]); - $colortrans = new Color(0, 0, 0, 100); - $colorsemitrans = new Color(255, 255, 255, 60); - $colorgradient = new LinearGradient(new Color(235, 235, 235), new Color(255, 255, 255), 0); - $colorwhite = new Color(255, 255, 255); - - // Graph - $graph = new Graph($this->width, $this->height); - $graph->border->hide(); - $graph->setAntiAliasing(true); - if (isset($this->title)) - { - $graph->title->set($this->title); - //print $artichow_defaultfont;exit; - $graph->title->setFont(new $artichow_defaultfont(10)); - } - - if (is_array($this->bgcolor)) $graph->setBackgroundColor($bgcolor); - else $graph->setBackgroundGradient($colorgradient); - - $group = new PlotGroup; - //$group->setSpace(5, 5, 0, 0); - - $paddleft = 50; - $paddright = 10; - $strl = dol_strlen(max(abs($this->MaxValue), abs($this->MinValue))); - if ($strl > 6) $paddleft += ($strl * 4); - $group->setPadding($paddleft, $paddright); // Width on left and right for Y axis values - $group->legend->setSpace(0); - $group->legend->setPadding(2, 2, 2, 2); - $group->legend->setPosition(null, 0.1); - $group->legend->setBackgroundColor($colorsemitrans); - - if (is_array($this->bgcolorgrid)) $group->grid->setBackgroundColor($bgcolorgrid); - else $group->grid->setBackgroundColor($colortrans); - - if ($this->hideXGrid) $group->grid->hideVertical(true); - if ($this->hideYGrid) $group->grid->hideHorizontal(true); - - // On boucle sur chaque lot de donnees - $legends = array(); - $i = 0; - $nblot = count($this->data[0]) - 1; - - while ($i < $nblot) - { - $x = 0; - $values = array(); - foreach ($this->data as $key => $valarray) - { - $legends[$x] = $valarray[0]; - $values[$x] = $valarray[$i + 1]; - $x++; - } - - // We fix unknown values to null - $newvalues = array(); - foreach ($values as $val) - { - $newvalues[] = (is_numeric($val) ? $val : null); - } - - - if ($this->type[0] == 'bars') - { - //print "Lot de donnees $i
"; - //print_r($values); - //print '
'; - - $color = new Color($this->datacolor[$i][0], $this->datacolor[$i][1], $this->datacolor[$i][2], 20); - $colorbis = new Color(min($this->datacolor[$i][0] + 50, 255), min($this->datacolor[$i][1] + 50, 255), min($this->datacolor[$i][2] + 50, 255), 50); - - $colorgrey = new Color(100, 100, 100); - $colorborder = new Color($this->datacolor[$i][0], $this->datacolor[$i][1], $this->datacolor[$i][2]); - - if ($this->mode == 'side') $plot = new BarPlot($newvalues, $i + 1, $nblot); - if ($this->mode == 'depth') $plot = new BarPlot($newvalues, 1, 1, ($nblot - $i - 1) * 5); - - $plot->barBorder->setColor($colorgrey); - //$plot->setBarColor($color); - $plot->setBarGradient(new LinearGradient($colorbis, $color, 90)); - - if ($this->mode == 'side') $plot->setBarPadding(0.1, 0.1); - if ($this->mode == 'depth') $plot->setBarPadding(0.1, 0.4); - if ($this->mode == 'side') $plot->setBarSpace(5); - if ($this->mode == 'depth') $plot->setBarSpace(2); - - $plot->barShadow->setSize($this->SetShading); - $plot->barShadow->setPosition(SHADOW_RIGHT_TOP); - $plot->barShadow->setColor(new Color(160, 160, 160, 50)); - $plot->barShadow->smooth(true); - //$plot->setSize(1, 0.96); - //$plot->setCenter(0.5, 0.52); - - // Le mode automatique est plus efficace - $plot->SetYMax($this->MaxValue); - $plot->SetYMin($this->MinValue); - } - - if ($this->type[0] == 'lines' || $this->type[0] == 'linesnopoint') - { - $color = new Color($this->datacolor[$i][0], $this->datacolor[$i][1], $this->datacolor[$i][2], 20); - $colorbis = new Color(min($this->datacolor[$i][0] + 20, 255), min($this->datacolor[$i][1] + 20, 255), min($this->datacolor[$i][2] + 20, 255), 60); - $colorter = new Color(min($this->datacolor[$i][0] + 50, 255), min($this->datacolor[$i][1] + 50, 255), min($this->datacolor[$i][2] + 50, 255), 90); - - $plot = new LinePlot($newvalues); - //$plot->setSize(1, 0.96); - //$plot->setCenter(0.5, 0.52); - - $plot->setColor($color); - $plot->setThickness(1); - - // Set line background gradient - $plot->setFillGradient(new LinearGradient($colorter, $colorbis, 90)); - - $plot->xAxis->setLabelText($legends); - - // Le mode automatique est plus efficace - $plot->SetYMax($this->MaxValue); - $plot->SetYMin($this->MinValue); - //$plot->setYAxis(0); - //$plot->hideLine(true); - } - - //$plot->reduce(80); // Evite temps d'affichage trop long et nombre de ticks absisce satures - - $group->legend->setTextFont(new $artichow_defaultfont(10)); // This is to force Artichow to use awFileFontDriver to - // solve a bug in Artichow with UTF8 - if (count($this->Legend)) - { - if ($this->type[0] == 'bars') $group->legend->add($plot, $this->Legend[$i], LEGEND_BACKGROUND); - if ($this->type[0] == 'lines' || $this->type[0] == 'linesnopoint') $group->legend->add($plot, $this->Legend[$i], LEGEND_LINE); - } - $group->add($plot); - - $i++; - } - - $group->axis->bottom->setLabelText($legends); - $group->axis->bottom->label->setFont(new $artichow_defaultfont(7)); - - //print $group->axis->bottom->getLabelNumber(); - if ($this->labelInterval > 0) $group->axis->bottom->setLabelInterval($this->labelInterval); - - $graph->add($group); - - // Generate file - $graph->draw($file); - - $this->stringtoshow = ''.dol_escape_htmltag($this->title ? $this->title : $this->YLabel).''; - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Build a graph using JFlot library. Input when calling this method should be: @@ -875,7 +671,7 @@ class DolGraph * $this->data = array(array(0=>'labelxA',1=>yA1,...,n=>yAn), array('labelxB',yB1,...yBn)); // or when there is n series to show for each x * $this->data = array(array('label'=>'labelxA','data'=>yA), array('labelxB',yB)); // Syntax deprecated * $this->legend= array("Val1",...,"Valn"); // list of n series name - * $this->type = array('bars',...'lines'); or array('pie') + * $this->type = array('bars',...'lines','linesnopoint'); or array('pie') or array('polar') * $this->mode = 'depth' ??? * $this->bgcolorgrid * $this->datacolor @@ -888,7 +684,7 @@ class DolGraph private function draw_jflot($file, $fileurl) { // phpcs:enable - global $langs; + global $conf, $langs; dol_syslog(get_class($this)."::draw_jflot this->type=".join(',', $this->type)." this->MaxValue=".$this->MaxValue); @@ -924,8 +720,7 @@ class DolGraph $x++; } - // TODO Avoid push by adding generated long array... - if (isset($this->type[$firstlot]) && $this->type[$firstlot] == 'pie') + if (isset($this->type[$firstlot]) && in_array($this->type[$firstlot], array('pie', 'piesemicircle', 'polar'))) { foreach ($values as $x => $y) { if (isset($y)) $serie[$i] .= 'd'.$i.'.push({"label":"'.dol_escape_js($legends[$x]).'", "data":'.$y.'});'."\n"; @@ -943,7 +738,7 @@ class DolGraph } $tag = dol_escape_htmltag(dol_string_unaccent(dol_string_nospecial(basename($file), '_', array('-', '.')))); - $this->stringtoshow = ''."\n"; + $this->stringtoshow = ''."\n"; if (!empty($this->title)) $this->stringtoshow .= '
'.$this->title.'
'; if (!empty($this->shownographyet)) { @@ -951,30 +746,38 @@ class DolGraph $this->stringtoshow .= '
'.$langs->trans("NotEnoughDataYet").'
'; return; } - $this->stringtoshow .= '
'."\n"; + + // Start the div that will contains all the graph + $dolxaxisvertical=''; + if (count($this->data) > 20) $dolxaxisvertical='dol-xaxis-vertical'; + $this->stringtoshow .= '
'."\n"; $this->stringtoshow .= ''."\n"; } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Build a graph using Chart library. Input when calling this method should be: + * $this->data = array(array(0=>'labelxA',1=>yA), array('labelxB',yB)); + * $this->data = array(array(0=>'labelxA',1=>yA1,...,n=>yAn), array('labelxB',yB1,...yBn)); // or when there is n series to show for each x + * $this->data = array(array('label'=>'labelxA','data'=>yA), array('labelxB',yB)); // Syntax deprecated + * $this->legend= array("Val1",...,"Valn"); // list of n series name + * $this->type = array('bars',...'lines', 'linesnopoint'); or array('pie') or array('polar') or array('piesemicircle'); + * $this->mode = 'depth' ??? + * $this->bgcolorgrid + * $this->datacolor + * $this->shownodatagraph + * + * @param string $file Image file name to use to save onto disk (also used as javascript unique id) + * @param string $fileurl Url path to show image if saved onto disk. Never used here. + * @return void + */ + private function draw_chart($file, $fileurl) + { + // phpcs:enable + global $conf, $langs; + + dol_syslog(get_class($this)."::draw_chart this->type=".join(',', $this->type)." this->MaxValue=".$this->MaxValue); + + if (empty($this->width) && empty($this->height)) + { + print 'Error width or height not set'; + return; + } + + $showlegend = $this->showlegend; + + $legends = array(); + $nblot = 0; + if (is_array($this->data)) { + foreach ($this->data as $valarray) // Loop on each x + { + $nblot = max($nblot, count($valarray) - 1); // -1 to remove legend + } + } + //var_dump($nblot); + if ($nblot < 0) dol_syslog('Bad value for property ->data. Must be set by mydolgraph->SetData before calling mydolgrapgh->draw', LOG_WARNING); + $firstlot = 0; + // Works with line but not with bars + //if ($nblot > 2) $firstlot = ($nblot - 2); // We limit nblot to 2 because jflot can't manage more than 2 bars on same x + + $serie = array(); $arrayofgroupslegend = array(); + //var_dump($this->data); + + $i = $firstlot; + while ($i < $nblot) // Loop on each serie + { + $values = array(); // Array with horizontal y values (specific values of a serie) for each abscisse x (with x=0,1,2,...) + $serie[$i] = ""; + + // Fill array $values + $x = 0; + foreach ($this->data as $valarray) // Loop on each x + { + $legends[$x] = (array_key_exists('label', $valarray) ? $valarray['label'] : $valarray[0]); + $array_of_ykeys = array_keys($valarray); + $alabelexists = 1; + $tmpykey = explode('_', ($array_of_ykeys[$i+($alabelexists ? 1 : 0)]), 3); + if (! empty($tmpykey[2]) || $tmpykey[2] == '0') { // This is a 'Group by' array + $tmpvalue = (array_key_exists('y_'.$tmpykey[1].'_'.$tmpykey[2], $valarray) ? $valarray['y_'.$tmpykey[1].'_'.$tmpykey[2]] : $valarray[$i + 1]); + $values[$x] = (is_numeric($tmpvalue) ? $tmpvalue : null); + $arrayofgroupslegend[$i] = array( + 'stacknum'=> $tmpykey[1], + 'legend' => $this->Legend[$tmpykey[1]], + 'legendwithgroup' => $this->Legend[$tmpykey[1]].' - '.$tmpykey[2] + ); + } else { + $tmpvalue = (array_key_exists('y_'.$i, $valarray) ? $valarray['y_'.$i] : $valarray[$i + 1]); + //var_dump($i.'_'.$x.'_'.$tmpvalue); + $values[$x] = (is_numeric($tmpvalue) ? $tmpvalue : null); + } + $x++; + } + //var_dump($values); + $j = 0; + foreach ($values as $x => $y) { + if (isset($y)) { + $serie[$i] .= ($j > 0 ? ", " : "").$y; + } else { + $serie[$i] .= ($j > 0 ? ", " : "").'null'; + } + $j++; + } + + $values = null; // Free mem + $i++; + } + //var_dump($serie); + //var_dump($arrayofgroupslegend); + + $tag = dol_escape_htmltag(dol_string_unaccent(dol_string_nospecial(basename($file), '_', array('-', '.')))); + + $this->stringtoshow = ''."\n"; + if (!empty($this->title)) $this->stringtoshow .= '
'.$this->title.'
'; + if (!empty($this->shownographyet)) + { + $this->stringtoshow .= '
'; + $this->stringtoshow .= '
'.$langs->trans("NotEnoughDataYet").'
'; + return; + } + + // Start the div that will contains all the graph + $dolxaxisvertical=''; + if (count($this->data) > 20) $dolxaxisvertical='dol-xaxis-vertical'; + // No height for the pie grah + $cssfordiv = 'dolgraphchart'; + if (isset($this->type[$firstlot])) $cssfordiv .= ' dolgraphchar'.$this->type[$firstlot]; + $this->stringtoshow .= '
'."\n"; + + $this->stringtoshow .= ''."\n"; + } + + /** * Output HTML string to total value * diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php index 4425e43cda2..d241c2a8c5a 100644 --- a/htdocs/core/class/dolreceiptprinter.class.php +++ b/htdocs/core/class/dolreceiptprinter.class.php @@ -1,5 +1,6 @@ + * Copyright (C) 2020 Andreu Bisquerra * * 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 @@ -30,26 +31,26 @@ * Use font A of printer * Use font B of printer * Use font C of printer - * Text Bold - * Text double height - * Text double width - * Underline text - * Underline with double line - * Emphasized text - * Print in white on black - * Ticket print width of 57mm + * Text Bold + * Disable Text Bold + * Text double height + * Text double width + * Text default height and width + * Underline text + * Disable underline text * Cut ticket completely * Cut ticket partially * Open cash drawer - * Activate buzzer + * Activate buzzer * Print barcode - * Print QR Code * Print logo stored on printer. Example : 32|32 * Print logo stored on printer. Must be followed by logo code. For old printers. * Print object lines * Print object total tax * Print object local tax * Print object total + * Print order lines for Printer1 + * Print order lines for Printer2 * Print payment method * * Code which can be placed everywhere @@ -60,8 +61,6 @@ * Replaced by month number * Replaced by day number * Replaced by day number - * Replaced by table number (for restaurant, bar...) - * Replaced by number of cutlery (for restaurant) * Replaced by object id * Replaced by object ref * Replaced by customer firstname @@ -162,26 +161,17 @@ class dolReceiptPrinter extends Printer 'dol_use_font_b', 'dol_use_font_c', 'dol_bold', - '/dol_bold', + 'dol_bold_disabled', 'dol_double_height', - '/dol_double_height', 'dol_double_width', - '/dol_double_width', + 'dol_default_height_width', 'dol_underline', - '/dol_underline', - 'dol_underline_2dots', - '/dol_underline', - 'dol_emphasized', - '/dol_emphasized', - 'dol_switch_colors', - '/dol_switch_colors', - 'dol_set_print_width_57', + 'dol_underline_disabled', 'dol_cut_paper_full', 'dol_cut_paper_partial', 'dol_open_drawer', - //'dol_activate_buzzer', + 'dol_beep', 'dol_print_text', - 'dol_print_qrcode', 'dol_print_barcode', 'dol_value_date', 'dol_value_date_time', @@ -190,8 +180,6 @@ class dolReceiptPrinter extends Printer 'dol_value_month', 'dol_value_day', 'dol_value_day_letters', - 'dol_value_table', - 'dol_value_cutlery', 'dol_print_payment', 'dol_print_logo', 'dol_print_logo_old', @@ -202,6 +190,8 @@ class dolReceiptPrinter extends Printer 'dol_print_object_local_tax', 'dol_print_object_total', 'dol_print_object_number', + 'dol_print_order_lines_printer1', + 'dol_print_order_lines_printer2', 'dol_value_customer_firstname', 'dol_value_customer_lastname', 'dol_value_customer_mail', @@ -515,7 +505,7 @@ class dolReceiptPrinter extends Printer { global $conf; $error = 0; - $img = EscposImage::load(DOL_DOCUMENT_ROOT.'/theme/common/dolibarr_logo_bw.png'); + $img = EscposImage::load(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo_bw.png'); //$this->profile = CapabilityProfile::load("TM-T88IV"); $ret = $this->initPrinter($printerid); if ($ret > 0) { @@ -589,15 +579,13 @@ class dolReceiptPrinter extends Printer $this->template = str_replace('', $object->vendor_firstname, $this->template); $this->template = str_replace('', $object->vendor_lastname, $this->template); $this->template = str_replace('', $object->vendor_mail, $this->template); - $this->template = str_replace('', $object->date, $this->template); - $this->template = str_replace('', $object->date_time, $this->template); - $this->template = str_replace('', $object->date_time, $this->template); - $this->template = str_replace('', $object->date_time, $this->template); - $this->template = str_replace('', $object->date_time, $this->template); - $this->template = str_replace('', $object->date_time, $this->template); - $this->template = str_replace('', $object->date_time, $this->template); - $this->template = str_replace('', $object->table, $this->template); - $this->template = str_replace('', $object->cutlery, $this->template); + $this->template = str_replace('', dol_print_date($object->date, 'day'), $this->template); + $this->template = str_replace('', dol_print_date($object->date, 'dayhour'), $this->template); + $this->template = str_replace('', dol_print_date($object->date, '%Y'), $this->template); + $this->template = str_replace('', $langs->trans("Month".dol_print_date($object->date, '%m')), $this->template); + $this->template = str_replace('', dol_print_date($object->date, '%m'), $this->template); + $this->template = str_replace('', dol_print_date($object->date, '%d'), $this->template); + $this->template = str_replace('', $langs->trans("Day".dol_print_date($object->date, '%m')[1]), $this->template); // parse template $p = xml_parser_create(); @@ -712,6 +700,52 @@ class dolReceiptPrinter extends Printer case 'DOL_USE_FONT_C': $this->printer->setFont(Printer::FONT_C); break; + case 'DOL_BOLD': + $this->printer->setEmphasis(true); + break; + case 'DOL_BOLD_DISABLED': + $this->printer->setEmphasis(false); + break; + case 'DOL_DOUBLE_HEIGHT': + $this->printer->setTextSize(1, 2); + break; + case 'DOL_DOUBLE_WIDTH': + $this->printer->setTextSize(2, 1); + break; + case 'DOL_DEFAULT_HEIGHT_WIDTH': + $this->printer->setTextSize(1, 1); + break; + case 'DOL_UNDERLINE': + $this->printer->setUnderline(true); + break; + case 'DOL_UNDERLINE_DISABLED': + $this->printer->setUnderline(false); + break; + case 'DOL_BEEP': + $this->printer->getPrintConnector() -> write("\x1e"); + break; + case 'DOL_PRINT_ORDER_LINES_PRINTER1': + foreach ($object->lines as $line) { + if ($line->special_code==1) + { + $spacestoadd = $nbcharactbyline - strlen($line->ref) - strlen($line->qty) - 10 - 1; + $spaces = str_repeat(' ', $spacestoadd); + $this->printer->text($line->ref.$spaces.$line->qty.' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n"); + $this->printer->text(strip_tags(htmlspecialchars_decode($line->desc))."\n"); + } + } + break; + case 'DOL_PRINT_ORDER_LINES_PRINTER2': + foreach ($object->lines as $line) { + if ($line->special_code==2) + { + $spacestoadd = $nbcharactbyline - strlen($line->ref) - strlen($line->qty) - 10 - 1; + $spaces = str_repeat(' ', $spacestoadd); + $this->printer->text($line->ref.$spaces.$line->qty.' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n"); + $this->printer->text(strip_tags(htmlspecialchars_decode($line->desc))."\n"); + } + } + break; default: $this->printer->text($vals[$tplline]['tag']); $this->printer->text($vals[$tplline]['value']); diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 5d5540d77b8..a9b908203fe 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -225,9 +225,10 @@ class ExtraFields * @param string $langfile Language file * @param string $enabled Condition to have the field enabled or not * @param int $totalizable Is a measure. Must show a total on lists + * @param int $printable Is extrafield displayed on PDF * @return int <=0 if KO, >0 if OK */ - public function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique = 0, $required = 0, $default_value = '', $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0) + public function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique = 0, $required = 0, $default_value = '', $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0) { if (empty($attrname)) return -1; if (empty($label)) return -1; @@ -245,7 +246,7 @@ class ExtraFields if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') { // Add declaration of field into table - $result2 = $this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable); + $result2 = $this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable, $printable); $err2 = $this->errno; if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) { @@ -374,9 +375,11 @@ class ExtraFields * @param string $langfile Language file * @param string $enabled Condition to have the field enabled or not * @param int $totalizable Is a measure. Must show a total on lists + * @param int $printable Is extrafield displayed on PDF * @return int <=0 if KO, >0 if OK + * @throws Exception */ - private function create_label($attrname, $label = '', $type = '', $pos = 0, $size = 0, $elementtype = 'member', $unique = 0, $required = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0) + private function create_label($attrname, $label = '', $type = '', $pos = 0, $size = 0, $elementtype = 'member', $unique = 0, $required = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0) { // phpcs:enable global $conf, $user; @@ -390,6 +393,7 @@ class ExtraFields if (empty($required)) $required = 0; if (empty($unique)) $unique = 0; if (empty($alwayseditable)) $alwayseditable = 0; + if (empty($totalizable)) $totalizable = 0; if (!empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/", $attrname) && !is_numeric($attrname)) { @@ -421,6 +425,7 @@ class ExtraFields $sql .= " perms,"; $sql .= " langs,"; $sql .= " list,"; + $sql .= " printable,"; $sql .= " fielddefault,"; $sql .= " fieldcomputed,"; $sql .= " fk_user_author,"; @@ -444,6 +449,7 @@ class ExtraFields $sql .= " ".($perms ? "'".$this->db->escape($perms)."'" : "null").","; $sql .= " ".($langfile ? "'".$this->db->escape($langfile)."'" : "null").","; $sql .= " '".$this->db->escape($list)."',"; + $sql .= " '".$this->db->escape($printable)."',"; $sql .= " ".($default ? "'".$this->db->escape($default)."'" : "null").","; $sql .= " ".($computed ? "'".$this->db->escape($computed)."'" : "null").","; $sql .= " ".(is_object($user) ? $user->id : 0).","; @@ -451,7 +457,7 @@ class ExtraFields $sql .= "'".$this->db->idate(dol_now())."',"; $sql .= " ".($enabled ? "'".$this->db->escape($enabled)."'" : "1").","; $sql .= " ".($help ? "'".$this->db->escape($help)."'" : "null").","; - $sql .= " ".($totalizable ? '1' : '0'); + $sql .= " ".($totalizable ? 'TRUE' : 'FALSE'); $sql .= ')'; dol_syslog(get_class($this)."::create_label", LOG_DEBUG); @@ -590,9 +596,11 @@ class ExtraFields * @param string $langfile Language file * @param string $enabled Condition to have the field enabled or not * @param int $totalizable Is extrafield totalizable on list + * @param int $printable Is extrafield displayed on PDF * @return int >0 if OK, <=0 if KO + * @throws Exception */ - public function update($attrname, $label, $type, $length, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0) + public function update($attrname, $label, $type, $length, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0) { if ($elementtype == 'thirdparty') $elementtype = 'societe'; if ($elementtype == 'contact') $elementtype = 'socpeople'; @@ -642,7 +650,7 @@ class ExtraFields { if ($label) { - $result = $this->update_label($attrname, $label, $type, $length, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default, $computed, $entity, $langfile, $enabled, $totalizable); + $result = $this->update_label($attrname, $label, $type, $length, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default, $computed, $entity, $langfile, $enabled, $totalizable, $printable); } if ($result > 0) { @@ -700,13 +708,15 @@ class ExtraFields * @param string $langfile Language file * @param string $enabled Condition to have the field enabled or not * @param int $totalizable Is extrafield totalizable on list + * @param int $printable Is extrafield displayed on PDF * @return int <=0 if KO, >0 if OK + * @throws Exception */ - private function update_label($attrname, $label, $type, $size, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '0', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0) + private function update_label($attrname, $label, $type, $size, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '0', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0) { // phpcs:enable global $conf, $user; - dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled.", ".$totalizable); + dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled.", ".$totalizable.", ".$printable); // Clean parameters if ($elementtype == 'thirdparty') $elementtype = 'societe'; @@ -771,6 +781,7 @@ class ExtraFields $sql .= " alwayseditable,"; $sql .= " param,"; $sql .= " list,"; + $sql .= " printable,"; $sql .= " totalizable,"; $sql .= " fielddefault,"; $sql .= " fieldcomputed,"; @@ -794,7 +805,8 @@ class ExtraFields $sql .= " '".$this->db->escape($alwayseditable)."',"; $sql .= " '".$this->db->escape($params)."',"; $sql .= " '".$this->db->escape($list)."', "; - $sql .= " ".$totalizable.","; + $sql .= " '".$this->db->escape($printable)."', "; + $sql .= " ".($totalizable ? 'TRUE' : 'FALSE').","; $sql .= " ".(($default != '') ? "'".$this->db->escape($default)."'" : "null").","; $sql .= " ".($computed ? "'".$this->db->escape($computed)."'" : "null").","; $sql .= " ".$user->id.","; @@ -871,7 +883,7 @@ class ExtraFields }*/ // We should not have several time this request. If we have, there is some optimization to do by calling a simple $extrafields->fetch_optionals() in top of code and not into subcode - $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,totalizable,fielddefault,fieldcomputed,entity,enabled,help"; + $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,langs,list,printable,totalizable,fielddefault,fieldcomputed,entity,enabled,help"; $sql .= " FROM ".MAIN_DB_PREFIX."extrafields"; //$sql.= " WHERE entity IN (0,".$conf->entity.")"; // Filter is done later if ($elementtype) $sql .= " WHERE elementtype = '".$elementtype."'"; // Filed with object->table_element @@ -933,7 +945,8 @@ class ExtraFields $this->attributes[$tab->elementtype]['perms'][$tab->name] = (strlen($tab->perms) == 0 ? 1 : $tab->perms); $this->attributes[$tab->elementtype]['langfile'][$tab->name] = $tab->langs; $this->attributes[$tab->elementtype]['list'][$tab->name] = $tab->list; - $this->attributes[$tab->elementtype]['totalizable'][$tab->name] = $tab->totalizable; + $this->attributes[$tab->elementtype]['printable'][$tab->name] = $tab->printable; + $this->attributes[$tab->elementtype]['totalizable'][$tab->name] = ($tab->totalizable ? 1 : 0); $this->attributes[$tab->elementtype]['entityid'][$tab->name] = $tab->entity; $this->attributes[$tab->elementtype]['enabled'][$tab->name] = $tab->enabled; $this->attributes[$tab->elementtype]['help'][$tab->name] = $tab->help; diff --git a/htdocs/core/class/hookmanager.class.php b/htdocs/core/class/hookmanager.class.php index 39493825377..437ac507462 100644 --- a/htdocs/core/class/hookmanager.class.php +++ b/htdocs/core/class/hookmanager.class.php @@ -177,6 +177,7 @@ class HookManager 'getFormatedCustomerRef', 'getFormatedSupplierRef', 'getIdProfUrl', + 'getInputIdProf', 'moveUploadedFile', 'moreHtmlStatus', 'pdf_build_address', diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index e7cd695dc0b..0db01a84656 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -202,7 +202,7 @@ class Form $ret .= ''; if (empty($notabletag)) $ret .= ''; if (empty($notabletag)) $ret .= ''; $label_title = empty($conf->global->MAIN_APPLICATION_TITLE) ? $mysoc->name : $conf->global->MAIN_APPLICATION_TITLE; - print ''; // Destinataires @@ -935,13 +935,13 @@ class FormTicket if (is_array($contacts) && count($contacts) > 0) { foreach ($contacts as $key => $info_sendto) { if ($info_sendto['email'] != '') { - $sendto[] = dol_escape_htmltag(trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">")." (".dol_escape_htmltag($info_sendto['libelle']).")"; + $sendto[] = dol_escape_htmltag(trim($info_sendto['firstname']." ".$info_sendto['lastname'])." <".$info_sendto['email'].">").' ('.dol_escape_htmltag($info_sendto['libelle']).")"; } } } if ($ticketstat->origin_email && !in_array($this->dao->origin_email, $sendto)) { - $sendto[] = dol_escape_htmltag($ticketstat->origin_email)." (".$langs->trans("TicketEmailOriginIssuer").")"; + $sendto[] = dol_escape_htmltag($ticketstat->origin_email).' ('.$langs->trans("TicketEmailOriginIssuer").")"; } if ($ticketstat->fk_soc > 0) { @@ -949,12 +949,12 @@ class FormTicket $ticketstat->fetch_thirdparty(); if (is_array($ticketstat->thirdparty->email) && !in_array($ticketstat->thirdparty->email, $sendto)) { - $sendto[] = $ticketstat->thirdparty->email.' ('.$langs->trans('Customer').')'; + $sendto[] = $ticketstat->thirdparty->email.' ('.$langs->trans('Customer').')'; } } if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS) { - $sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO.' (generic email)'; + $sendto[] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO.' (generic email)'; } // Print recipient list diff --git a/htdocs/core/class/html.formwebsite.class.php b/htdocs/core/class/html.formwebsite.class.php index 6cd88175a67..7b067fa11d6 100644 --- a/htdocs/core/class/html.formwebsite.class.php +++ b/htdocs/core/class/html.formwebsite.class.php @@ -269,7 +269,15 @@ class FormWebsite $valueforoption = '['.$valpage->type_container.' '.sprintf("%03d", $valpage->id).'] '; $valueforoption .= $valpage->pageurl.' - '.$valpage->title; - if ($website->fk_default_home && $key == $website->fk_default_home) $valueforoption .= ' ('.$langs->trans("HomePage").')'; + if ($website->otherlang) { // If there is alternative lang for this web site, we show the language code + if ($valpage->lang) { + $valueforoption .= ' ('.$valpage->lang.')'; + } + } + if ($website->fk_default_home && $key == $website->fk_default_home) { + //$valueforoption .= ' ('.$langs->trans("HomePage").')'; + $valueforoption .= ' '; + } $out .= '
'; - if (preg_match('/^(string|email)/', $typeofdata)) + if (preg_match('/^(string|safehtmlstring|email)/', $typeofdata)) { $tmp = explode(':', $typeofdata); $ret .= ''; @@ -276,6 +276,7 @@ class Form if (preg_match('/^(email)/', $typeofdata)) $ret .= dol_print_email($value, 0, 0, 0, 0, 1); elseif (preg_match('/^(amount|numeric)/', $typeofdata)) $ret .= ($value != '' ? price($value, '', $langs, 0, -1, -1, $conf->currency) : ''); elseif (preg_match('/^text/', $typeofdata) || preg_match('/^note/', $typeofdata)) $ret .= dol_htmlentitiesbr($value); + elseif (preg_match('/^safehtmlstring/', $typeofdata)) $ret .= dol_string_onlythesehtmltags($value); elseif ($typeofdata == 'day' || $typeofdata == 'datepicker') $ret .= dol_print_date($value, 'day'); elseif ($typeofdata == 'dayhour' || $typeofdata == 'datehourpicker') $ret .= dol_print_date($value, 'dayhour'); elseif (preg_match('/^select;/', $typeofdata)) @@ -298,9 +299,13 @@ class Form $firstline = preg_replace('/[\n\r].*/', '', $firstline); $tmpcontent = $firstline.((strlen($firstline) != strlen($tmpcontent)) ? '...' : ''); } - $ret .= $tmpcontent; + // We dont use dol_escape_htmltag to get the html formating active, but this need we must also + // clean data from some dangerous html + $ret .= dol_string_onlythesehtmltags(dol_htmlentitiesbr($tmpcontent)); + } + else { + $ret .= dol_escape_htmltag($value); } - else $ret .= dol_escape_htmltag($value); if ($formatfunc && method_exists($object, $formatfunc)) { @@ -461,8 +466,6 @@ class Form */ public function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 3, $incbefore = '', $noencodehtmltext = 0, $tooltiptrigger = '', $forcenowrap = 0) { - global $conf; - if ($incbefore) $text = $incbefore.$text; if (!$htmltext) return $text; @@ -470,9 +473,7 @@ class Form if ($notabs == 2) $tag = 'div'; if ($notabs == 3) $tag = 'span'; // Sanitize tooltip - //$htmltext=str_replace("\\","\\\\",$htmltext); - $htmltext = str_replace("\r", "", $htmltext); - $htmltext = str_replace("\n", "", $htmltext); + $htmltext = str_replace(array("\r", "\n"), '', $htmltext); $extrastyle = ''; if ($direction < 0) { $extracss = ($extracss ? $extracss.' ' : '').($notabs != 3 ? 'inline-block' : ''); $extrastyle = 'padding: 0px; padding-left: 3px !important;'; } @@ -484,7 +485,7 @@ class Form if ($tooltiptrigger == '') { - $htmltext = str_replace('"', """, $htmltext); + $htmltext = str_replace('"', '"', $htmltext); } else { @@ -2109,7 +2110,7 @@ class Form } } - $selectFields = " p.rowid, p.label, p.ref, p.description, p.barcode, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.duration, p.fk_price_expression"; + $selectFields = " p.rowid, p.ref, p.label, p.description, p.barcode, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.duration, p.fk_price_expression"; if (count($warehouseStatusArray)) { $selectFieldsGrouped = ", sum(".$db->ifsql("e.statut IS NULL", "0", "ps.reel").") as stock"; // e.statut is null if there is no record in stock @@ -2400,9 +2401,10 @@ class Form * @param string $selected Preselected value * @param int $hidepriceinlabel Hide price in label * @param string $filterkey Filter key to highlight + * @param int $novirtualstock Do not load virtual stock, even if slow option STOCK_SHOW_VIRTUAL_STOCK_IN_PRODUCTS_COMBO is on. * @return void */ - protected function constructProductListOption(&$objp, &$opt, &$optJson, $price_level, $selected, $hidepriceinlabel = 0, $filterkey = '') + protected function constructProductListOption(&$objp, &$opt, &$optJson, $price_level, $selected, $hidepriceinlabel = 0, $filterkey = '', $novirtualstock = 0) { global $langs, $conf, $user, $db; @@ -2431,6 +2433,7 @@ class Form $outlabel = $objp->label; $outdesc = $objp->description; $outbarcode = $objp->barcode; + $outpbq = empty($objp->price_by_qty_rowid) ? '' : $objp->price_by_qty_rowid; $outtype = $objp->fk_product_type; $outdurationvalue = $outtype == Product::TYPE_SERVICE ?substr($objp->duration, 0, dol_strlen($objp->duration) - 1) : ''; @@ -2478,7 +2481,7 @@ class Form $opt .= ($objp->rowid == $selected) ? ' selected' : ''; if (!empty($objp->price_by_qty_rowid) && $objp->price_by_qty_rowid > 0) { - $opt .= ' pbq="'.$objp->price_by_qty_rowid.'" data-pbq="'.$objp->price_by_qty_rowid.'" data-pbqqty="'.$objp->price_by_qty_quantity.'" data-pbqpercent="'.$objp->price_by_qty_remise_percent.'"'; + $opt .= ' pbq="'.$objp->price_by_qty_rowid.'" data-pbq="'.$objp->price_by_qty_rowid.'" data-pbqup="'.$objp->price_by_qty_unitprice.'" data-pbqbase="'.$objp->price_by_qty_price_base_type.'" data-pbqqty="'.$objp->price_by_qty_quantity.'" data-pbqpercent="'.$objp->price_by_qty_remise_percent.'"'; } if (!empty($conf->stock->enabled) && isset($objp->stock) && ($objp->fk_product_type == Product::TYPE_PRODUCT || !empty($conf->global->STOCK_SUPPORTS_SERVICES))) { @@ -2638,7 +2641,7 @@ class Form } $outval .= $langs->transnoentities("Stock").':'.$objp->stock; $outval .= ''; - if (!empty($conf->global->STOCK_SHOW_VIRTUAL_STOCK_IN_PRODUCTS_COMBO)) // Warning, this option may slow down combo list generation + if (empty($novirtualstock) && !empty($conf->global->STOCK_SHOW_VIRTUAL_STOCK_IN_PRODUCTS_COMBO)) // Warning, this option may slow down combo list generation { $langs->load("stocks"); @@ -2664,7 +2667,7 @@ class Form } $opt .= "\n"; - $optJson = array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'label2'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>price2num($outprice_ht), 'price_ttc'=>price2num($outprice_ttc), 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx, 'qty'=>$outqty, 'discount'=>$outdiscount, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit); + $optJson = array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'label2'=>$outlabel, 'desc'=>$outdesc, 'type'=>$outtype, 'price_ht'=>price2num($outprice_ht), 'price_ttc'=>price2num($outprice_ttc), 'pricebasetype'=>$outpricebasetype, 'tva_tx'=>$outtva_tx, 'qty'=>$outqty, 'discount'=>$outdiscount, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit, 'pbq'=>$outpbq); } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -2736,13 +2739,15 @@ class Form $out = ''; $outarray = array(); + $maxlengtharticle = (empty($conf->global->PRODUCT_MAX_LENGTH_COMBO) ? 48 : $conf->global->PRODUCT_MAX_LENGTH_COMBO); + $langs->load('stocks'); // Units if ($conf->global->PRODUCT_USE_UNITS) { $langs->load('other'); } - $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, p.fk_product_type,"; + $sql = "SELECT p.rowid, p.ref, p.label, p.price, p.duration, p.fk_product_type,"; $sql .= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.quantity, pfp.remise_percent, pfp.remise, pfp.unitprice,"; $sql .= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, pfp.fk_soc, s.nom as name,"; $sql .= " pfp.supplier_reputation"; @@ -2750,7 +2755,7 @@ class Form if ($conf->global->PRODUCT_USE_UNITS) { $sql .= ", u.label as unit_long, u.short_label as unit_short, p.weight, p.weight_units, p.length, p.length_units, p.width, p.width_units, p.height, p.height_units, p.surface, p.surface_units, p.volume, p.volume_units"; } - if (!empty($conf->barcode->enabled)) $sql .= " ,pfp.barcode"; + if (!empty($conf->barcode->enabled)) $sql .= ", pfp.barcode"; $sql .= " FROM ".MAIN_DB_PREFIX."product as p"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product"; if ($socid) $sql .= " AND pfp.fk_soc = ".$socid; @@ -2813,6 +2818,7 @@ class Form $outref = $objp->ref; $outval = ''; + $outbarcode = $objp->barcode; $outqty = 1; $outdiscount = 0; $outtype = $objp->fk_product_type; @@ -2863,12 +2869,22 @@ class Form if ($filterkey && $filterkey != '') $label = preg_replace('/('.preg_quote($filterkey).')/i', '$1', $label, 1); $optlabel = $objp->ref; - if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) + if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) { $optlabel .= ' ('.$objp->ref_fourn.')'; + } + if (!empty($conf->barcode->enabled) && !empty($objp->barcode)) { + $optlabel .= ' ('.$outbarcode.')'; + } + $optlabel .= ' - '.dol_trunc($label, $maxlengtharticle); $outvallabel = $objRef; - if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) + if (!empty($objp->idprodfournprice) && ($objp->ref != $objp->ref_fourn)) { $outvallabel .= ' ('.$objRefFourn.')'; + } + if (!empty($conf->barcode->enabled) && !empty($objp->barcode)) { + $outvallabel .= ' ('.$outbarcode.')'; + } + $outvallabel .= ' - '.dol_trunc($label, $maxlengtharticle); // Units $optlabel .= $outvalUnits; @@ -2891,7 +2907,7 @@ class Form $objp->fprice = $price_result; if ($objp->quantity >= 1) { - $objp->unitprice = $objp->fprice / $objp->quantity; + $objp->unitprice = $objp->fprice / $objp->quantity; // Replace dynamically unitprice } } } @@ -2930,12 +2946,6 @@ class Form $optlabel .= " - ".dol_trunc($objp->name, 8); $outvallabel .= " - ".dol_trunc($objp->name, 8); } - if (!empty($conf->barcode->enabled) && !empty($objp->barcode)) - { - //$optlabel .= " - ".$objp->barcode; - $optlabel .= " - ".$objp->barcode; - $outvallabel .= " - ".$objp->barcode; - } if ($objp->supplier_reputation) { //TODO dictionary @@ -2964,7 +2974,7 @@ class Form if (empty($objp->idprodfournprice) && empty($alsoproductwithnosupplierprice)) $opt .= ' disabled'; if (!empty($objp->idprodfournprice) && $objp->idprodfournprice > 0) { - $opt .= ' pbq="'.$objp->idprodfournprice.'" data-pbq="'.$objp->idprodfournprice.'" data-pbqqty="'.$objp->quantity.'" data-pbqpercent="'.$objp->remise_percent.'"'; + $opt .= ' pbq="'.$objp->idprodfournprice.'" data-pbq="'.$objp->idprodfournprice.'" data-pbqqty="'.$objp->quantity.'" data-pbqup="'.$objp->unitprice.'" data-pbqpercent="'.$objp->remise_percent.'"'; } $opt .= ' data-html="'.dol_escape_htmltag($optlabel).'"'; $opt .= '>'; @@ -2979,7 +2989,7 @@ class Form // "key" value of json key array is used by jQuery automatically as selected value // "label" value of json key array is used by jQuery automatically as text for combo box $out .= $opt; - array_push($outarray, array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'qty'=>$outqty, 'discount'=>$outdiscount, 'type'=>$outtype, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit, 'disabled'=>(empty($objp->idprodfournprice) ?true:false))); + array_push($outarray, array('key'=>$outkey, 'value'=>$outref, 'label'=>$outval, 'qty'=>$outqty, 'up'=>$objp->unitprice, 'discount'=>$outdiscount, 'type'=>$outtype, 'duration_value'=>$outdurationvalue, 'duration_unit'=>$outdurationunit, 'disabled'=>(empty($objp->idprodfournprice) ?true:false))); // Exemple of var_dump $outarray // array(1) {[0]=>array(6) {[key"]=>string(1) "2" ["value"]=>string(3) "ppp" // ["label"]=>string(76) "ppp (fff2) - ppp - 20,00 Euros/1unité (20,00 Euros/unité)" @@ -3023,7 +3033,7 @@ class Form $langs->load('stocks'); - $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.duration, pfp.fk_soc,"; + $sql = "SELECT p.rowid, p.ref, p.label, p.price, p.duration, pfp.fk_soc,"; $sql .= " pfp.ref_fourn, pfp.rowid as idprodfournprice, pfp.price as fprice, pfp.remise_percent, pfp.quantity, pfp.unitprice,"; $sql .= " pfp.fk_supplier_price_expression, pfp.fk_product, pfp.tva_tx, s.nom as name"; $sql .= " FROM ".MAIN_DB_PREFIX."product as p"; @@ -3498,6 +3508,7 @@ class Form // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Return list of payment methods + * Constant MAIN_DEFAULT_PAYMENT_TYPE_ID can used to set default value but scope is all application, probably not what you want. * * @param string $selected Id du mode de paiement pre-selectionne * @param string $htmlname Nom de la zone select @@ -3513,7 +3524,7 @@ class Form public function select_types_paiements($selected = '', $htmlname = 'paiementtype', $filtertype = '', $format = 0, $empty = 1, $noadmininfo = 0, $maxlength = 0, $active = 1, $morecss = '') { // phpcs:enable - global $langs, $user; + global $langs, $user, $conf; dol_syslog(__METHOD__." ".$selected.", ".$htmlname.", ".$filtertype.", ".$format, LOG_DEBUG); @@ -3524,6 +3535,9 @@ class Form $this->load_cache_types_paiements(); + // Set default value if not already set by caller + if (empty($selected) && !empty($conf->global->MAIN_DEFAULT_PAYMENT_TYPE_ID)) $selected = $conf->global->MAIN_DEFAULT_PAYMENT_TYPE_ID; + print ''; $ret .= ''; - foreach($arrayofcriterias as $criterias) { - foreach($criterias as $criteriafamilykey => $criteriafamilyval) { + foreach ($arrayofcriterias as $criterias) { + foreach ($criterias as $criteriafamilykey => $criteriafamilyval) { if (in_array('search_'.$criteriafamilykey, $arrayofinputfieldsalreadyoutput)) continue; if (in_array($criteriafamilykey, array('rowid', 'ref_ext', 'entity', 'extraparams'))) continue; if (in_array($criteriafamilyval['type'], array('date', 'datetime', 'timestamp'))) { diff --git a/htdocs/core/class/html.formaccounting.class.php b/htdocs/core/class/html.formaccounting.class.php index 64e027db537..19fa3f6fb26 100644 --- a/htdocs/core/class/html.formaccounting.class.php +++ b/htdocs/core/class/html.formaccounting.class.php @@ -461,12 +461,12 @@ class FormAccounting extends Form $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping"; $sql .= " WHERE entity IN (".getEntity('accountancy').")"; $sql .= " ORDER BY date_format(doc_date, '%Y')"; - dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG); + dol_syslog(__METHOD__, LOG_DEBUG); $resql = $this->db->query($sql); if (!$resql) { $this->error = "Error ".$this->db->lasterror(); - dol_syslog(get_class($this)."::".__METHOD__.$this->error, LOG_ERR); + dol_syslog(__METHOD__.$this->error, LOG_ERR); return -1; } while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/class/html.formadmin.class.php b/htdocs/core/class/html.formadmin.class.php index 7012b813f7d..21c15b3b7c6 100644 --- a/htdocs/core/class/html.formadmin.class.php +++ b/htdocs/core/class/html.formadmin.class.php @@ -50,7 +50,7 @@ class FormAdmin * @param string $selected Language pre-selected * @param string $htmlname Name of HTML select * @param int $showauto Show 'auto' choice - * @param array $filter Array of keys to exclude in list + * @param array $filter Array of keys to exclude in list (opposite of $onlykeys) * @param string $showempty '1'=Add empty value or string to show * @param int $showwarning Show a warning if language is not complete * @param int $disabled Disable edit of select @@ -58,16 +58,18 @@ class FormAdmin * @param int $showcode 1=Add language code into label at begining, 2=Add language code into label at end * @param int $forcecombo Force to use combo box (so no ajax beautify effect) * @param int $multiselect Make the combo a multiselect + * @param array $onlykeys Show only the following keys (opposite of $filter) + * @param int $mainlangonly 1=Show only main languages ('fr_FR' no' fr_BE', 'es_ES' not 'es_MX', ...) * @return string Return HTML select string with list of languages */ - public function select_language($selected = '', $htmlname = 'lang_id', $showauto = 0, $filter = null, $showempty = '', $showwarning = 0, $disabled = 0, $morecss = '', $showcode = 0, $forcecombo = 0, $multiselect = 0) + public function select_language($selected = '', $htmlname = 'lang_id', $showauto = 0, $filter = null, $showempty = '', $showwarning = 0, $disabled = 0, $morecss = '', $showcode = 0, $forcecombo = 0, $multiselect = 0, $onlykeys = array(), $mainlangonly = 0) { // phpcs:enable global $conf, $langs; if (!empty($conf->global->MAIN_DEFAULT_LANGUAGE_FILTER)) $filter[$conf->global->MAIN_DEFAULT_LANGUAGE_FILTER] = 1; - $langs_available=$langs->get_available_languages(DOL_DOCUMENT_ROOT, 12); + $langs_available=$langs->get_available_languages(DOL_DOCUMENT_ROOT, 12, 0, $mainlangonly); $out=''; @@ -94,19 +96,28 @@ class FormAdmin { $valuetoshow=$value; if ($showcode == 1) $valuetoshow=$key.' - '.$value; - if ($showcode == 2) $valuetoshow=$value.' ('.$key.')'; + if ($showcode == 2) { + if ($mainlangonly) $valuetoshow=$value.' ('.preg_replace('/[_-].*$/', '', $key).')'; + else $valuetoshow=$value.' ('.$key.')'; + } - if ($filter && is_array($filter) && array_key_exists($key, $filter)) - { + $keytouse = $key; + if ($mainlangonly) $keytouse = preg_replace('/[_-].*$/', '', $key); + + if ($filter && is_array($filter) && array_key_exists($keytouse, $filter)) { continue; } - elseif ($selected == $key) + if ($onlykeys && is_array($onlykeys) && ! array_key_exists($keytouse, $onlykeys)) { + continue; + } + + if ($selected == $keytouse) { - $out.= ''; + $out.= ''; } else { - $out.= ''; + $out.= ''; } } $out.= ''; @@ -134,49 +145,49 @@ class FormAdmin public function select_menu($selected, $htmlname, $dirmenuarray, $moreattrib = '') { // phpcs:enable - global $langs,$conf; + global $langs, $conf; // Clean parameters // Check parameters - if (! is_array($dirmenuarray)) return -1; + if (!is_array($dirmenuarray)) return -1; - $menuarray=array(); + $menuarray = array(); foreach ($conf->file->dol_document_root as $dirroot) { - foreach($dirmenuarray as $dirtoscan) + foreach ($dirmenuarray as $dirtoscan) { - $dir=$dirroot.$dirtoscan; + $dir = $dirroot.$dirtoscan; //print $dir.'
'; if (is_dir($dir)) { - $handle=opendir($dir); + $handle = opendir($dir); if (is_resource($handle)) { - while (($file = readdir($handle))!==false) + while (($file = readdir($handle)) !== false) { if (is_file($dir."/".$file) && substr($file, 0, 1) <> '.' && substr($file, 0, 3) <> 'CVS' && substr($file, 0, 5) != 'index') { - if (preg_match('/lib\.php$/i', $file)) continue; // We exclude library files - if (preg_match('/eldy_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files - if (preg_match('/auguria_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files - if (preg_match('/smartphone_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files + if (preg_match('/lib\.php$/i', $file)) continue; // We exclude library files + if (preg_match('/eldy_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files + if (preg_match('/auguria_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files + if (preg_match('/smartphone_(backoffice|frontoffice)\.php$/i', $file)) continue; // We exclude all menu manager files - $filelib=preg_replace('/\.php$/i', '', $file); - $prefix=''; + $filelib = preg_replace('/\.php$/i', '', $file); + $prefix = ''; // 0=Recommanded, 1=Experimental, 2=Developpement, 3=Other - if (preg_match('/^eldy/i', $file)) $prefix='0'; - elseif (preg_match('/^smartphone/i', $file)) $prefix='2'; - else $prefix='3'; + if (preg_match('/^eldy/i', $file)) $prefix = '0'; + elseif (preg_match('/^smartphone/i', $file)) $prefix = '2'; + else $prefix = '3'; if ($file == $selected) { - $menuarray[$prefix.'_'.$file]=''; + $menuarray[$prefix.'_'.$file] = ''; } else { - $menuarray[$prefix.'_'.$file]=''; + $menuarray[$prefix.'_'.$file] = ''; } } } @@ -188,26 +199,26 @@ class FormAdmin ksort($menuarray); // Output combo list of menus - print ''; + $oldprefix = ''; foreach ($menuarray as $key => $val) { - $tab=explode('_', $key); - $newprefix=$tab[0]; - if ($newprefix=='1' && ($conf->global->MAIN_FEATURES_LEVEL < 1)) continue; - if ($newprefix=='2' && ($conf->global->MAIN_FEATURES_LEVEL < 2)) continue; + $tab = explode('_', $key); + $newprefix = $tab[0]; + if ($newprefix == '1' && ($conf->global->MAIN_FEATURES_LEVEL < 1)) continue; + if ($newprefix == '2' && ($conf->global->MAIN_FEATURES_LEVEL < 2)) continue; if ($newprefix != $oldprefix) // Add separators { // Affiche titre print ''; - $oldprefix=$newprefix; + $oldprefix = $newprefix; } - print $val."\n"; // Show menu entry + print $val."\n"; // Show menu entry } print ''; } @@ -224,37 +235,37 @@ class FormAdmin public function select_menu_families($selected, $htmlname, $dirmenuarray) { // phpcs:enable - global $langs,$conf; + global $langs, $conf; //$expdevmenu=array('smartphone_backoffice.php','smartphone_frontoffice.php'); // Menu to disable if $conf->global->MAIN_FEATURES_LEVEL is not set - $expdevmenu=array(); + $expdevmenu = array(); - $menuarray=array(); + $menuarray = array(); - foreach($dirmenuarray as $dirmenu) + foreach ($dirmenuarray as $dirmenu) { foreach ($conf->file->dol_document_root as $dirroot) { - $dir=$dirroot.$dirmenu; + $dir = $dirroot.$dirmenu; if (is_dir($dir)) { - $handle=opendir($dir); + $handle = opendir($dir); if (is_resource($handle)) { - while (($file = readdir($handle))!==false) + while (($file = readdir($handle)) !== false) { if (is_file($dir."/".$file) && substr($file, 0, 1) <> '.' && substr($file, 0, 3) <> 'CVS') { - $filelib=preg_replace('/(_backoffice|_frontoffice)?\.php$/i', '', $file); + $filelib = preg_replace('/(_backoffice|_frontoffice)?\.php$/i', '', $file); if (preg_match('/^index/i', $filelib)) continue; if (preg_match('/^default/i', $filelib)) continue; if (preg_match('/^empty/i', $filelib)) continue; if (preg_match('/\.lib/i', $filelib)) continue; if (empty($conf->global->MAIN_FEATURES_LEVEL) && in_array($file, $expdevmenu)) continue; - $menuarray[$filelib]=1; + $menuarray[$filelib] = 1; } - $menuarray['all']=1; + $menuarray['all'] = 1; } closedir($handle); } @@ -266,11 +277,11 @@ class FormAdmin // Affichage liste deroulante des menus print ''; + $out .= ''; + $out .= ''; return $out; } diff --git a/htdocs/core/class/html.formcategory.class.php b/htdocs/core/class/html.formcategory.class.php new file mode 100644 index 00000000000..4dd8bed247b --- /dev/null +++ b/htdocs/core/class/html.formcategory.class.php @@ -0,0 +1,58 @@ + + * + * 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/core/class/html.formcategory.class.php + * \ingroup core + * \brief File of class to build HTML component for category filtering + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; + +class FormCategory extends Form +{ + /** + * Return a HTML filter box for a list filter view + * + * @param string $type The categorie type (e.g Categorie::TYPE_WAREHOUSE) + * @param Array $preSelected A list with the elements that should pre-selected + * @return string A HTML filter box (Note: selected results can get with GETPOST("search_category_".$type."_list")) + */ + public function getFilterBox($type, $preSelected) + { + // phpcs:enable + global $langs; + + if (empty($preSelected) || !is_array($preSelected)) + { + $preSelected = array(); + } + + $htmlName = "search_category_".$type."_list"; + + $categoryArray = $this->select_all_categories($type, "", "", 64, 0, 1); + $categoryArray[-2] = "- ".$langs->trans('NotCategorized')." -"; + + $filter = ''; + $filter .= '
'; + $filter .= $langs->trans('Categories').": "; + $filter .= Form::multiselectarray($htmlName, $categoryArray, $preSelected, 0, 0, "minwidth300"); + $filter .= "
"; + + return $filter; + } +} diff --git a/htdocs/core/class/html.formcompany.class.php b/htdocs/core/class/html.formcompany.class.php index a08694560ec..e084028b430 100644 --- a/htdocs/core/class/html.formcompany.class.php +++ b/htdocs/core/class/html.formcompany.class.php @@ -249,8 +249,7 @@ class FormCompany extends Form } } - if ((!empty($selected) && $selected == $obj->rowid) - || (empty($selected) && !empty($conf->global->MAIN_FORCE_DEFAULT_STATE_ID) && $conf->global->MAIN_FORCE_DEFAULT_STATE_ID == $obj->rowid)) + if (!empty($selected) && $selected == $obj->rowid) { $out .= '
'; // maring bottom must be same than into print_barre_list + $return .= '
'; // maring bottom must be same than into print_barre_list + $return .= ''; if ($picto) $return .= ''; $return .= ''; + if ($picto && $titre) print ''; print ''; // Center @@ -5344,10 +5383,10 @@ function get_default_localtax($thirdparty_seller, $thirdparty_buyer, $local, $id /** * Return yes or no in current language * - * @param string $yesno Value to test (1, 'yes', 'true' or 0, 'no', 'false') - * @param integer $case 1=Yes/No, 0=yes/no, 2=Disabled checkbox, 3=Disabled checkbox + Yes/No - * @param int $color 0=texte only, 1=Text is formated with a color font style ('ok' or 'error'), 2=Text is formated with 'ok' color. - * @return string HTML string + * @param string|int $yesno Value to test (1, 'yes', 'true' or 0, 'no', 'false') + * @param integer $case 1=Yes/No, 0=yes/no, 2=Disabled checkbox, 3=Disabled checkbox + Yes/No + * @param int $color 0=texte only, 1=Text is formated with a color font style ('ok' or 'error'), 2=Text is formated with 'ok' color. + * @return string HTML string */ function yn($yesno, $case = 1, $color = 0) { @@ -5559,22 +5598,27 @@ function dol_string_nohtmltag($stringtoclean, $removelinefeed = 1, $pagecodeto = /** * Clean a string to keep only desirable HTML tags. * - * @param string $stringtoclean String to clean - * @return string String cleaned + * @param string $stringtoclean String to clean + * @param string $cleanalsosomestyles Clean also some tags + * @return string String cleaned * * @see dol_escape_htmltag() strip_tags() dol_string_nohtmltag() dol_string_neverthesehtmltags() */ -function dol_string_onlythesehtmltags($stringtoclean) +function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1) { $allowed_tags = array( - "html", "head", "meta", "body", "article", "a", "b", "br", "div", "em", "font", "img", "ins", "hr", "i", "li", "link", - "ol", "p", "s", "section", "span", "strong", "title", + "html", "head", "meta", "body", "article", "a", "abbr", "b", "blockquote", "br", "cite", "div", "dl", "dd", "dt", "em", "font", "img", "ins", "hr", "i", "li", "link", + "ol", "p", "q", "s", "section", "span", "strike", "strong", "title", "table", "tr", "th", "td", "u", "ul" ); - $allowed_tags_string = join("><", $allowed_tags); $allowed_tags_string = preg_replace('/^>/', '', $allowed_tags_string); $allowed_tags_string = preg_replace('/<$/', '', $allowed_tags_string); + $allowed_tags_string = '<'.$allowed_tags_string.'>'; + + if ($cleanalsosomestyles) { + $stringtoclean = preg_replace('/position\s*:\s*(absolute|fixed)\s*!\s*important/', '', $stringtoclean); // Note: If hacker try to introduce css comment into string to avoid this, string should be encoded by the dol_htmlentitiesbr so be harmless + } $temp = strip_tags($stringtoclean, $allowed_tags_string); @@ -5583,14 +5627,16 @@ function dol_string_onlythesehtmltags($stringtoclean) /** * Clean a string from some undesirable HTML tags. + * Note. Not enough secured as dol_string_onlythesehtmltags(). * - * @param string $stringtoclean String to clean - * @param array $disallowed_tags Array of tags not allowed - * @return string String cleaned + * @param string $stringtoclean String to clean + * @param array $disallowed_tags Array of tags not allowed + * @param string $cleanalsosomestyles Clean also some tags + * @return string String cleaned * * @see dol_escape_htmltag() strip_tags() dol_string_nohtmltag() dol_string_onlythesehtmltags() */ -function dol_string_neverthesehtmltags($stringtoclean, $disallowed_tags = array('textarea')) +function dol_string_neverthesehtmltags($stringtoclean, $disallowed_tags = array('textarea'), $cleanalsosomestyles = 0) { $temp = $stringtoclean; foreach ($disallowed_tags as $tagtoremove) @@ -5598,6 +5644,11 @@ function dol_string_neverthesehtmltags($stringtoclean, $disallowed_tags = array( $temp = preg_replace('/<\/?'.$tagtoremove.'>/', '', $temp); $temp = preg_replace('/<\/?'.$tagtoremove.'\s+[^>]*>/', '', $temp); } + + if ($cleanalsosomestyles) { + $temp = preg_replace('/position\s*:\s*(absolute|fixed)\s*!\s*important/', '', $temp); // Note: If hacker try to introduce css comment into string to avoid this, string should be encoded by the dol_htmlentitiesbr so be harmless + } + return $temp; } @@ -5970,7 +6021,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, $substitutionarray = array_merge($substitutionarray, array( '__USER_ID__' => (string) $user->id, '__USER_LOGIN__' => (string) $user->login, - '__USER_LASTNAME__' => (string) $user->lastname, + '__USER_EMAIL__' => (string) $user->email, + '__USER_LASTNAME__' => (string) $user->lastname, '__USER_FIRSTNAME__' => (string) $user->firstname, '__USER_FULLNAME__' => (string) $user->getFullName($outputlangs), '__USER_SUPERVISOR_ID__' => (string) ($user->fk_user ? $user->fk_user : '0'), @@ -6095,7 +6147,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, $substitutionarray['__REFCLIENT__'] = (isset($object->ref_client) ? $object->ref_client : (isset($object->ref_customer) ? $object->ref_customer : null)); $substitutionarray['__REFSUPPLIER__'] = (isset($object->ref_supplier) ? $object->ref_supplier : null); $substitutionarray['__SUPPLIER_ORDER_DATE_DELIVERY__'] = (isset($object->date_livraison) ? dol_print_date($object->date_livraison, 'day', 0, $outputlangs) : ''); - $substitutionarray['__SUPPLIER_ORDER_DELAY_DELIVERY__'] = $outputlangs->transnoentities("AvailabilityType".$object->availability_code)!=('AvailabilityType'.$object->availability_code)?$outputlangs->transnoentities("AvailabilityType".$object->availability_code):$outputlangs->convToOutputCharset(isset($object->availability)?$object->availability:''); + $substitutionarray['__SUPPLIER_ORDER_DELAY_DELIVERY__'] = $outputlangs->transnoentities("AvailabilityType".$object->availability_code) != ('AvailabilityType'.$object->availability_code) ? $outputlangs->transnoentities("AvailabilityType".$object->availability_code) : $outputlangs->convToOutputCharset(isset($object->availability) ? $object->availability : ''); $birthday = dol_print_date($object->birth, 'day'); @@ -6271,6 +6323,10 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null, $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__'] = $object->getLastMainDocLink($object->element); } else $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__'] = ''; + + if (is_object($object) && $object->element == 'propal') $substitutionarray['__URL_PROPOSAL__'] = DOL_MAIN_URL_ROOT . "/comm/propal/card.php?id=" . $object->id; + if (is_object($object) && $object->element == 'commande') $substitutionarray['__URL_ORDER__'] = DOL_MAIN_URL_ROOT . "/commande/card.php?id=" . $object->id; + if (is_object($object) && $object->element == 'facture') $substitutionarray['__URL_INVOICE__'] = DOL_MAIN_URL_ROOT . "/compta/facture/card.php?id=" . $object->id; } } } @@ -6910,6 +6966,24 @@ function utf8_check($str) return true; } +/** + * Check if a string is in ASCII + * + * @param string $str String to check + * @return boolean True if string is ASCII, False if not (byte value > 0x7F) + */ +function ascii_check($str) +{ + if (function_exists('mb_check_encoding')) { + //if (mb_detect_encoding($str, 'ASCII', true) return false; + if (!mb_check_encoding($str, 'ASCII')) return false; + } else { + if (preg_match('/[^\x00-\x7f]/', $str)) return false; // Contains a byte > 7f + } + + return true; +} + /** * Return a string encoded into OS filesystem encoding. This function is used to define @@ -7571,15 +7645,12 @@ function printCommonFooter($zone = 'private') $micro_end_time = microtime(true); print ' - Build time: '.ceil(1000 * ($micro_end_time - $micro_start_time)).' ms'; } - if (function_exists("memory_get_usage")) - { - print ' - Mem: '.memory_get_usage(); + + if (function_exists("memory_get_usage")) { + print ' - Mem: '.memory_get_usage(); // Do not use true here, it seems it takes the peak amount } - if (function_exists("xdebug_memory_usage")) - { - print ' - XDebug time: '.ceil(1000 * xdebug_time_index()).' ms'; - print ' - XDebug mem: '.xdebug_memory_usage(); - print ' - XDebug mem peak: '.xdebug_peak_memory_usage(); + if (function_exists("memory_get_peak_usage")) { + print ' - Real mem peak: '.memory_get_peak_usage(true); } if (function_exists("zend_loader_file_encoded")) { @@ -7796,12 +7867,11 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0) } else // $mode=0 { - $textcrit = ''; $tmpcrits = explode('|', $crit); $i3 = 0; foreach ($tmpcrits as $tmpcrit) { - if (empty($tmpcrit)) continue; + if ($tmpcrit !== '0' && empty($tmpcrit)) continue; $newres .= (($i2 > 0 || $i3 > 0) ? ' OR ' : ''); @@ -7992,7 +8062,7 @@ function dol_mimetype($file, $default = 'application/octet-stream', $mode = 0) if (preg_match('/\.bas$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'text.png'; $srclang = 'bas'; $famime = 'file-code-o'; } if (preg_match('/\.(c)$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'text.png'; $srclang = 'c'; $famime = 'file-code-o'; } if (preg_match('/\.(cpp)$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'text.png'; $srclang = 'cpp'; $famime = 'file-code-o'; } - if (preg_match('/\.cs$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'text.png'; $srclang = 'cs'; $famime = 'file-code-o'; } + if (preg_match('/\.cs$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'text.png'; $srclang = 'cs'; $famime = 'file-code-o'; } if (preg_match('/\.(h)$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'text.png'; $srclang = 'h'; $famime = 'file-code-o'; } if (preg_match('/\.(java|jsp)$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'text.png'; $srclang = 'java'; $famime = 'file-code-o'; } if (preg_match('/\.php([0-9]{1})?$/i', $tmpfile)) { $mime = 'text/plain'; $imgmime = 'php.png'; $srclang = 'php'; $famime = 'file-code-o'; } @@ -8549,6 +8619,160 @@ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $u return $button; } +/** + * Get an array with properties of an element. + * Called by fetchObjectByElement. + * + * @param string $element_type Element type (Value of $object->element). Example: 'action', 'facture', 'project_task' or 'object@mymodule'... + * @return array (module, classpath, element, subelement, classfile, classname) + */ +function getElementProperties($element_type) +{ + $regs = array(); + + $classfile = $classname = $classpath = ''; + + // Parse element/subelement (ex: project_task) + $module = $element_type; + $element = $element_type; + $subelement = $element_type; + + // If we ask an resource form external module (instead of default path) + if (preg_match('/^([^@]+)@([^@]+)$/i', $element_type, $regs)) { + $element = $subelement = $regs[1]; + $module = $regs[2]; + } + + //print '
1. element : '.$element.' - module : '.$module .'
'; + if (preg_match('/^([^_]+)_([^_]+)/i', $element, $regs)) { + $module = $element = $regs[1]; + $subelement = $regs[2]; + } + + // For compat + if ($element_type == "action") { + $classpath = 'comm/action/class'; + $subelement = 'Actioncomm'; + $module = 'agenda'; + } + + // To work with non standard path + if ($element_type == 'facture' || $element_type == 'invoice') { + $classpath = 'compta/facture/class'; + $module = 'facture'; + $subelement = 'facture'; + } + if ($element_type == 'commande' || $element_type == 'order') { + $classpath = 'commande/class'; + $module = 'commande'; + $subelement = 'commande'; + } + if ($element_type == 'propal') { + $classpath = 'comm/propal/class'; + } + if ($element_type == 'supplier_proposal') { + $classpath = 'supplier_proposal/class'; + } + if ($element_type == 'shipping') { + $classpath = 'expedition/class'; + $subelement = 'expedition'; + $module = 'expedition_bon'; + } + if ($element_type == 'delivery') { + $classpath = 'livraison/class'; + $subelement = 'livraison'; + $module = 'livraison_bon'; + } + if ($element_type == 'contract') { + $classpath = 'contrat/class'; + $module = 'contrat'; + $subelement = 'contrat'; + } + if ($element_type == 'member') { + $classpath = 'adherents/class'; + $module = 'adherent'; + $subelement = 'adherent'; + } + if ($element_type == 'cabinetmed_cons') { + $classpath = 'cabinetmed/class'; + $module = 'cabinetmed'; + $subelement = 'cabinetmedcons'; + } + if ($element_type == 'fichinter') { + $classpath = 'fichinter/class'; + $module = 'ficheinter'; + $subelement = 'fichinter'; + } + if ($element_type == 'dolresource' || $element_type == 'resource') { + $classpath = 'resource/class'; + $module = 'resource'; + $subelement = 'dolresource'; + } + if ($element_type == 'propaldet') { + $classpath = 'comm/propal/class'; + $module = 'propal'; + $subelement = 'propaleligne'; + } + if ($element_type == 'order_supplier') { + $classpath = 'fourn/class'; + $module = 'fournisseur'; + $subelement = 'commandefournisseur'; + $classfile = 'fournisseur.commande'; + } + if ($element_type == 'invoice_supplier') { + $classpath = 'fourn/class'; + $module = 'fournisseur'; + $subelement = 'facturefournisseur'; + $classfile = 'fournisseur.facture'; + } + if ($element_type == "service") { + $classpath = 'product/class'; + $subelement = 'product'; + } + + if (empty($classfile)) $classfile = strtolower($subelement); + if (empty($classname)) $classname = ucfirst($subelement); + if (empty($classpath)) $classpath = $module.'/class'; + + $element_properties = array( + 'module' => $module, + 'classpath' => $classpath, + 'element' => $element, + 'subelement' => $subelement, + 'classfile' => $classfile, + 'classname' => $classname + ); + return $element_properties; +} + +/** + * Fetch an object from its id and element_type + * Inclusion of classes is automatic + * + * @param int $element_id Element id + * @param string $element_type Element type + * @param string $element_ref Element ref (Use this or element_id but not both) + * @return int|object object || 0 || -1 if error + */ +function fetchObjectByElement($element_id, $element_type, $element_ref = '') +{ + global $conf, $db; + + $element_prop = getElementProperties($element_type); + if (is_array($element_prop) && $conf->{$element_prop['module']}->enabled) + { + dol_include_once('/'.$element_prop['classpath'].'/'.$element_prop['classfile'].'.class.php'); + + $objecttmp = new $element_prop['classname']($db); + $ret = $objecttmp->fetch($element_id, $element_ref); + if ($ret >= 0) + { + return $objecttmp; + } + } + return 0; +} + /** * Return if a file can contains executable content * diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 98d636e97dd..531e0fe242c 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -2058,157 +2058,6 @@ function cleanCorruptedTree($db, $tabletocleantree, $fieldfkparent) } } -/** - * Get an array with properties of an element - * - * @param string $element_type Element type: 'action', 'facture', 'project_task' or 'object@mymodule'... - * @return array (module, classpath, element, subelement, classfile, classname) - */ -function getElementProperties($element_type) -{ - $regs = array(); - - // Parse element/subelement (ex: project_task) - $module = $element_type; - $element = $element_type; - $subelement = $element_type; - - // If we ask an resource form external module (instead of default path) - if (preg_match('/^([^@]+)@([^@]+)$/i', $element_type, $regs)) { - $element = $subelement = $regs[1]; - $module = $regs[2]; - } - - //print '
1. element : '.$element.' - module : '.$module .'
'; - if (preg_match('/^([^_]+)_([^_]+)/i', $element, $regs)) { - $module = $element = $regs[1]; - $subelement = $regs[2]; - } - - // For compat - if ($element_type == "action") { - $classpath = 'comm/action/class'; - $subelement = 'Actioncomm'; - $module = 'agenda'; - } - - // To work with non standard path - if ($element_type == 'facture' || $element_type == 'invoice') { - $classpath = 'compta/facture/class'; - $module = 'facture'; - $subelement = 'facture'; - } - if ($element_type == 'commande' || $element_type == 'order') { - $classpath = 'commande/class'; - $module = 'commande'; - $subelement = 'commande'; - } - if ($element_type == 'propal') { - $classpath = 'comm/propal/class'; - } - if ($element_type == 'supplier_proposal') { - $classpath = 'supplier_proposal/class'; - } - if ($element_type == 'shipping') { - $classpath = 'expedition/class'; - $subelement = 'expedition'; - $module = 'expedition_bon'; - } - if ($element_type == 'delivery') { - $classpath = 'livraison/class'; - $subelement = 'livraison'; - $module = 'livraison_bon'; - } - if ($element_type == 'contract') { - $classpath = 'contrat/class'; - $module = 'contrat'; - $subelement = 'contrat'; - } - if ($element_type == 'member') { - $classpath = 'adherents/class'; - $module = 'adherent'; - $subelement = 'adherent'; - } - if ($element_type == 'cabinetmed_cons') { - $classpath = 'cabinetmed/class'; - $module = 'cabinetmed'; - $subelement = 'cabinetmedcons'; - } - if ($element_type == 'fichinter') { - $classpath = 'fichinter/class'; - $module = 'ficheinter'; - $subelement = 'fichinter'; - } - if ($element_type == 'dolresource' || $element_type == 'resource') { - $classpath = 'resource/class'; - $module = 'resource'; - $subelement = 'dolresource'; - } - if ($element_type == 'propaldet') { - $classpath = 'comm/propal/class'; - $module = 'propal'; - $subelement = 'propaleligne'; - } - if ($element_type == 'order_supplier') { - $classpath = 'fourn/class'; - $module = 'fournisseur'; - $subelement = 'commandefournisseur'; - $classfile = 'fournisseur.commande'; - } - if ($element_type == 'invoice_supplier') { - $classpath = 'fourn/class'; - $module = 'fournisseur'; - $subelement = 'facturefournisseur'; - $classfile = 'fournisseur.facture'; - } - if ($element_type == "service") { - $classpath = 'product/class'; - $subelement = 'product'; - } - - if (!isset($classfile)) $classfile = strtolower($subelement); - if (!isset($classname)) $classname = ucfirst($subelement); - if (!isset($classpath)) $classpath = $module.'/class'; - - $element_properties = array( - 'module' => $module, - 'classpath' => $classpath, - 'element' => $element, - 'subelement' => $subelement, - 'classfile' => $classfile, - 'classname' => $classname - ); - return $element_properties; -} - -/** - * Fetch an object from its id and element_type - * Inclusion of classes is automatic - * - * @param int $element_id Element id - * @param string $element_type Element type - * @param string $element_ref Element ref (Use this or element_id but not both) - * @return int|object object || 0 || -1 if error - */ -function fetchObjectByElement($element_id, $element_type, $element_ref = '') -{ - global $conf, $db; - - $element_prop = getElementProperties($element_type); - if (is_array($element_prop) && $conf->{$element_prop['module']}->enabled) - { - dol_include_once('/'.$element_prop['classpath'].'/'.$element_prop['classfile'].'.class.php'); - - $objecttmp = new $element_prop['classname']($db); - $ret = $objecttmp->fetch($element_id, $element_ref); - if ($ret >= 0) - { - return $objecttmp; - } - } - return 0; -} - /** * Convert an array with RGB value into hex RGB value. @@ -2377,7 +2226,7 @@ function colorLighten($hex, $percent) /** * @param string $hex color in hex * @param float $alpha 0 to 1 to add alpha channel - * @param bool $returnArray Array set to 1 to return an array instead of string + * @param bool $returnArray true=return an array instead, false=return string * @return string|array String or array */ function colorHexToRgb($hex, $alpha = false, $returnArray = false) diff --git a/htdocs/core/lib/functionsnumtoword.lib.php b/htdocs/core/lib/functionsnumtoword.lib.php index 94479fe2c28..26db2bbec90 100644 --- a/htdocs/core/lib/functionsnumtoword.lib.php +++ b/htdocs/core/lib/functionsnumtoword.lib.php @@ -25,7 +25,7 @@ /** * Function to return number in text. - * + * May use module NUMBERWORDS if found. * * @param float $num Number to convert * @param Translate $langs Language @@ -38,15 +38,15 @@ function dol_convertToWord($num, $langs, $currency = false, $centimes = false) global $conf; $num = str_replace(array(',', ' '), '', trim($num)); - if (! $num) { + if (!$num) { return false; } if ($centimes && strlen($num) == 1) { - $num = $num*10; + $num = $num * 10; } - if (! empty($conf->global->MAIN_MODULE_NUMBERWORDS)) { + if (!empty($conf->global->MAIN_MODULE_NUMBERWORDS)) { if ($currency) { $type = 1; } else { @@ -106,24 +106,24 @@ function dol_convertToWord($num, $langs, $currency = false, $centimes = false) $num_length = strlen($num); $levels = (int) (($num_length + 2) / 3); $max_length = $levels * 3; - $num = substr('00' . $num, -$max_length); + $num = substr('00'.$num, -$max_length); $num_levels = str_split($num, 3); $nboflevels = count($num_levels); for ($i = 0; $i < $nboflevels; $i++) { $levels--; $hundreds = (int) ($num_levels[$i] / 100); - $hundreds = ($hundreds ? ' ' . $list1[$hundreds] . ' '.$langs->transnoentities('hundred') . ( $hundreds == 1 ? '' : 's' ) . ' ': ''); + $hundreds = ($hundreds ? ' '.$list1[$hundreds].' '.$langs->transnoentities('hundred').($hundreds == 1 ? '' : 's').' ' : ''); $tens = (int) ($num_levels[$i] % 100); $singles = ''; - if ( $tens < 20 ) { - $tens = ($tens ? ' ' . $list1[$tens] . ' ' : '' ); + if ($tens < 20) { + $tens = ($tens ? ' '.$list1[$tens].' ' : ''); } else { $tens = (int) ($tens / 10); - $tens = ' ' . $list2[$tens] . ' '; + $tens = ' '.$list2[$tens].' '; $singles = (int) ($num_levels[$i] % 10); - $singles = ' ' . $list1[$singles] . ' '; + $singles = ' '.$list1[$singles].' '; } - $words[] = $hundreds . $tens . $singles . ( ( $levels && ( int ) ( $num_levels[$i] ) ) ? ' ' . $list3[$levels] . ' ' : '' ); + $words[] = $hundreds.$tens.$singles.(($levels && (int) ($num_levels[$i])) ? ' '.$list3[$levels].' ' : ''); } //end for loop $commas = count($words); if ($commas > 1) { @@ -133,15 +133,15 @@ function dol_convertToWord($num, $langs, $currency = false, $centimes = false) // Delete multi whitespaces $concatWords = trim(preg_replace('/[ ]+/', ' ', $concatWords)); - if(!empty($currency)) { + if (!empty($currency)) { $concatWords .= ' '.$currency; } // If we need to write cents call again this function for cents - if(!empty($TNum[1])) { - if(!empty($currency)) $concatWords .= ' '.$langs->transnoentities('and'); + if (!empty($TNum[1])) { + if (!empty($currency)) $concatWords .= ' '.$langs->transnoentities('and'); $concatWords .= ' '.dol_convertToWord($TNum[1], $langs, $currency, true); - if(!empty($currency)) $concatWords .= ' '.$langs->transnoentities('centimes'); + if (!empty($currency)) $concatWords .= ' '.$langs->transnoentities('centimes'); } return $concatWords; } @@ -165,35 +165,35 @@ function dolNumberToWord($numero, $langs, $numorcurrency = 'number') return -1; // Get 2 decimals to cents, another functions round or truncate $strnumber = number_format($numero, 10); - $len=strlen($strnumber); - for ($i=0; $i<$len; $i++) + $len = strlen($strnumber); + for ($i = 0; $i < $len; $i++) { - if ($strnumber[$i]=='.') { - $parte_decimal = $strnumber[$i+1].$strnumber[$i+2]; + if ($strnumber[$i] == '.') { + $parte_decimal = $strnumber[$i + 1].$strnumber[$i + 2]; break; } } /*In dolibarr 3.6.2 (my current version) doesn't have $langs->default and in case exist why ask $lang like a parameter?*/ - if (((is_object($langs) && $langs->default == 'es_MX') || (! is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency') + if (((is_object($langs) && $langs->default == 'es_MX') || (!is_object($langs) && $langs == 'es_MX')) && $numorcurrency == 'currency') { - if ($numero>=1 && $numero<2) { + if ($numero >= 1 && $numero < 2) { return ("UN PESO ".$parte_decimal." / 100 M.N."); } - elseif ($numero>=0 && $numero<1){ + elseif ($numero >= 0 && $numero < 1) { return ("CERO PESOS ".$parte_decimal." / 100 M.N."); } - elseif ($numero>=1000000 && $numero<1000001){ + elseif ($numero >= 1000000 && $numero < 1000001) { return ("UN MILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); } - elseif ($numero>=1000000000000 && $numero<1000000000001){ + elseif ($numero >= 1000000000000 && $numero < 1000000000001) { return ("UN BILLÓN DE PESOS ".$parte_decimal." / 100 M.N."); } else { - $entexto =""; + $entexto = ""; $number = $numero; - if ($number >= 1000000000){ + if ($number >= 1000000000) { $CdMMillon = (int) ($numero / 100000000000); $numero = $numero - $CdMMillon * 100000000000; $DdMMillon = (int) ($numero / 10000000000); @@ -203,7 +203,7 @@ function dolNumberToWord($numero, $langs, $numorcurrency = 'number') $entexto .= hundreds2text($CdMMillon, $DdMMillon, $UdMMillon); $entexto .= " MIL "; } - if ($number >= 1000000){ + if ($number >= 1000000) { $CdMILLON = (int) ($numero / 100000000); $numero = $numero - $CdMILLON * 100000000; $DdMILLON = (int) ($numero / 10000000); @@ -211,7 +211,7 @@ function dolNumberToWord($numero, $langs, $numorcurrency = 'number') $udMILLON = (int) ($numero / 1000000); $numero = $numero - $udMILLON * 1000000; $entexto .= hundreds2text($CdMILLON, $DdMILLON, $udMILLON); - if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON==1) + if (!$CdMMillon && !$DdMMillon && !$UdMMillon && !$CdMILLON && !$DdMILLON && $udMILLON == 1) $entexto .= " MILLÓN "; else $entexto .= " MILLONES "; @@ -232,7 +232,7 @@ function dolNumberToWord($numero, $langs, $numorcurrency = 'number') $d = (int) ($numero / 10); $u = (int) $numero - $d * 10; $entexto .= hundreds2text($c, $d, $u); - if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number>1000000) + if (!$cdm && !$ddm && !$udm && !$c && !$d && !$u && $number > 1000000) $entexto .= " DE"; $entexto .= " PESOS ".$parte_decimal." / 100 M.N."; } @@ -250,40 +250,40 @@ function dolNumberToWord($numero, $langs, $numorcurrency = 'number') */ function hundreds2text($hundreds, $tens, $units) { - if ($hundreds==1 && $tens==0 && $units==0){ + if ($hundreds == 1 && $tens == 0 && $units == 0) { return "CIEN"; } - $centenas = array("CIENTO","DOSCIENTOS","TRESCIENTOS","CUATROCIENTOS","QUINIENTOS","SEISCIENTOS","SETECIENTOS","OCHOCIENTOS","NOVECIENTOS"); - $decenas = array("","","TREINTA ","CUARENTA ","CINCUENTA ","SESENTA ","SETENTA ","OCHENTA ","NOVENTA "); - $veintis = array("VEINTE","VEINTIUN","VEINTIDÓS","VEINTITRÉS","VEINTICUATRO","VEINTICINCO","VEINTISÉIS","VEINTISIETE","VEINTIOCHO","VEINTINUEVE"); - $diecis = array("DIEZ","ONCE","DOCE","TRECE","CATORCE","QUINCE","DIECISÉIS","DIECISIETE","DIECIOCHO","DIECINUEVE"); - $unidades = array("UN","DOS","TRES","CUATRO","CINCO","SEIS","SIETE","OCHO","NUEVE"); + $centenas = array("CIENTO", "DOSCIENTOS", "TRESCIENTOS", "CUATROCIENTOS", "QUINIENTOS", "SEISCIENTOS", "SETECIENTOS", "OCHOCIENTOS", "NOVECIENTOS"); + $decenas = array("", "", "TREINTA ", "CUARENTA ", "CINCUENTA ", "SESENTA ", "SETENTA ", "OCHENTA ", "NOVENTA "); + $veintis = array("VEINTE", "VEINTIUN", "VEINTIDÓS", "VEINTITRÉS", "VEINTICUATRO", "VEINTICINCO", "VEINTISÉIS", "VEINTISIETE", "VEINTIOCHO", "VEINTINUEVE"); + $diecis = array("DIEZ", "ONCE", "DOCE", "TRECE", "CATORCE", "QUINCE", "DIECISÉIS", "DIECISIETE", "DIECIOCHO", "DIECINUEVE"); + $unidades = array("UN", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE", "OCHO", "NUEVE"); $entexto = ""; - if ($hundreds!=0){ - $entexto .= $centenas[$hundreds-1]; + if ($hundreds != 0) { + $entexto .= $centenas[$hundreds - 1]; } - if ($tens>2){ - if ($hundreds!=0) $entexto .= " "; - $entexto .= $decenas[$tens-1]; - if ($units!=0){ + if ($tens > 2) { + if ($hundreds != 0) $entexto .= " "; + $entexto .= $decenas[$tens - 1]; + if ($units != 0) { $entexto .= " Y "; - $entexto .= $unidades[$units-1]; + $entexto .= $unidades[$units - 1]; } return $entexto; } - elseif ($tens==2){ - if ($hundreds!=0) $entexto .= " "; + elseif ($tens == 2) { + if ($hundreds != 0) $entexto .= " "; $entexto .= " ".$veintis[$units]; return $entexto; } - elseif ($tens==1){ - if ($hundreds!=0) $entexto .= " "; + elseif ($tens == 1) { + if ($hundreds != 0) $entexto .= " "; $entexto .= $diecis[$units]; return $entexto; } - if ($units!=0) { - if ($hundreds!=0 || $tens!=0) $entexto .= " "; - $entexto .= $unidades[$units-1]; + if ($units != 0) { + if ($hundreds != 0 || $tens != 0) $entexto .= " "; + $entexto .= $unidades[$units - 1]; } return $entexto; } diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index e7538725bc2..b75cb1e4bd6 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1401,7 +1401,7 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, foreach ($tblcateg as $cate) { // Adding the descriptions if they are filled - $desccateg = $cate->add_description; + $desccateg = $cate->description; if ($desccateg) $libelleproduitservice .= '__N__'.$desccateg; } diff --git a/htdocs/core/lib/product.lib.php b/htdocs/core/lib/product.lib.php index 9cf28ff20ee..79d77e0268f 100644 --- a/htdocs/core/lib/product.lib.php +++ b/htdocs/core/lib/product.lib.php @@ -76,13 +76,13 @@ function product_prepare_head($object) } // Sub products - if (! empty($conf->global->PRODUIT_SOUSPRODUITS)) + if (!empty($conf->global->PRODUIT_SOUSPRODUITS)) { $head[$h][0] = DOL_URL_ROOT."/product/composition/card.php?id=".$object->id; $head[$h][1] = $langs->trans('AssociatedProducts'); $nbFatherAndChild = $object->hasFatherOrChild(); - if ($nbFatherAndChild > 0) $head[$h][1].= ''.$nbFatherAndChild.''; + if ($nbFatherAndChild > 0) $head[$h][1] .= ''.$nbFatherAndChild.''; $head[$h][2] = 'subproduct'; $h++; } @@ -110,15 +110,15 @@ function product_prepare_head($object) $head[$h][1] = $langs->trans('ProductCombinations'); $head[$h][2] = 'combinations'; $nbVariant = $prodcomb->countNbOfCombinationForFkProductParent($object->id); - if ($nbVariant > 0) $head[$h][1].= ''.$nbVariant.''; + if ($nbVariant > 0) $head[$h][1] .= ''.$nbVariant.''; } $h++; } - if ($object->isProduct() || ($object->isService() && ! empty($conf->global->STOCK_SUPPORTS_SERVICES))) // If physical product we can stock (or service with option) + if ($object->isProduct() || ($object->isService() && !empty($conf->global->STOCK_SUPPORTS_SERVICES))) // If physical product we can stock (or service with option) { - if (! empty($conf->stock->enabled) && $user->rights->stock->lire) + if (!empty($conf->stock->enabled) && $user->rights->stock->lire) { $head[$h][0] = DOL_URL_ROOT."/product/stock/product.php?id=".$object->id; $head[$h][1] = $langs->trans("Stock"); @@ -156,11 +156,11 @@ function product_prepare_head($object) if (empty($conf->global->MAIN_DISABLE_NOTES_TAB)) { $nbNote = 0; - if(!empty($object->note_private)) $nbNote++; - if(!empty($object->note_public)) $nbNote++; + if (!empty($object->note_private)) $nbNote++; + if (!empty($object->note_public)) $nbNote++; $head[$h][0] = DOL_URL_ROOT.'/product/note.php?id='.$object->id; $head[$h][1] = $langs->trans('Notes'); - if ($nbNote > 0) $head[$h][1].= ''.$nbNote.''; + if ($nbNote > 0) $head[$h][1] .= ''.$nbNote.''; $head[$h][2] = 'note'; $h++; } @@ -168,18 +168,18 @@ function product_prepare_head($object) // Attachments require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; - if (! empty($conf->product->enabled) && ($object->type==Product::TYPE_PRODUCT)) $upload_dir = $conf->product->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref); - if (! empty($conf->service->enabled) && ($object->type==Product::TYPE_SERVICE)) $upload_dir = $conf->service->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref); + if (!empty($conf->product->enabled) && ($object->type == Product::TYPE_PRODUCT)) $upload_dir = $conf->product->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref); + if (!empty($conf->service->enabled) && ($object->type == Product::TYPE_SERVICE)) $upload_dir = $conf->service->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref); $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); - if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) { - if (! empty($conf->product->enabled) && ($object->type==Product::TYPE_PRODUCT)) $upload_dir = $conf->product->multidir_output[$object->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'product').$object->id.'/photos'; - if (! empty($conf->service->enabled) && ($object->type==Product::TYPE_SERVICE)) $upload_dir = $conf->service->multidir_output[$object->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'product').$object->id.'/photos'; + if (!empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) { + if (!empty($conf->product->enabled) && ($object->type == Product::TYPE_PRODUCT)) $upload_dir = $conf->product->multidir_output[$object->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'product').$object->id.'/photos'; + if (!empty($conf->service->enabled) && ($object->type == Product::TYPE_SERVICE)) $upload_dir = $conf->service->multidir_output[$object->entity].'/'.get_exdir($object->id, 2, 0, 0, $object, 'product').$object->id.'/photos'; $nbFiles += count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); } - $nbLinks=Link::count($db, $object->element, $object->id); + $nbLinks = Link::count($db, $object->element, $object->id); $head[$h][0] = DOL_URL_ROOT.'/product/document.php?id='.$object->id; $head[$h][1] = $langs->trans('Documents'); - if (($nbFiles+$nbLinks) > 0) $head[$h][1].= ''.($nbFiles+$nbLinks).''; + if (($nbFiles + $nbLinks) > 0) $head[$h][1] .= ''.($nbFiles + $nbLinks).''; $head[$h][2] = 'documents'; $h++; @@ -225,10 +225,10 @@ function productlot_prepare_head($object) require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; $upload_dir = $conf->productbatch->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref); $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); - $nbLinks=Link::count($db, $object->element, $object->id); + $nbLinks = Link::count($db, $object->element, $object->id); $head[$h][0] = DOL_URL_ROOT."/product/stock/productlot_document.php?id=".$object->id; $head[$h][1] = $langs->trans("Documents"); - if (($nbFiles+$nbLinks) > 0) $head[$h][1].= ''.($nbFiles+$nbLinks).''; + if (($nbFiles + $nbLinks) > 0) $head[$h][1] .= ''.($nbFiles + $nbLinks).''; $head[$h][2] = 'documents'; $h++; @@ -425,6 +425,24 @@ function show_stats_for_company($product, $socid) print ''; print '
'; } + // MO + if (!empty($conf->mrp->enabled) && $user->rights->mrp->read) + { + $nblines++; + //$ret = $product->load_stats_mo($socid); + if ($ret < 0) dol_print_error($db); + $langs->load("orders"); + print ''; + print ''; + } // Customer invoices if (!empty($conf->facture->enabled) && $user->rights->facture->lire) { @@ -504,7 +522,7 @@ function measuring_units_string($scale = '', $measuring_style = '', $unit = 0, $ * Return translation label of a unit key * * @param int $unit ID of unit (rowid in llx_c_units table) - * @param string $measuring_style Style of unit: weight, volume,... + * @param string $measuring_style Style of unit: 'weight', 'volume', ..., '' = 'net_measure' for option PRODUCT_ADD_NET_MEASURE * @param string $scale Scale of unit: '0', '-3', '6', ... * @param int $use_short_label 1=Use short label ('g' instead of 'gram'). Short labels are not translated. * @return string Unit string @@ -518,9 +536,16 @@ function measuringUnitString($unit, $measuring_style = '', $scale = '', $use_sho if (empty($measuring_unit_cache[$unit.'_'.$measuring_style.'_'.$scale.'_'.$use_short_label])) { require_once DOL_DOCUMENT_ROOT.'/core/class/cunits.class.php'; - $measuringUnits= new CUnits($db); + $measuringUnits = new CUnits($db); - if ($scale !== '') + if ($measuring_style == '' && $scale == '') + { + $arrayforfilter = array( + 't.rowid' => $unit, + 't.active' => 1 + ); + } + elseif ($scale !== '') { $arrayforfilter = array( 't.scale' => $scale, diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 16e78d24414..dbfeef03259 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -265,7 +265,7 @@ function project_timesheet_prepare_head($mode, $fuser = null) if (empty($conf->global->PROJECT_DISABLE_TIMESHEET_PERMONTH)) { - $head[$h][0] = DOL_URL_ROOT."/projet/activity/permonth.php".($param?'?'.$param:''); + $head[$h][0] = DOL_URL_ROOT."/projet/activity/permonth.php".($param ? '?'.$param : ''); $head[$h][1] = $langs->trans("InputPerMonth"); $head[$h][2] = 'inputpermonth'; $h++; @@ -1735,19 +1735,19 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, & global $conf, $db, $user, $bc, $langs; global $form, $formother, $projectstatic, $taskstatic, $thirdpartystatic; - $numlines=count($lines); + $numlines = count($lines); - $lastprojectid=0; - $workloadforid=array(); - $totalforeachweek=array(); - $lineswithoutlevel0=array(); + $lastprojectid = 0; + $workloadforid = array(); + $totalforeachweek = array(); + $lineswithoutlevel0 = array(); // Create a smaller array with sublevels only to be used later. This increase dramatically performances. if ($parent == 0) // Always and only if at first level { - for ($i = 0 ; $i < $numlines ; $i++) + for ($i = 0; $i < $numlines; $i++) { - if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[]=$lines[$i]; + if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[] = $lines[$i]; } } @@ -1755,24 +1755,24 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, & if (empty($oldprojectforbreak)) { - $oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)?0:-1); // 0 = start break, -1 = never break + $oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT) ? 0 : -1); // 0 = start break, -1 = never break } - for ($i = 0 ; $i < $numlines ; $i++) + for ($i = 0; $i < $numlines; $i++) { if ($parent == 0) $level = 0; if ($lines[$i]->fk_task_parent == $parent) { // If we want all or we have a role on task, we show it - if (empty($mine) || ! empty($tasksrole[$lines[$i]->id])) + if (empty($mine) || !empty($tasksrole[$lines[$i]->id])) { //dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project); // Break on a new project if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid) { - $lastprojectid=$lines[$i]->fk_project; + $lastprojectid = $lines[$i]->fk_project; $projectstatic->id = $lines[$i]->fk_project; } @@ -1780,32 +1780,32 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, & //var_dump($projectstatic->weekWorkLoadPerTask); if (empty($workloadforid[$projectstatic->id])) { - $projectstatic->loadTimeSpentMonth($firstdaytoshow, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week - $workloadforid[$projectstatic->id]=1; + $projectstatic->loadTimeSpentMonth($firstdaytoshow, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week + $workloadforid[$projectstatic->id] = 1; } //var_dump($projectstatic->weekWorkLoadPerTask); //var_dump('--- '.$projectstatic->id.' '.$workloadforid[$projectstatic->id]); - $projectstatic->id=$lines[$i]->fk_project; - $projectstatic->ref=$lines[$i]->projectref; - $projectstatic->title=$lines[$i]->projectlabel; - $projectstatic->public=$lines[$i]->public; - $projectstatic->thirdparty_name=$lines[$i]->thirdparty_name; + $projectstatic->id = $lines[$i]->fk_project; + $projectstatic->ref = $lines[$i]->projectref; + $projectstatic->title = $lines[$i]->projectlabel; + $projectstatic->public = $lines[$i]->public; + $projectstatic->thirdparty_name = $lines[$i]->thirdparty_name; - $taskstatic->id=$lines[$i]->id; - $taskstatic->ref=($lines[$i]->ref?$lines[$i]->ref:$lines[$i]->id); - $taskstatic->label=$lines[$i]->label; - $taskstatic->date_start=$lines[$i]->date_start; - $taskstatic->date_end=$lines[$i]->date_end; + $taskstatic->id = $lines[$i]->id; + $taskstatic->ref = ($lines[$i]->ref ? $lines[$i]->ref : $lines[$i]->id); + $taskstatic->label = $lines[$i]->label; + $taskstatic->date_start = $lines[$i]->date_start; + $taskstatic->date_end = $lines[$i]->date_end; - $thirdpartystatic->id=$lines[$i]->thirdparty_id; - $thirdpartystatic->name=$lines[$i]->thirdparty_name; - $thirdpartystatic->email=$lines[$i]->thirdparty_email; + $thirdpartystatic->id = $lines[$i]->thirdparty_id; + $thirdpartystatic->name = $lines[$i]->thirdparty_name; + $thirdpartystatic->email = $lines[$i]->thirdparty_email; if (empty($oldprojectforbreak) || ($oldprojectforbreak != -1 && $oldprojectforbreak != $projectstatic->id)) { print ''."\n"; - print ''; // Time spent by everybody @@ -1877,66 +1877,66 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, & // Time spent by user print '\n"; - $disabledproject=1;$disabledtask=1; + $disabledproject = 1; $disabledtask = 1; //print "x".$lines[$i]->fk_project; //var_dump($lines[$i]); //var_dump($projectsrole[$lines[$i]->fk_project]); // If at least one role for project - if ($lines[$i]->public || ! empty($projectsrole[$lines[$i]->fk_project]) || $user->rights->projet->all->creer) + if ($lines[$i]->public || !empty($projectsrole[$lines[$i]->fk_project]) || $user->rights->projet->all->creer) { - $disabledproject=0; - $disabledtask=0; + $disabledproject = 0; + $disabledtask = 0; } // If $restricteditformytask is on and I have no role on task, i disable edit if ($restricteditformytask && empty($tasksrole[$lines[$i]->id])) { - $disabledtask=1; + $disabledtask = 1; } //var_dump($projectstatic->weekWorkLoadPerTask); //TODO // Fields to show current time - $tableCell=''; $modeinput='hours'; + $tableCell = ''; $modeinput = 'hours'; $TFirstDay = getFirstDayOfEachWeek($TWeek, date('Y', $firstdaytoshow)); $TFirstDay[reset($TWeek)] = 1; - foreach($TFirstDay as &$fday) { + foreach ($TFirstDay as &$fday) { $fday--; } foreach ($TWeek as $weekNb) { $weekWorkLoad = $projectstatic->monthWorkLoadPerTask[$weekNb][$lines[$i]->id]; - $totalforeachweek[$weekNb]+=$weekWorkLoad; + $totalforeachweek[$weekNb] += $weekWorkLoad; - $alreadyspent=''; - if ($weekWorkLoad > 0) $alreadyspent=convertSecondToTime($weekWorkLoad, 'allhourmin'); - $alttitle=$langs->trans("AddHereTimeSpentForWeek", $weekNb); + $alreadyspent = ''; + if ($weekWorkLoad > 0) $alreadyspent = convertSecondToTime($weekWorkLoad, 'allhourmin'); + $alttitle = $langs->trans("AddHereTimeSpentForWeek", $weekNb); - $tableCell =''; + $tableCell .= ''; + $tableCell .= ''; print $tableCell; } // Warning print '\n"; $total_plannedworkload = 0; @@ -2161,13 +2179,14 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks if ($userAccess >= 0) { $projectstatic->ref = $objp->ref; - $projectstatic->statut = $objp->status; + $projectstatic->statut = $objp->status; // deprecated + $projectstatic->status = $objp->status; $projectstatic->title = $objp->title; $projectstatic->datee = $db->jdate($objp->datee); $projectstatic->dateo = $db->jdate($objp->dateo); - print ''; + print ''; + if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { + if (!in_array('prospectionstatus', $hiddenfields)) { + print ''; + } + print ''; print ''; } + if (empty($conf->global->PROJECT_HIDE_TASKS)) { print ''; @@ -2212,12 +2263,16 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks } } - print ''; + if (!in_array('projectstatus', $hiddenfields)) { + print ''; + } + print "\n"; $total_task = $total_task + $objp->nb; $total_opp_amount = $total_opp_amount + $objp->opp_amount; - $ponderated_opp_amount = $ponderated_opp_amount + price2num($listofoppstatus[$objp->opp_status] * $objp->opp_amount / 100); } $i++; @@ -2227,6 +2282,9 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks print '"; if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { + if (!in_array('prospectionstatus', $hiddenfields)) { + print ''; + } print ''; print ''; } @@ -2236,7 +2294,9 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks if (!in_array('plannedworkload', $hiddenfields)) print ''; if (!in_array('declaredprogress', $hiddenfields)) print ''; } - print ''; + if (!in_array('projectstatus', $hiddenfields)) { + print ''; + } print ''; $db->free($resql); @@ -2400,7 +2460,7 @@ function getTaskProgressView($task, $label = true, $progressNumber = true, $hide */ function getTaskProgressBadge($task, $label = '', $tooltip = '') { - global $conf; + global $conf, $langs; $out = ''; $badgeClass = ''; @@ -2418,12 +2478,15 @@ function getTaskProgressBadge($task, $label = '', $tooltip = '') if (doubleval($progressCalculated) > doubleval($task->progress * $warningRatio)) { $badgeClass .= 'badge-danger'; + if (empty($tooltip)) $tooltip = $task->progress.'% < '.$langs->trans("Expected").' '.$progressCalculated.'%'; } elseif (doubleval($progressCalculated) > doubleval($task->progress)) { // warning if close at 10% $badgeClass .= 'badge-warning'; + if (empty($tooltip)) $tooltip = $task->progress.'% < '.$langs->trans("Expected").' '.$progressCalculated.'%'; } else { $badgeClass .= 'badge-success'; + if (empty($tooltip)) $tooltip = $task->progress.'% >= '.$langs->trans("Expected").' '.$progressCalculated.'%'; } } } diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 93f17422c47..83cf576f0bb 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -107,7 +107,7 @@ function dol_decode($chain, $key = '1') * If constant MAIN_SECURITY_SALT is defined, we use it as a salt (used only if hashing algorightm is something else than 'password_hash'). * * @param string $chain String to hash - * @param string $type Type of hash ('0':auto will use MAIN_SECURITY_HASH_ALGO else md5, '1':sha1, '2':sha1+md5, '3':md5, '4':md5 for OpenLdap, '5':sha256). Use '3' here, if hash is not needed for security purpose, for security need, prefer '0'. + * @param string $type Type of hash ('0':auto will use MAIN_SECURITY_HASH_ALGO else md5, '1':sha1, '2':sha1+md5, '3':md5, '4':md5 for OpenLdap with no salt, '5':sha256). Use '3' here, if hash is not needed for security purpose, for security need, prefer '0'. * @return string Hash of string * @see getRandomPassword() */ @@ -122,7 +122,7 @@ function dol_hash($chain, $type = '0') } // Salt value - if (!empty($conf->global->MAIN_SECURITY_SALT)) $chain = $conf->global->MAIN_SECURITY_SALT.$chain; + if (! empty($conf->global->MAIN_SECURITY_SALT) && $type != '4' && $type !== 'md5openldap') $chain = $conf->global->MAIN_SECURITY_SALT.$chain; if ($type == '1' || $type == 'sha1') return sha1($chain); elseif ($type == '2' || $type == 'sha1md5') return sha1(md5($chain)); @@ -168,7 +168,7 @@ function dol_verifyHash($chain, $hash, $type = '0') * If GETPOST('action','aZ09') defined, we also check write and delete permission. * * @param User $user User to check - * @param string $features Features to check (it must be module name. Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...) + * @param string $features Features to check (it must be module $object->element. Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...) * @param int $objectid Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional). * @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany modume. Param not used if objectid is null (optional). * @param string $feature2 Feature to check, second level of permission (optional). Can be a 'or' check with 'sublevela|sublevelb'. @@ -188,11 +188,21 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f //print ", dbtablename=".$dbtablename.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select; //print ", perm: ".$features."->".$feature2."=".($user->rights->$features->$feature2->lire)."
"; + if ($features == 'facturerec') $features = 'facture'; + if ($features == 'mo') $features = 'mrp'; + if ($features == 'member') $features = 'adherent'; + if ($features == 'subscription') { $features = 'adherent'; $feature2 = 'cotisation'; }; + // Get more permissions checks from hooks $parameters = array('features'=>$features, 'objectid'=>$objectid, 'idtype'=>$dbt_select); $reshook = $hookmanager->executeHooks('restrictedArea', $parameters); - if (!empty($hookmanager->resArray['result'])) return true; - if ($reshook > 0) return false; + + if (isset($hookmanager->resArray['result'])) { + if ($hookmanager->resArray['result'] == 0) accessforbidden(); // Module returns 0, so access forbidden + } + if ($reshook > 0) { // No other test done. + return 1; + } if ($dbt_select != 'rowid' && $dbt_select != 'id') $objectid = "'".$objectid."'"; @@ -311,6 +321,9 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f { foreach ($feature2 as $subfeature) { + if ($subfeature == 'user' && $user->id == $objectid && $user->rights->user->self->creer) continue; // User can edit its own card + if ($subfeature == 'user' && $user->id == $objectid && $user->rights->user->self->password) continue; // User can edit its own password + if (empty($user->rights->$feature->$subfeature->creer) && empty($user->rights->$feature->$subfeature->write) && empty($user->rights->$feature->$subfeature->create)) { diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index 10da4f60fc1..b9a606b98b4 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -221,7 +221,7 @@ if (!function_exists('dol_loginfunction')) // Show logo (search in order: small company logo, large company logo, theme logo, common logo) $width = 0; - $urllogo = DOL_URL_ROOT.'/theme/login_logo.png'; + $urllogo=DOL_URL_ROOT.'/theme/common/login_logo.png'; if (!empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small)) { @@ -232,13 +232,9 @@ if (!function_exists('dol_loginfunction')) $urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('logos/'.$mysoc->logo); $width = 128; } - elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png')) + elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.svg')) { - $urllogo = DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/dolibarr_logo.png'; - } - elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.png')) - { - $urllogo = DOL_URL_ROOT.'/theme/dolibarr_logo.png'; + $urllogo = DOL_URL_ROOT.'/theme/dolibarr_logo.svg'; } // Security graphical code diff --git a/htdocs/core/lib/takepos.lib.php b/htdocs/core/lib/takepos.lib.php index dc86853859e..6cf8189f3c8 100644 --- a/htdocs/core/lib/takepos.lib.php +++ b/htdocs/core/lib/takepos.lib.php @@ -38,13 +38,10 @@ function takepos_prepare_head() $head[$h][2] = 'setup'; $h++; - if ($conf->global->TAKEPOS_CUSTOM_RECEIPT) - { - $head[$h][0] = DOL_URL_ROOT.'/takepos/admin/receipt.php'; - $head[$h][1] = $langs->trans("Receipt"); - $head[$h][2] = 'receipt'; - $h++; - } + $head[$h][0] = DOL_URL_ROOT.'/takepos/admin/receipt.php'; + $head[$h][1] = $langs->trans("Receipt"); + $head[$h][2] = 'receipt'; + $h++; $numterminals = max(1, $conf->global->TAKEPOS_NUM_TERMINALS); for ($i = 1; $i <= $numterminals; $i++) @@ -55,7 +52,12 @@ function takepos_prepare_head() $h++; } - complete_head_from_modules($conf, $langs, null, $head, $h, 'takepos'); + $head[$h][0] = DOL_URL_ROOT.'/takepos/admin/other.php'; + $head[$h][1] = $langs->trans("Other"); + $head[$h][2] = 'other'; + $h++; + + complete_head_from_modules($conf, $langs, null, $head, $h, 'takepos'); return $head; } diff --git a/htdocs/core/lib/ticket.lib.php b/htdocs/core/lib/ticket.lib.php index b7c741bd839..fe7fb4ba5a7 100644 --- a/htdocs/core/lib/ticket.lib.php +++ b/htdocs/core/lib/ticket.lib.php @@ -222,7 +222,7 @@ function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $ // Print logo if (! empty($conf->global->TICKET_SHOW_COMPANY_LOGO)) { - $urllogo = DOL_URL_ROOT . '/theme/login_logo.png'; + $urllogo = DOL_URL_ROOT . '/theme/common/login_logo.png'; if (!empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output . '/logos/thumbs/' . $mysoc->logo_small)) { $urllogo = DOL_URL_ROOT . '/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file=' . urlencode('logos/thumbs/'.$mysoc->logo_small); diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index 709832118c2..a234f4ed5e0 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -448,7 +448,8 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false) print '
- @@ -217,7 +231,7 @@ - +
'.img_picto('', $picto, 'class="valignmiddle widthpictotitle pictotitle"', $pictoisfullpath).''; $return .= '
'.$titre.'
'; @@ -4267,10 +4306,10 @@ function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '', // Left - if ($picto && $titre) print '
'.img_picto('', $picto, 'class="hideonsmartphone valignmiddle pictotitle widthpictotitle"', $pictoisfullpath).''.img_picto('', $picto, 'class="valignmiddle pictotitle widthpictotitle"', $pictoisfullpath).''; print '
'.$titre; - if (!empty($titre) && $savtotalnboflines >= 0 && (string) $savtotalnboflines != '') print ' ('.$totalnboflines.')'; + if (!empty($titre) && $savtotalnboflines >= 0 && (string) $savtotalnboflines != '') print '('.$totalnboflines.')'; print '
'; + print ''.img_object('', 'mrp').' '.$langs->trans("MO").''; + print ''; + print $product->stats_mo['suppliers']; + print ''; + print $product->stats_mo['nb']; + print ''; + print $product->stats_mo['qty']; + print '
'; + print ''; print $projectstatic->getNomUrl(1, '', 0, ''.$langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]); if ($thirdpartystatic->id > 0) print ' - '.$thirdpartystatic->getNomUrl(1); if ($projectstatic->title) @@ -1840,11 +1840,11 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, & // Ref print ''; print ''; - for ($k = 0 ; $k < $level ; $k++) print "   "; + for ($k = 0; $k < $level; $k++) print "   "; print $taskstatic->getNomUrl(1, 'withproject', 'time'); // Label task print '
'; - for ($k = 0 ; $k < $level ; $k++) print "   "; + for ($k = 0; $k < $level; $k++) print "   "; //print $taskstatic->getNomUrl(0, 'withproject', 'time'); print $taskstatic->label; //print "
"; @@ -1860,7 +1860,7 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, & // Progress declared % print '
'; - print $formother->select_percent($lines[$i]->progress, $lines[$i]->id . 'progress'); + print $formother->select_percent($lines[$i]->progress, $lines[$i]->id.'progress'); print ''; - $tmptimespent=$taskstatic->getSummaryOfTimeSpent($fuser->id); + $tmptimespent = $taskstatic->getSummaryOfTimeSpent($fuser->id); if ($tmptimespent['total_duration']) print convertSecondToTime($tmptimespent['total_duration'], 'allhourmin'); else print '--:--'; print "'; - $placeholder=''; + $tableCell = ''; + $placeholder = ''; if ($alreadyspent) { - $tableCell.=''; + $tableCell .= ''; //$placeholder=' placeholder="00:00"'; //$tableCell.='+'; } - $tableCell.=''; - $tableCell.=''; - if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('', $langs->trans("UserIsNotContactOfProject")); + if ((!$lines[$i]->public) && $disabledproject) print $form->textwithpicto('', $langs->trans("UserIsNotContactOfProject")); elseif ($disabledtask) { $titleassigntask = $langs->trans("AssignTaskToMe"); @@ -1959,9 +1959,9 @@ function projectLinesPerMonth(&$inc, $firstdaytoshow, $fuser, $parent, $lines, & $ret = projectLinesPerMonth($inc, $firstdaytoshow, $fuser, $lines[$i]->id, ($parent == 0 ? $lineswithoutlevel0 : $lines), $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable, $oldprojectforbreak, $TWeek); //var_dump('ret with parent='.$lines[$i]->id.' level='.$level); //var_dump($ret); - foreach($ret as $key => $val) + foreach ($ret as $key => $val) { - $totalforeachweek[$key]+=$val; + $totalforeachweek[$key] += $val; } //var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level.' + subtasks'); //var_dump($totalforeachday); @@ -2030,9 +2030,26 @@ function searchTaskInChild(&$inc, $parent, &$lines, &$taskrole) function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks = 0, $status = -1, $listofoppstatus = array(), $hiddenfields = array()) { global $langs, $conf, $user, $bc; + global $theme_datacolor; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + $listofstatus = array_keys($listofoppstatus); + + if (is_array($listofstatus) && ! empty($conf->global->USE_COLOR_FOR_PROSPECTION_STATUS)) { + // Define $themeColorId and array $statusOppList for each $listofstatus + $themeColorId = 0; + $statusOppList = array(); + foreach ($listofstatus as $oppStatus) { + $oppStatusCode = dol_getIdFromCode($db, $oppStatus, 'c_lead_status', 'rowid', 'code'); + if ($oppStatusCode) { + $statusOppList[$oppStatus]['code'] = $oppStatusCode; + $statusOppList[$oppStatus]['color'] = isset($theme_datacolor[$themeColorId]) ? implode(', ', $theme_datacolor[$themeColorId]) : ''; + } + $themeColorId++; + } + } + $projectstatic = new Project($db); $thirdpartystatic = new Societe($db); @@ -2109,14 +2126,14 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks if (empty($arrayidofprojects)) $arrayidofprojects[0] = -1; // Get list of project with calculation on tasks - $sql2 = "SELECT p.rowid as projectid, p.ref, p.title, p.fk_soc, s.nom as socname, p.fk_user_creat, p.public, p.fk_statut as status, p.fk_opp_status as opp_status, p.opp_amount,"; + $sql2 = "SELECT p.rowid as projectid, p.ref, p.title, p.fk_soc, s.nom as socname, p.fk_user_creat, p.public, p.fk_statut as status, p.fk_opp_status as opp_status, p.opp_percent, p.opp_amount,"; $sql2 .= " p.dateo, p.datee,"; $sql2 .= " COUNT(t.rowid) as nb, SUM(t.planned_workload) as planned_workload, SUM(t.planned_workload * t.progress / 100) as declared_progess_workload"; $sql2 .= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql2 .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = p.fk_soc"; $sql2 .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t ON p.rowid = t.fk_projet"; $sql2 .= " WHERE p.rowid IN (".join(',', $arrayidofprojects).")"; - $sql2 .= " GROUP BY p.rowid, p.ref, p.title, p.fk_soc, s.nom, p.fk_user_creat, p.public, p.fk_statut, p.fk_opp_status, p.opp_amount, p.dateo, p.datee"; + $sql2 .= " GROUP BY p.rowid, p.ref, p.title, p.fk_soc, s.nom, p.fk_user_creat, p.public, p.fk_statut, p.fk_opp_status, p.opp_percent, p.opp_amount, p.dateo, p.datee"; $sql2 .= " ORDER BY p.title, p.ref"; $resql = $db->query($sql2); @@ -2134,16 +2151,17 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks print_liste_field_titre("ThirdParty", $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder); if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { + if (!in_array('prospectionstatus', $hiddenfields)) print_liste_field_titre("OpportunityStatus", "", "", "", "", '', $sortfield, $sortorder, 'right '); print_liste_field_titre("OpportunityAmount", "", "", "", "", 'align="right"', $sortfield, $sortorder); - print_liste_field_titre("OpportunityStatus", "", "", "", "", 'align="right"', $sortfield, $sortorder); + print_liste_field_titre('OpportunityWeightedAmount', '', '', '', '', 'align="right"', $sortfield, $sortorder); } if (empty($conf->global->PROJECT_HIDE_TASKS)) { print_liste_field_titre("Tasks", "", "", "", "", 'align="right"', $sortfield, $sortorder); - if (!in_array('plannedworkload', $hiddenfields)) print_liste_field_titre("PlannedWorkload", "", "", "", "", 'align="right"', $sortfield, $sortorder); - if (!in_array('declaredprogress', $hiddenfields)) print_liste_field_titre("ProgressDeclared", "", "", "", "", 'align="right"', $sortfield, $sortorder); + if (!in_array('plannedworkload', $hiddenfields)) print_liste_field_titre("PlannedWorkload", "", "", "", "", '', $sortfield, $sortorder, 'right '); + if (!in_array('declaredprogress', $hiddenfields)) print_liste_field_titre("ProgressDeclared", "", "", "", "", '', $sortfield, $sortorder, 'right '); } - print_liste_field_titre("Status", "", "", "", "", 'align="right"', $sortfield, $sortorder); + if (!in_array('projectstatus', $hiddenfields)) print_liste_field_titre("Status", "", "", "", "", '', $sortfield, $sortorder, 'right '); print "
'; print $projectstatic->getNomUrl(1); if (!in_array('projectlabel', $hiddenfields)) print '
'.dol_trunc($objp->title, 24); @@ -2181,16 +2200,48 @@ function print_projecttasks_array($db, $form, $socid, $projectsListId, $mytasks print $thirdpartystatic->getNomUrl(1); } print '
'; + // Because color of prospection status has no meaning yet, it is used if hidden constant is set + if (empty($conf->global->USE_COLOR_FOR_PROSPECTION_STATUS)) { + $oppStatusCode = dol_getIdFromCode($db, $objp->opp_status, 'c_lead_status', 'rowid', 'code'); + if ($langs->trans("OppStatus".$oppStatusCode) != "OppStatus".$oppStatusCode) { + print $langs->trans("OppStatus".$oppStatusCode); + } + } else { + if (isset($statusOppList[$objp->opp_status])) { + $oppStatusCode = $statusOppList[$objp->opp_status]['code']; + $oppStatusColor = $statusOppList[$objp->opp_status]['color']; + } else { + $oppStatusCode = dol_getIdFromCode($db, $objp->opp_status, 'c_lead_status', 'rowid', 'code'); + $oppStatusColor = ''; + } + if ($oppStatusCode) { + if (!empty($oppStatusColor)) { + print ''; + } else { + print ''.$oppStatusCode.''; + } + } + } + print ''; if ($objp->opp_amount) print price($objp->opp_amount, 0, '', 1, -1, -1, $conf->currency); print ''; - $code = dol_getIdFromCode($db, $objp->opp_status, 'c_lead_status', 'rowid', 'code'); - if ($code) print $langs->trans("OppStatus".$code); + if ($objp->opp_percent && $objp->opp_amount) { + $opp_weighted_amount = $objp->opp_percent * $objp->opp_amount / 100; + print price($opp_weighted_amount, 0, '', 1, -1, -1, $conf->currency); + $ponderated_opp_amount += price2num($opp_weighted_amount); + } print ''.$objp->nb.''.$projectstatic->getLibStatut(3).''; + print $projectstatic->getLibStatut(3); + print '
'.$langs->trans("Total")."'.price($total_opp_amount, 0, '', 1, -1, -1, $conf->currency).''.$form->textwithpicto(price($ponderated_opp_amount, 0, '', 1, -1, -1, $conf->currency), $langs->trans("OpportunityPonderatedAmountDesc"), 1).''.($total_plannedworkload ?convertSecondToTime($total_plannedworkload) : '').''.($total_plannedworkload ?round(100 * $total_declaredprogressworkload / $total_plannedworkload, 0).'%' : '').'
'.$langs->trans("EnableShowLogo").''; if ($edit) { - print $form->selectyesno('MAIN_SHOW_LOGO', $conf->global->MAIN_SHOW_LOGO, 1); + print ajax_constantonoff('MAIN_SHOW_LOGO', array(), null, 0, 0, 1); + //print $form->selectyesno('MAIN_SHOW_LOGO', $conf->global->MAIN_SHOW_LOGO, 1); } else { @@ -494,7 +495,8 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false) print ''; if ($edit) { - print $form->selectyesno('THEME_TOPMENU_DISABLE_IMAGE', $conf->global->THEME_TOPMENU_DISABLE_IMAGE, 1); + print ajax_constantonoff('THEME_TOPMENU_DISABLE_IMAGE', array(), null, 0, 0, 1); + //print $form->selectyesno('THEME_TOPMENU_DISABLE_IMAGE', $conf->global->THEME_TOPMENU_DISABLE_IMAGE, 1); } else { diff --git a/htdocs/core/lib/vat.lib.php b/htdocs/core/lib/vat.lib.php index f8c7b579c18..1649e686ec2 100644 --- a/htdocs/core/lib/vat.lib.php +++ b/htdocs/core/lib/vat.lib.php @@ -49,7 +49,7 @@ function vat_prepare_head($object) require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; - $upload_dir = $conf->tax->dir_output . "/" . dol_sanitizeFileName($object->ref); + $upload_dir = $conf->tax->dir_output . "/vat/" . dol_sanitizeFileName($object->ref); $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); $nbLinks=Link::count($db, $object->element, $object->id); $head[$tab][0] = DOL_URL_ROOT.'/compta/tva/document.php?id='.$object->id; diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index f97c6efed1c..2257203d25b 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -51,11 +51,14 @@ function dolStripPhpCode($str, $replacewith = '') $partlings = explode('?>', $part); if (!empty($partlings)) { - $phppart = $partlings[0]; + //$phppart = $partlings[0]; //remove content before closing tag if (count($partlings) > 1) $partlings[0] = ''; // Todo why a count > 1 and not >= 1 ? //append to out string - $newstr .= ''.$replacewith.''.implode('', $partlings); + //$newstr .= ''.$replacewith.''.implode('', $partlings); + //$newstr .= ''.$replacewith.''.implode('', $partlings); + $newstr .= ''.$replacewith.''.implode('', $partlings); + //$newstr .= $replacewith.implode('', $partlings); } } } @@ -163,15 +166,15 @@ function dolWebsiteReplacementOfLinks($website, $content, $removephppart = 0, $c $content = str_replace('href="'.DOL_URL_ROOT.'/document.php', 'href="!~!~!~'.DOL_URL_ROOT.'/document.php', $content); // Replace relative link '/' with dolibarr URL - $content = preg_replace('/(href=")\/\"/', '\1!~!~!~'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageid='.$website->fk_default_home.'"', $content, -1, $nbrep); + $content = preg_replace('/(href=")\/(#[^\"<>]*)?\"/', '\1!~!~!~'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageid='.$website->fk_default_home.'\2"', $content, -1, $nbrep); // Replace relative link /xxx.php#aaa or /xxx.php with dolibarr URL (we discard param ?...) $content = preg_replace('/(href=")\/?([^:\"\!]*)\.php(#[^\"<>]*)?\"/', '\1!~!~!~'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageref=\2\3"', $content, -1, $nbrep); // Replace relative link /xxx.php?a=b&c=d#aaa or /xxx.php?a=b&c=d with dolibarr URL $content = preg_replace('/(href=")\/?([^:\"\!]*)\.php\?([^#\"<>]*)(#[^\"<>]*)?\"/', '\1!~!~!~'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageref=\2&\3\4"', $content, -1, $nbrep); // Fix relative link into medias with correct URL after the DOL_URL_ROOT: ../url("medias/ - $content = preg_replace('/url\((["\']?)medias\//', 'url(\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep); - $content = preg_replace('/data-slide-bg=(["\']?)medias\//', 'data-slide-bg=\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep); + $content = preg_replace('/url\((["\']?)\/?medias\//', 'url(\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep); + $content = preg_replace('/data-slide-bg=(["\']?)\/?medias\//', 'data-slide-bg=\1!~!~!~'.DOL_URL_ROOT.'/viewimage.php?modulepart=medias&file=', $content, -1, $nbrep); // id.'.tpl.php\'; '; + $aliascontent .= 'else require $dolibarr_main_data_root.\'/website/\'.$website->ref.\'/page'.$objectpage->id.'.tpl.php\';'."\n"; + $aliascontent .= '?>'."\n"; + $result = file_put_contents($filealias, $aliascontent); + if (!empty($conf->global->MAIN_UMASK)) { + @chmod($filealias, octdec($conf->global->MAIN_UMASK)); + } + } + return ($result ?true:false); } @@ -85,6 +104,7 @@ function dolSavePageAlias($filealias, $object, $objectpage) * @param Website $object Object website * @param WebsitePage $objectpage Object websitepage * @return boolean True if OK + * @see dolSavePageAlias() */ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage) { @@ -96,12 +116,15 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage) dol_delete_file($filetpl); $shortlangcode = ''; - if ($objectpage->lang) $shortlangcode = preg_replace('/[_-].*$/', '', $objectpage->lang); // en_US or en-US -> en + if ($objectpage->lang) $shortlangcode = substr($objectpage->lang, 0, 2); // en_US or en-US -> en $tplcontent = ''; $tplcontent .= "isMultiLang()) { // Add myself - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; + // Add page "translation of" $translationof = $objectpage->fk_page; if ($translationof) { @@ -135,7 +159,7 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage) $tmpshortlangcode = ''; if ($tmppage->lang) $tmpshortlangcode = preg_replace('/[_-].*$/', '', $tmppage->lang); // en_US or en-US -> en if ($tmpshortlangcode != $shortlangcode) { - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; } } } @@ -152,7 +176,7 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage) $tmpshortlangcode = ''; if ($obj->lang) $tmpshortlangcode = preg_replace('/[_-].*$/', '', $obj->lang); // en_US or en-US -> en if ($tmpshortlangcode != $shortlangcode) { - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; } } } @@ -160,11 +184,11 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage) else dol_print_error($db); } // Add canonical reference - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; // Add manifest.json on homepage $tplcontent .= 'use_manifest) { print \'\'."\n"; } ?>'."\n"; $tplcontent .= ''."\n"; - $tplcontent .= ''."\n"; + $tplcontent .= ''."\n"; $tplcontent .= ''."\n"; $tplcontent .= '/ims\', \'\', file_get_contents(DOL_DATA_ROOT."/website/".$websitekey."/htmlheader.html")); ?>'."\n"; $tplcontent .= ''."\n"; diff --git a/htdocs/core/login/functions_googleoauth.php b/htdocs/core/login/functions_googleoauth.php index 2f1fbcf3667..e621f41e562 100644 --- a/htdocs/core/login/functions_googleoauth.php +++ b/htdocs/core/login/functions_googleoauth.php @@ -48,7 +48,7 @@ function check_user_password_googleoauth($usertotest, $passwordtotest, $entityto $login = ''; // Get identity from user and redirect browser to Google OAuth Server - if (isset($_POST['username'])) + if (GETPOSTISSET('username')) { /*$openid = new SimpleOpenID(); $openid->SetIdentity($_POST['username']); diff --git a/htdocs/core/login/functions_openid.php b/htdocs/core/login/functions_openid.php index c20b2a32f90..a401dfd7764 100644 --- a/htdocs/core/login/functions_openid.php +++ b/htdocs/core/login/functions_openid.php @@ -36,26 +36,26 @@ include_once DOL_DOCUMENT_ROOT.'/core/class/openid.class.php'; */ function check_user_password_openid($usertotest, $passwordtotest, $entitytotest) { - global $_POST,$db,$conf,$langs; + global $_POST, $db, $conf, $langs; dol_syslog("functions_openid::check_user_password_openid usertotest=".$usertotest); - $login=''; + $login = ''; // Get identity from user and redirect browser to OpenID Server - if (isset($_POST['username'])) + if (GETPOSISSET('username')) { $openid = new SimpleOpenID(); $openid->SetIdentity($_POST['username']); $protocol = ($conf->file->main_force_https ? 'https://' : 'http://'); - $openid->SetTrustRoot($protocol . $_SERVER["HTTP_HOST"]); - $openid->SetRequiredFields(array('email','fullname')); + $openid->SetTrustRoot($protocol.$_SERVER["HTTP_HOST"]); + $openid->SetRequiredFields(array('email', 'fullname')); $_SESSION['dol_entity'] = $_POST["entity"]; //$openid->SetOptionalFields(array('dob','gender','postcode','country','language','timezone')); if ($openid->sendDiscoveryRequestToGetXRDS()) { - $openid->SetApprovedURL($protocol . $_SERVER["HTTP_HOST"] . $_SERVER["SCRIPT_NAME"]); // Send Response from OpenID server to this script - $openid->Redirect(); // This will redirect user to OpenID Server + $openid->SetApprovedURL($protocol.$_SERVER["HTTP_HOST"].$_SERVER["SCRIPT_NAME"]); // Send Response from OpenID server to this script + $openid->Redirect(); // This will redirect user to OpenID Server } else { @@ -65,7 +65,7 @@ function check_user_password_openid($usertotest, $passwordtotest, $entitytotest) return false; } // Perform HTTP Request to OpenID server to validate key - elseif($_GET['openid_mode'] == 'id_res') + elseif ($_GET['openid_mode'] == 'id_res') { $openid = new SimpleOpenID(); $openid->SetIdentity($_GET['openid_identity']); @@ -74,23 +74,23 @@ function check_user_password_openid($usertotest, $passwordtotest, $entitytotest) { // OK HERE KEY IS VALID - $sql ="SELECT login"; - $sql.=" FROM ".MAIN_DB_PREFIX."user"; - $sql.=" WHERE openid = '".$db->escape($_GET['openid_identity'])."'"; - $sql.=" AND entity IN (0," . ($_SESSION["dol_entity"] ? $_SESSION["dol_entity"] : 1) . ")"; + $sql = "SELECT login"; + $sql .= " FROM ".MAIN_DB_PREFIX."user"; + $sql .= " WHERE openid = '".$db->escape($_GET['openid_identity'])."'"; + $sql .= " AND entity IN (0,".($_SESSION["dol_entity"] ? $_SESSION["dol_entity"] : 1).")"; dol_syslog("functions_openid::check_user_password_openid", LOG_DEBUG); - $resql=$db->query($sql); + $resql = $db->query($sql); if ($resql) { - $obj=$db->fetch_object($resql); + $obj = $db->fetch_object($resql); if ($obj) { - $login=$obj->login; + $login = $obj->login; } } } - elseif($openid->IsError() === true) + elseif ($openid->IsError() === true) { // ON THE WAY, WE GOT SOME ERROR $error = $openid->GetError(); diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index 8948c391899..66ed948585f 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -281,7 +281,7 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left -- Balance 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->accounting->enabled', __HANDLER__, 'left', 2435__+MAX_llx_menu__, 'accountancy', 'balance', 2400__+MAX_llx_menu__, '/accountancy/bookkeeping/balance.php?mainmenu=accountancy&leftmenu=accountancy_balance', 'AccountBalance', 1, 'accountancy', '$user->rights->accounting->mouvements->lire', '', 0, 16, __ENTITY__); -- Export accounting documents - 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->accounting->enabled', __HANDLER__, 'left', 2436__+MAX_llx_menu__, 'accountancy', 'accountancy_files', 2400__+MAX_llx_menu__, '/compta/compta-files.php?mainmenu=accountancy&leftmenu=accountancy_files', 'AccountantFiles', 1, 'accountancy', '$user->rights->accounting->mouvements->lire', '', 0, 17, __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->comptabilite->enabled || $conf->accounting->enabled', __HANDLER__, 'left', 2436__+MAX_llx_menu__, 'accountancy', 'accountancy_files', 2400__+MAX_llx_menu__, '/compta/accounting-files.php?mainmenu=accountancy&leftmenu=accountancy_files', 'AccountantFiles', 1, 'accountancy', '$user->rights->compta->resultat->lire || $user->rights->accounting->mouvements->lire', '', 0, 17, __ENTITY__); -- Reports 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->accounting->enabled', __HANDLER__, 'left', 2440__+MAX_llx_menu__, 'accountancy', 'accountancy_report', 2400__+MAX_llx_menu__, '/compta/resultat/index.php?mainmenu=accountancy&leftmenu=accountancy_report', 'Reportings', 1, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 17, __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->accounting->enabled && $leftmenu=="accountancy_report"', __HANDLER__, 'left', 2441__+MAX_llx_menu__, 'accountancy', 'accountancy_report', 2440__+MAX_llx_menu__, '/compta/resultat/index.php?mainmenu=accountancy&leftmenu=accountancy_report', 'MenuReportInOut', 2, 'main', '$user->rights->compta->resultat->lire || $user->rights->accounting->comptarapport->lire', '', 0, 18, __ENTITY__); diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php index e35f45576d1..390c50aa748 100644 --- a/htdocs/core/menus/standard/auguria.lib.php +++ b/htdocs/core/menus/standard/auguria.lib.php @@ -548,7 +548,7 @@ function print_left_auguria_menu($db, $menu_array_before, $menu_array_after, &$t if ($menu_array[$i]['enabled']) // Enabled so visible { print '

- N° 11580*03
+ N° 11580*04
DGFIP
Reçu au titre des dons
à certains organismes d’intérêt général

- Articles 200, 238 bis et 885-0 V bis A du code général des impôts (CGI) + Articles 200, 238 bis et 978 du code général des impôts (CGI)
Numéro d'ordre du reçu
@@ -46,13 +60,13 @@ __MAIN_INFO_SOCIETE_NOM__
Adresse :
__MAIN_INFO_SOCIETE_ADDRESS__
- Code postal __MAIN_INFO_SOCIETE_ZIP__ Commune __MAIN_INFO_SOCIETE_TOWN__
+ Code postal __MAIN_INFO_SOCIETE_ZIP__ Commune __MAIN_INFO_SOCIETE_TOWN__
Objet:
__MAIN_INFO_SOCIETE_OBJECT__
+
Cochez la case concernée (1) :
@@ -90,7 +104,7 @@ - + @@ -138,7 +152,7 @@ - +
Association cultuelle ou de bienfaisance et établissement public des cultes reconnus d'Alsace-MoselleAssociation cultuelle ou de bienfaisance et établissement public reconnus d'Alsace-Moselle
Autre organisme : ………………………………………………………………………………………………Autres organismes : ………………………………………………………………………………………………
__ARTICLE200__ __ARTICLE238____ARTICLE885____ARTICLE978__

@@ -251,7 +265,7 @@ - - @@ -274,10 +288,10 @@
(3) + L’organisme bénéficiaire peut cocher une ou plusieurs cases.
L’organisme bénéficiaire peut, en application de l’article L. 80 C du livre des procédures fiscales, demander à l’administration s’il relève de l’une des catégories d’organismes mentionnées aux articles 200 et 238 bis du code général des impôts.
@@ -262,7 +276,7 @@
(4) + Notamment : abandon de revenus ou de produits ; frais engagés par les bénévoles, dont ils renoncent expressément au remboursement
- + '; - print ''; + print ''; print ''; print ''; print ''; diff --git a/htdocs/don/list.php b/htdocs/don/list.php index 48b5f108b81..3cd49a20649 100644 --- a/htdocs/don/list.php +++ b/htdocs/don/list.php @@ -43,7 +43,7 @@ $pagenext = $page + 1; if (! $sortorder) $sortorder="DESC"; if (! $sortfield) $sortfield="d.datedon"; -$search_status=(GETPOST("search_status", 'intcomma') != '') ? GETPOST("search_status", 'intcomma') : "-1"; +$search_status=(GETPOST("search_status", 'intcomma') != '') ? GETPOST("search_status", 'intcomma') : "-4"; $search_all=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml')); $search_ref=GETPOST('search_ref', 'alpha'); $search_company=GETPOST('search_company', 'alpha'); @@ -60,6 +60,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_company = ""; $search_name = ""; $search_amount = ""; + $search_status = ''; } // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context @@ -91,7 +92,7 @@ $sql.= " d.amount, d.fk_statut as status,"; $sql.= " p.rowid as pid, p.ref, p.title, p.public"; $sql.= " FROM ".MAIN_DB_PREFIX."don as d LEFT JOIN ".MAIN_DB_PREFIX."projet AS p"; $sql.= " ON p.rowid = d.fk_projet WHERE d.entity IN (".getEntity('donation').")"; -if ($search_status != '' && $search_status != '-1') +if ($search_status != '' && $search_status != '-4') { $sql .= " AND d.fk_statut IN (".$db->escape($search_status).")"; } @@ -196,7 +197,15 @@ if ($resql) print ''; } print ''; - print ''; + print ''; print '"; print ''; print '\n"; print ''; print ''; print ''; print ''; // Number @@ -238,8 +238,8 @@ if ($action == 'create') print ''; print "\n"; - $total=0; - $totalrecu=0; + $total = 0; + $totalrecu = 0; while ($i < $num) { diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index e6968109bf7..57311c2e437 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -812,9 +812,9 @@ class EmailCollector extends CommonObject //var_dump($tmpproperty.' - '.$regexstring.' - '.$regexoptions.' - '.$sourcestring); if (preg_match('/'.$regexstring.'/'.$regexoptions, $sourcestring, $regforval)) { - //var_dump($regforval[1]);exit; + //var_dump($regforval[count($regforval)-1]);exit; // Overwrite param $tmpproperty - $object->$tmpproperty = isset($regforval[1]) ?trim($regforval[1]) : null; + $object->$tmpproperty = isset($regforval[count($regforval)-1]) ?trim($regforval[count($regforval)-1]) : null; } else { @@ -1236,13 +1236,14 @@ class EmailCollector extends CommonObject // References: <1542377954.SMTPs-dolibarr-tic649@8f6014fde11ec6cdec9a822234fc557e> // References: <1542377954.SMTPs-dolibarr-abc649@8f6014fde11ec6cdec9a822234fc557e> $trackid = ''; + $objectid = 0; + $objectemail = null; + $reg = array(); if (!empty($headers['References']) && preg_match('/dolibarr-([a-z]+)([0-9]+)@'.preg_quote($host, '/').'/', $headers['References'], $reg)) { $trackid = $reg[1].$reg[2]; - $objectid = 0; - $objectemail = null; if ($reg[1] == 'inv') { $objectid = $reg[2]; @@ -1423,9 +1424,9 @@ class EmailCollector extends CommonObject //var_dump($regexstring);var_dump($sourcestring); if (preg_match('/'.$regexstring.'/ms', $sourcestring, $regforval)) { - //var_dump($regforval[1]);exit; + //var_dump($regforval[count($regforval)-1]);exit; // Overwrite param $tmpproperty - $nametouseforthirdparty = isset($regforval[1]) ?trim($regforval[1]) : null; + $nametouseforthirdparty = isset($regforval[count($regforval)-1]) ?trim($regforval[count($regforval)-1]) : null; } else { @@ -1793,6 +1794,39 @@ class EmailCollector extends CommonObject } $tickettocreate->ref = $defaultref; } + // Create event specific on hook + // this code action is hook..... for support this call + elseif (substr($operation['type'], 0, 4) == 'hook'){ + global $hookmanager; + + if(!is_object($hookmanager)) + $hookmanager->initHooks(array('emailcollectorcard')); + + $parameters = array( + 'connection'=> $connection, + 'imapemail'=>$imapemail, + 'overview'=>$overview, + + 'from' => $from , + 'fromtext' => $fromtext, + + 'actionparam'=> $operation['actionparam'], + + + + 'thirdpartyid' => $thirdpartyid , + 'objectid'=> $objectid, + 'objectemail'=> $objectemail, + + 'messagetext'=>$messagetext, + 'subject'=>$subject, + 'header'=>$header, + ) ; + $res = $hookmanager->executeHooks('doCollectOneCollector', $parameters, $this, $operation['type']); + + if($res < 0 ) + $this->error = $hookmanager->resPrint; + } if ($errorforthisaction) { diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 66b47ab563f..b465297fe34 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -241,11 +241,11 @@ if (empty($reshook)) if ($objectsrc->lines[$i]->product_tobatch) // If product need a batch number { - if (isset($_POST[$batch])) + if (GETPOSTISSET($batch)) { //shipment line with batch-enable product $qty .= '_'.$j; - while (isset($_POST[$batch])) + while (GETPOSTISSET($batch)) { // save line of detail into sub_qty $sub_qty[$j]['q'] = GETPOST($qty, 'int'); // the qty we want to move for this stock record @@ -277,11 +277,11 @@ if (empty($reshook)) } } } - elseif (isset($_POST[$stockLocation])) + elseif (GETPOSTISSET($stockLocation)) { //shipment line from multiple stock locations $qty .= '_'.$j; - while (isset($_POST[$stockLocation])) + while (GETPOSTISSET($stockLocation)) { // save sub line of warehouse $stockLine[$i][$j]['qty'] = GETPOST($qty, 'int'); @@ -1578,7 +1578,7 @@ if ($action == 'create') //$line->fetch_optionals($line->id); $line->array_options = array_merge($line->array_options, $srcLine->array_options); - print $expLine->showOptionals($extrafields, 'edit', array('style'=>'class="drag drop oddeven"', 'colspan'=>$colspan), $indiceAsked, '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1); + print $expLine->showOptionals($extrafields, 'edit', array('style'=>'class="drag drop oddeven"', 'colspan'=>$colspan), $indiceAsked, '', 1); } } @@ -1967,7 +1967,7 @@ elseif ($id || $ref) // Tracking Number print ''; // Incoterms diff --git a/htdocs/expedition/class/api_shipments.class.php b/htdocs/expedition/class/api_shipments.class.php index 5aca14fb28d..8526f0c9610 100644 --- a/htdocs/expedition/class/api_shipments.class.php +++ b/htdocs/expedition/class/api_shipments.class.php @@ -373,8 +373,9 @@ class Shipments extends DolibarrApi * @url DELETE {id}/lines/{lineid} * * @return int - * @throws 401 - * @throws 404 + * + * @throws RestException 401 + * @throws RestException 404 */ public function deleteLine($id, $lineid) { @@ -537,10 +538,10 @@ class Shipments extends DolibarrApi // * // * @return int // * - // * @throws 400 - // * @throws 401 - // * @throws 404 - // * @throws 405 + // * @throws RestException 400 + // * @throws RestException 401 + // * @throws RestException 404 + // * @throws RestException 405 // */ /* public function setinvoiced($id) @@ -574,10 +575,10 @@ class Shipments extends DolibarrApi // * @url POST /createfromorder/{orderid} // * // * @return int - // * @throws 400 - // * @throws 401 - // * @throws 404 - // * @throws 405 + // * @throws RestException 400 + // * @throws RestException 401 + // * @throws RestException 404 + // * @throws RestException 405 // */ /* public function createShipmentFromOrder($orderid) diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index a3f5f21659d..4c6b7f46e47 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -85,6 +85,7 @@ class Expedition extends CommonObject /** * @var string internal ref + * @deprecated */ public $ref_int; @@ -447,7 +448,7 @@ class Expedition extends CommonObject * @param array $array_options extrafields array * @return int <0 if KO, line_id if OK */ - public function create_line($entrepot_id, $origin_line_id, $qty, $rang, $array_options = 0) + public function create_line($entrepot_id, $origin_line_id, $qty, $rang = 0, $array_options = 0) { //phpcs:enable global $user; @@ -523,15 +524,15 @@ class Expedition extends CommonObject * @param int $id Id of object to load * @param string $ref Ref of object * @param string $ref_ext External reference of object - * @param string $ref_int Internal reference of other object + * @param string $notused Internal reference of other object * @return int >0 if OK, 0 if not found, <0 if KO */ - public function fetch($id, $ref = '', $ref_ext = '', $ref_int = '') + public function fetch($id, $ref = '', $ref_ext = '', $notused = '') { global $conf; // Check parameters - if (empty($id) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1; + if (empty($id) && empty($ref) && empty($ref_ext)) return -1; $sql = "SELECT e.rowid, e.ref, e.fk_soc as socid, e.date_creation, e.ref_customer, e.ref_ext, e.ref_int, e.fk_user_author, e.fk_statut, e.fk_projet as fk_project, e.billed"; $sql.= ", e.date_valid"; @@ -551,7 +552,7 @@ class Expedition extends CommonObject if ($id) $sql.= " AND e.rowid=".$id; if ($ref) $sql.= " AND e.ref='".$this->db->escape($ref)."'"; if ($ref_ext) $sql.= " AND e.ref_ext='".$this->db->escape($ref_ext)."'"; - if ($ref_int) $sql.= " AND e.ref_int='".$this->db->escape($ref_int)."'"; + if ($notused) $sql.= " AND e.ref_int='".$this->db->escape($notused)."'"; dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $result = $this->db->query($sql); @@ -697,7 +698,7 @@ class Expedition extends CommonObject { $numref = "EXP".$this->id; } - $this->newref = $numref; + $this->newref = dol_sanitizeFileName($numref); $now = dol_now(); diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php index 60e5eafcb48..770d39ec951 100644 --- a/htdocs/expensereport/class/api_expensereports.class.php +++ b/htdocs/expensereport/class/api_expensereports.class.php @@ -33,7 +33,7 @@ class ExpenseReports extends DolibarrApi * @var array $FIELDS Mandatory fields, checked when create and update object */ static $FIELDS = array( - 'socid' + 'fk_user_author' ); /** @@ -384,6 +384,10 @@ class ExpenseReports extends DolibarrApi * @param array $request_data Datas * * @return int + * + * @throws RestException 401 Not allowed + * @throws RestException 404 Expense report not found + * @throws RestException 500 */ public function put($id, $request_data = null) { @@ -501,6 +505,11 @@ class ExpenseReports extends DolibarrApi // phpcs:enable $object = parent::_cleanObjectDatas($object); + unset($object->fk_statut); + unset($object->statut); + unset($object->user); + unset($object->thirdparty); + unset($object->cond_reglement); unset($object->shipping_method_id); @@ -509,6 +518,32 @@ class ExpenseReports extends DolibarrApi unset($object->barcode_type_label); unset($object->barcode_type_coder); + unset($object->code_paiement); + unset($object->code_statut); + unset($object->fk_c_paiement); + unset($object->fk_incoterms); + unset($object->label_incoterms); + unset($object->location_incoterms); + unset($object->mode_reglement_id); + unset($object->cond_reglement_id); + + unset($object->name); + unset($object->lastname); + unset($object->firstname); + unset($object->civility_id); + unset($object->cond_reglement_id); + unset($object->contact); + unset($object->contact_id); + + unset($object->state); + unset($object->state_id); + unset($object->state_code); + unset($object->country); + unset($object->country_id); + unset($object->country_code); + + unset($object->note); // We already use note_public and note_pricate + return $object; } diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index 05272aa2ff7..d78ac9e6261 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -58,19 +58,20 @@ class ExpenseReport extends CommonObject public $date_fin; + /** + * 0=draft, 2=validated (attente approb), 4=canceled, 5=approved, 6=payed, 99=denied + * + * @var int Status + */ public $status; - public $fk_statut; // -- 0=draft, 2=validated (attente approb), 4=canceled, 5=approved, 6=payed, 99=denied + public $fk_statut; + public $fk_c_paiement; public $paid; public $user_author_infos; public $user_validator_infos; - public $fk_typepayment; - public $num_payment; - public $code_paiement; - public $code_statut; - // ACTIONS // Create @@ -285,10 +286,33 @@ class ExpenseReport extends CommonObject { if (is_array($this->lines) && count($this->lines) > 0) { - foreach ($this->lines as $i => $val) + foreach ($this->lines as $line) { + // Test and convert into object this->lines[$i]. When coming from REST API, we may still have an array + //if (! is_object($line)) $line=json_decode(json_encode($line), false); // convert recursively array into object. + if (!is_object($line)) { + $line = (object) $line; + $newndfline = new ExpenseReportLine($this->db); + $newndfline->fk_expensereport = $line->fk_expensereport; + $newndfline->fk_c_type_fees = $line->fk_c_type_fees; + $newndfline->fk_project = $line->fk_project; + $newndfline->vatrate = $line->vatrate; + $newndfline->vat_src_code = $line->vat_src_code; + $newndfline->comments = $line->comments; + $newndfline->qty = $line->qty; + $newndfline->value_unit = $line->value_unit; + $newndfline->total_ht = $line->total_ht; + $newndfline->total_ttc = $line->total_ttc; + $newndfline->total_tva = $line->total_tva; + $newndfline->date = $line->date; + $newndfline->rule_warning_message = $line->rule_warning_message; + $newndfline->fk_c_exp_tax_cat = $line->fk_c_exp_tax_cat; + $newndfline->fk_ecm_files = $line->fk_ecm_files; + } + else { + $newndfline = $line; + } //$newndfline=new ExpenseReportLine($this->db); - $newndfline = $this->lines[$i]; $newndfline->fk_expensereport = $this->id; $result = $newndfline->insert(); if ($result < 0) @@ -514,10 +538,8 @@ class ExpenseReport extends CommonObject $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, d.paid,"; - $sql .= " dp.libelle as label_payment, dp.code as code_paiement"; // INNER JOIN paiement + $sql .= " d.fk_statut as status, d.fk_c_paiement, d.paid"; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as d"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as dp ON d.fk_c_paiement = dp.id"; if ($ref) $sql .= " WHERE d.ref = '".$this->db->escape($ref)."'"; else $sql .= " WHERE d.rowid = ".$id; //$sql.= $restrict; @@ -566,7 +588,7 @@ class ExpenseReport extends CommonObject elseif ($this->fk_user_validator > 0) $user_approver->fetch($this->fk_user_validator); // For backward compatibility $this->user_validator_infos = dolGetFirstLastname($user_approver->firstname, $user_approver->lastname); - $this->fk_statut = $obj->status; + $this->fk_statut = $obj->status; // deprecated $this->status = $obj->status; $this->fk_c_paiement = $obj->fk_c_paiement; $this->paid = $obj->paid; @@ -578,9 +600,6 @@ class ExpenseReport extends CommonObject $this->user_valid_infos = dolGetFirstLastname($user_valid->firstname, $user_valid->lastname); } - $this->code_statut = $obj->code_statut; - $this->code_paiement = $obj->code_paiement; - $this->lines = array(); $result = $this->fetch_lines(); @@ -996,7 +1015,9 @@ class ExpenseReport extends CommonObject public function fetch_lines() { // phpcs:enable - $this->lines = array(); + global $conf; + + $this->lines = array(); $sql = ' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,'; $sql .= ' de.'.$this->fk_element.', de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project, de.tva_tx, de.fk_ecm_files,'; @@ -1144,7 +1165,7 @@ class ExpenseReport extends CommonObject } if (empty($num) || $num < 0) return -1; - $this->newref = $num; + $this->newref = dol_sanitizeFileName($num); $this->db->begin(); @@ -1486,7 +1507,7 @@ class ExpenseReport extends CommonObject { // phpcs:enable $error = 0; - $this->date_cancel = $this->db->idate(gmmktime()); + $this->date_cancel = $this->db->idate(dol_now()); if ($this->fk_statut != self::STATUS_CANCELED) { $this->db->begin(); @@ -2650,7 +2671,7 @@ class ExpenseReportLine $sql .= " ".$this->db->escape($this->total_ht).","; $sql .= " ".$this->db->escape($this->total_tva).","; $sql .= " ".$this->db->escape($this->total_ttc).","; - $sql .= "'".$this->db->idate($this->date)."',"; + $sql .= " '".$this->db->idate($this->date)."',"; $sql .= " '".$this->db->escape($this->rule_warning_message)."',"; $sql .= " ".$this->db->escape($this->fk_c_exp_tax_cat).","; $sql .= " ".($this->fk_ecm_files > 0 ? $this->fk_ecm_files : 'null'); diff --git a/htdocs/expensereport/class/expensereport_ik.class.php b/htdocs/expensereport/class/expensereport_ik.class.php index bac8522ca74..c7bf959e27e 100644 --- a/htdocs/expensereport/class/expensereport_ik.class.php +++ b/htdocs/expensereport/class/expensereport_ik.class.php @@ -32,17 +32,17 @@ class ExpenseReportIk extends CoreObject /** * @var string ID to identify managed object */ - public $element='expenseik'; + public $element = 'expenseik'; /** * @var string Name of table without prefix where object is stored */ - public $table_element='expensereport_ik'; + public $table_element = 'expensereport_ik'; /** * @var int Field with ID of parent key if this field has a parent */ - public $fk_element='fk_expense_ik'; + public $fk_element = 'fk_expense_ik'; /** * c_exp_tax_cat Id @@ -72,10 +72,10 @@ class ExpenseReportIk extends CoreObject * Attribute object linked with database * @var array */ - protected $fields=array( - 'rowid'=>array('type'=>'integer','index'=>true) - ,'fk_c_exp_tax_cat'=>array('type'=>'integer','index'=>true) - ,'fk_range'=>array('type'=>'integer','index'=>true) + public $fields = array( + 'rowid'=>array('type'=>'integer', 'index'=>true) + ,'fk_c_exp_tax_cat'=>array('type'=>'integer', 'index'=>true) + ,'fk_range'=>array('type'=>'integer', 'index'=>true) ,'coef'=>array('type'=>'double') ,'ikoffset'=>array('type'=>'double') ); @@ -109,10 +109,10 @@ class ExpenseReportIk extends CoreObject $categories = array(); $sql = 'SELECT rowid, label, entity, active'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_cat'; - $sql.= ' WHERE entity IN ('. getEntity('c_exp_tax_cat').')'; - if ($mode == 1) $sql.= ' AND active = 1'; - elseif ($mode == 2) $sql.= 'AND active = 0'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_cat'; + $sql .= ' WHERE entity IN ('.getEntity('c_exp_tax_cat').')'; + if ($mode == 1) $sql .= ' AND active = 1'; + elseif ($mode == 2) $sql .= 'AND active = 0'; dol_syslog(get_called_class().'::getTaxCategories sql='.$sql, LOG_DEBUG); $resql = $db->query($sql); @@ -144,8 +144,8 @@ class ExpenseReportIk extends CoreObject $ranges = self::getRangesByCategory($fk_c_exp_tax_cat); // substract 1 because array start from 0 - if (empty($ranges) || !isset($ranges[$default_range-1])) return false; - else return $ranges[$default_range-1]; + if (empty($ranges) || !isset($ranges[$default_range - 1])) return false; + else return $ranges[$default_range - 1]; } /** @@ -162,10 +162,10 @@ class ExpenseReportIk extends CoreObject $ranges = array(); $sql = 'SELECT r.rowid FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r'; - if ($active) $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_c_exp_tax_cat = c.rowid)'; - $sql.= ' WHERE r.fk_c_exp_tax_cat = '.$fk_c_exp_tax_cat; - if ($active) $sql.= ' AND r.active = 1 AND c.active = 1'; - $sql.= ' ORDER BY r.range_ik'; + if ($active) $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_c_exp_tax_cat = c.rowid)'; + $sql .= ' WHERE r.fk_c_exp_tax_cat = '.$fk_c_exp_tax_cat; + if ($active) $sql .= ' AND r.active = 1 AND c.active = 1'; + $sql .= ' ORDER BY r.range_ik'; dol_syslog(get_called_class().'::getRangesByCategory sql='.$sql, LOG_DEBUG); $resql = $db->query($sql); @@ -203,11 +203,11 @@ class ExpenseReportIk extends CoreObject $ranges = array(); $sql = ' SELECT r.rowid, r.fk_c_exp_tax_cat, r.range_ik, c.label, i.rowid as fk_expense_ik, r.active as range_active, c.active as cat_active'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r'; - $sql.= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_c_exp_tax_cat = c.rowid)'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'expensereport_ik i ON (r.rowid = i.fk_range)'; - $sql.= ' WHERE r.entity IN (0, '. getEntity('').')'; - $sql.= ' ORDER BY r.fk_c_exp_tax_cat, r.range_ik'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r'; + $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_c_exp_tax_cat = c.rowid)'; + $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'expensereport_ik i ON (r.rowid = i.fk_range)'; + $sql .= ' WHERE r.entity IN (0, '.getEntity('').')'; + $sql .= ' ORDER BY r.fk_c_exp_tax_cat, r.range_ik'; dol_syslog(get_called_class().'::getAllRanges sql='.$sql, LOG_DEBUG); $resql = $db->query($sql); @@ -239,14 +239,14 @@ class ExpenseReportIk extends CoreObject */ public static function getMaxRangeNumber($default_c_exp_tax_cat = 0) { - global $db,$conf; + global $db, $conf; $sql = 'SELECT MAX(counted) as nbRange FROM ('; - $sql.= ' SELECT COUNT(*) as counted'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r'; - $sql.= ' WHERE r.entity IN (0, '.$conf->entity.')'; + $sql .= ' SELECT COUNT(*) as counted'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r'; + $sql .= ' WHERE r.entity IN (0, '.$conf->entity.')'; if ($default_c_exp_tax_cat > 0) $sql .= ' AND r.fk_c_exp_tax_cat = '.$default_c_exp_tax_cat; - $sql.= ' GROUP BY r.fk_c_exp_tax_cat'; + $sql .= ' GROUP BY r.fk_c_exp_tax_cat'; $sql .= ') as counts'; dol_syslog(get_called_class().'::getMaxRangeNumber sql='.$sql, LOG_DEBUG); diff --git a/htdocs/expensereport/class/expensereport_rule.class.php b/htdocs/expensereport/class/expensereport_rule.class.php index 9726184a94a..b98552f681d 100644 --- a/htdocs/expensereport/class/expensereport_rule.class.php +++ b/htdocs/expensereport/class/expensereport_rule.class.php @@ -32,17 +32,17 @@ class ExpenseReportRule extends CoreObject /** * @var string ID to identify managed object */ - public $element='expenserule'; + public $element = 'expenserule'; /** * @var string Name of table without prefix where object is stored */ - public $table_element='expensereport_rules'; + public $table_element = 'expensereport_rules'; /** * @var int Field with ID of parent key if this field has a parent */ - public $fk_element='fk_expense_rule'; + public $fk_element = 'fk_expense_rule'; /** * date start @@ -111,8 +111,8 @@ class ExpenseReportRule extends CoreObject * Attribute object linked with database * @var array */ - protected $fields=array( - 'rowid'=>array('type'=>'integer','index'=>true) + public $fields = array( + 'rowid'=>array('type'=>'integer', 'index'=>true) ,'dates'=>array('type'=>'date') ,'datee'=>array('type'=>'date') ,'amount'=>array('type'=>'double') @@ -154,25 +154,25 @@ class ExpenseReportRule extends CoreObject $rules = array(); $sql = 'SELECT er.rowid'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'expensereport_rules er'; - $sql.= ' WHERE er.entity IN (0,'. getEntity('').')'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'expensereport_rules er'; + $sql .= ' WHERE er.entity IN (0,'.getEntity('').')'; if (!empty($fk_c_type_fees)) { - $sql.= ' AND er.fk_c_type_fees IN (-1, '.$fk_c_type_fees.')'; + $sql .= ' AND er.fk_c_type_fees IN (-1, '.$fk_c_type_fees.')'; } if (!empty($date)) { $date = dol_print_date($date, '%Y-%m-%d'); - $sql.= ' AND er.dates <= \''.$date.'\''; - $sql.= ' AND er.datee >= \''.$date.'\''; + $sql .= ' AND er.dates <= \''.$date.'\''; + $sql .= ' AND er.datee >= \''.$date.'\''; } if ($fk_user > 0) { - $sql.= ' AND (er.is_for_all = 1'; - $sql.= ' OR er.fk_user = '.$fk_user; - $sql.= ' OR er.fk_usergroup IN (SELECT ugu.fk_usergroup FROM '.MAIN_DB_PREFIX.'usergroup_user ugu WHERE ugu.fk_user = '.$fk_user.') )'; + $sql .= ' AND (er.is_for_all = 1'; + $sql .= ' OR er.fk_user = '.$fk_user; + $sql .= ' OR er.fk_usergroup IN (SELECT ugu.fk_usergroup FROM '.MAIN_DB_PREFIX.'usergroup_user ugu WHERE ugu.fk_user = '.$fk_user.') )'; } - $sql.= ' ORDER BY er.is_for_all, er.fk_usergroup, er.fk_user'; + $sql .= ' ORDER BY er.is_for_all, er.fk_usergroup, er.fk_user'; dol_syslog("ExpenseReportRule::getAllRule sql=".$sql); diff --git a/htdocs/expensereport/index.php b/htdocs/expensereport/index.php index ec6f78d91f7..77cf3bb481e 100644 --- a/htdocs/expensereport/index.php +++ b/htdocs/expensereport/index.php @@ -136,10 +136,10 @@ if ($conf->use_javascript_ajax) $dolgraph->SetData($dataseries); $dolgraph->setHeight(350); $dolgraph->combine = empty($conf->global->MAIN_EXPENSEREPORT_COMBINE_GRAPH_STAT) ? 0.05 : $conf->global->MAIN_EXPENSEREPORT_COMBINE_GRAPH_STAT; - $dolgraph->setShowLegend(1); + $dolgraph->setShowLegend(2); $dolgraph->setShowPercent(1); $dolgraph->SetType(array('pie')); - $dolgraph->setWidth('100%'); + $dolgraph->setHeight('200'); $dolgraph->draw('idgraphstatus'); print $dolgraph->show($totalnb ? 0 : 1); diff --git a/htdocs/expensereport/payment/payment.php b/htdocs/expensereport/payment/payment.php index 2f915b3f8e8..15073c50620 100644 --- a/htdocs/expensereport/payment/payment.php +++ b/htdocs/expensereport/payment/payment.php @@ -248,14 +248,14 @@ if ($action == 'create' || empty($action)) print '
- - +
Date et signature

+ '; print ''; print ''; print ''; +print ''; print ''; -if ($conf->multicompany->enabled) { +if ($conf->multicompany->enabled){ print ''; } print ''; @@ -92,6 +93,7 @@ if (is_array($extrafields->attributes[$elementtype]['type']) && count($extrafiel print '\n"; print '\n"; print '\n"; + print '\n"; print '\n"; if (! empty($conf->multicompany->enabled)) { print '\n"; //Line extrafield if (!empty($extrafields)) { - print $line->showOptionals($extrafields, 'view', array('style'=>'class="drag drop oddeven"', 'colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1); + print $line->showOptionals($extrafields, 'view', array('style'=>'class="drag drop oddeven"', 'colspan'=>$coldisplay), '', '', 1); } print "\n"; diff --git a/htdocs/core/triggers/interface_20_all_Logevents.class.php b/htdocs/core/triggers/interface_20_all_Logevents.class.php index 93d1b37c690..66e1b6fa4cd 100644 --- a/htdocs/core/triggers/interface_20_all_Logevents.class.php +++ b/htdocs/core/triggers/interface_20_all_Logevents.class.php @@ -206,9 +206,10 @@ class InterfaceLogevents extends DolibarrTriggers else { $error ="Failed to insert security event: ".$event->error; + $this->errors[] = $error; $this->error=$error; - dol_syslog(get_class($this).": ".$this->error, LOG_ERR); + dol_syslog(get_class($this).": ".$error, LOG_ERR); return -1; } } diff --git a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php index 26958aed875..161ebe6cd73 100644 --- a/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php +++ b/htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php @@ -829,7 +829,7 @@ class InterfaceActionsAuto extends DolibarrTriggers $object->sendtoid=0; } // TODO Merge all previous cases into this generic one - else // $action = TICKET_CREATE, TICKET_MODIFY, TICKET_DELETE, ... + else // $action = BILL_DELETE, TICKET_CREATE, TICKET_MODIFY, TICKET_DELETE, ... { // Note: We are here only if $conf->global->MAIN_AGENDA_ACTIONAUTO_action is on (tested at begining of this function). Key can be set in agenda setup if defined into c_action_trigger // Load translation files required by the page diff --git a/htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php b/htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php index b50008dba2e..b51fd0a20b7 100644 --- a/htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php +++ b/htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php @@ -1,10 +1,11 @@ - * Copyright (C) 2009-2017 Regis Houssin - * Copyright (C) 2011-2014 Juanjo Menent - * Copyright (C) 2013 Cedric GROSS - * Copyright (C) 2014 Marcos García - * Copyright (C) 2015 Bahfir Abbes +/* + * Copyright (C) 2005-2017 Laurent Destailleur + * Copyright (C) 2009-2017 Regis Houssin + * Copyright (C) 2011-2014 Juanjo Menent + * Copyright (C) 2013 Cedric GROSS + * Copyright (C) 2014 Marcos García + * Copyright (C) 2015 Bahfir Abbes * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +14,7 @@ * * 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 + * 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 @@ -21,29 +22,31 @@ */ /** - * \file htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php - * \ingroup agenda - * \brief Trigger file for company - contactroles + * \file htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php + * \ingroup agenda + * \brief Trigger file for company - contactroles */ - require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php'; - /** - * Class of triggered functions for agenda module + * Class of triggered functions for agenda module */ class InterfaceContactRoles extends DolibarrTriggers { + public $family = 'agenda'; + public $description = "Triggers of this module auto link contact to company."; /** * Version of the trigger + * * @var string */ public $version = self::VERSION_DOLIBARR; /** + * * @var string Image of the trigger */ public $picto = 'action'; @@ -53,56 +56,56 @@ class InterfaceContactRoles extends DolibarrTriggers * All functions "runTrigger" are triggered if file is inside directory htdocs/core/triggers or htdocs/module/code/triggers (and declared) * * Following properties may be set before calling trigger. The may be completed by this trigger to be used for writing the event into database: - * $object->socid or $object->fk_soc(id of thirdparty) - * $object->element (element type of object) + * $object->socid or $object->fk_soc(id of thirdparty) + * $object->element (element type of object) * - * @param string $action Event action code - * @param Object $object Object - * @param User $user Object user - * @param Translate $langs Object langs - * @param conf $conf Object conf - * @return int <0 if KO, 0 if no triggered ran, >0 if OK + * @param string $action Event action code + * @param Object $object Object + * @param User $user Object user + * @param Translate $langs Object langs + * @param conf $conf Object conf + * @return int <0 if KO, 0 if no triggered ran, >0 if OK */ public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) { - - if ($action === 'PROPAL_CREATE' || $action === 'ORDER_CREATE' || $action === 'BILL_CREATE' || $action === 'ORDER_SUPPLIER_CREATE' || $action === 'BILL_SUPPLIER_CREATE' - || $action === 'CONTRACT_CREATE' || $action === 'FICHINTER_CREATE' || $action === 'PROJECT_CREATE' || $action === 'TICKET_CREATE' || $action === 'ACTION_CREATE') { + if ($action === 'PROPAL_CREATE' || $action === 'ORDER_CREATE' || $action === 'BILL_CREATE' + || $action === 'ORDER_SUPPLIER_CREATE' || $action === 'BILL_SUPPLIER_CREATE' || $action === 'PROPOSAL_SUPPLIER_CREATE' + || $action === 'CONTRACT_CREATE' || $action === 'FICHINTER_CREATE' || $action === 'PROJECT_CREATE' || $action === 'TICKET_CREATE') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); - $socid=(property_exists($object, 'socid')?$object->socid:$object->fk_soc); + $socid = (property_exists($object, 'socid') ? $object->socid : $object->fk_soc); - if (! empty($socid) && $socid > 0) { + if (!empty($socid) && $socid > 0) { require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; $contactdefault = new Contact($this->db); - $contactdefault->socid=$socid; + $contactdefault->socid = $socid; $TContact = $contactdefault->getContactRoles($object->element); - $TContactAlreadyLinked = array(); - if ($object->id > 0) - { - $class = get_class($object); - $cloneFrom = new $class($this->db); - $r = $cloneFrom->fetch($object->id); + if (is_array($TContact) && !empty($TContact)) { + $TContactAlreadyLinked = array(); + if ($object->id > 0) { + $cloneFrom = dol_clone($object, 1); - if (!empty($cloneFrom->id)) $TContactAlreadyLinked = array_merge($cloneFrom->liste_contact(-1, 'external'), $cloneFrom->liste_contact(-1, 'internal')); - } + if (!empty($cloneFrom->id)) { + $TContactAlreadyLinked = array_merge($cloneFrom->liste_contact(-1, 'external'), $cloneFrom->liste_contact(-1, 'internal')); + } + } - if (is_array($TContact)) - { - foreach($TContact as $i => $infos) { + foreach ($TContact as $i => $infos) { foreach ($TContactAlreadyLinked as $contactData) { - if ($contactData['id'] == $infos['fk_socpeople'] && $contactData['fk_c_type_contact'] == $infos['type_contact']) unset($TContact[$i]); + if ($contactData['id'] == $infos['fk_socpeople'] && $contactData['fk_c_type_contact'] == $infos['type_contact']) + unset($TContact[$i]); } } $nb = 0; - foreach($TContact as $infos) { + foreach ($TContact as $infos) { $res = $object->add_contact($infos['fk_socpeople'], $infos['type_contact']); - if ($res > 0) $nb++; + if ($res > 0) + $nb++; } - if($nb > 0) { + if ($nb > 0) { setEventMessages($langs->trans('ContactAddedAutomatically', $nb), null, 'mesgs'); } } diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index 82a898a8ddf..6d7b17f7fe0 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1094,7 +1094,7 @@ class Cronjob extends CommonObject $errmsg = ''; if (!is_array($object->errors) || !in_array($object->error, $object->errors)) $errmsg .= $object->error; - if (is_array($object->errors) && count($object->errors)) $errmsg .= ($errmsg ? ', '.$errmsg : '').join(', ', $object->errors); + if (is_array($object->errors) && count($object->errors)) $errmsg .= (($errmsg ? ', ' : '').join(', ', $object->errors)); if (empty($errmsg)) $errmsg = $langs->trans('ErrorUnknown'); dol_syslog(get_class($this)."::run_jobs END result=".$result." error=".$errmsg, LOG_ERR); @@ -1320,9 +1320,9 @@ class Cronjob extends CommonObject if ($processing) $moretext = ' ('.$langs->trans("Running").')'; elseif ($lastresult) $moretext .= ' ('.$langs->trans("Error").')'; - $this->labelStatus[self::STATUS_DISABLED] = $langs->trans('Draft').$moretext; + $this->labelStatus[self::STATUS_DISABLED] = $langs->trans('Disabled').$moretext; $this->labelStatus[self::STATUS_ENABLED] = $langs->trans('Enabled').$moretext; - $this->labelStatusShort[self::STATUS_DISABLED] = $langs->trans('Draft'); + $this->labelStatusShort[self::STATUS_DISABLED] = $langs->trans('Disabled'); $this->labelStatusShort[self::STATUS_ENABLED] = $langs->trans('Enabled'); } diff --git a/htdocs/dav/dav.class.php b/htdocs/dav/dav.class.php index 7bb598135f3..145da542976 100644 --- a/htdocs/dav/dav.class.php +++ b/htdocs/dav/dav.class.php @@ -175,7 +175,7 @@ class CdavLib $caldata.="LAST-MODIFIED:".gmdate('Ymd\THis', strtotime($obj->lastupd))."Z\n"; $caldata.="DTSTAMP:".gmdate('Ymd\THis', strtotime($obj->lastupd))."Z\n"; if($obj->sourceuid=='') - $caldata.="UID:".$obj->id.'-ev-'.$calid.'-cal-'.CDAV_URI_KEY."\n"; + $caldata.="UID:".$obj->id.'-ev-'.$calid.'-cal-'.constant('CDAV_URI_KEY')."\n"; else $caldata.="UID:".$obj->sourceuid."\n"; $caldata.="SUMMARY:".$obj->label."\n"; @@ -277,7 +277,7 @@ class CdavLib { $calevents[] = array( 'calendardata' => $calendardata, - 'uri' => $obj->id.'-ev-'.CDAV_URI_KEY, + 'uri' => $obj->id.'-ev-'.constant('CDAV_URI_KEY'), 'lastmodified' => strtotime($obj->lastupd), 'etag' => '"'.md5($calendardata).'"', 'calendarid' => $calendarId, @@ -289,7 +289,7 @@ class CdavLib { $calevents[] = array( // 'calendardata' => $calendardata, not necessary because etag+size are present - 'uri' => $obj->id.'-ev-'.CDAV_URI_KEY, + 'uri' => $obj->id.'-ev-'.constant('CDAV_URI_KEY'), 'lastmodified' => strtotime($obj->lastupd), 'etag' => '"'.md5($calendardata).'"', 'calendarid' => $calendarId, diff --git a/htdocs/don/admin/donation.php b/htdocs/don/admin/donation.php index 9387c1a099d..e8e7fa4f5b9 100644 --- a/htdocs/don/admin/donation.php +++ b/htdocs/don/admin/donation.php @@ -2,9 +2,9 @@ /* Copyright (C) 2005-2010 Laurent Destailleur * Copyright (C) 2012-2015 Juanjo Menent * Copyright (C) 2013-2017 Philippe Grand - * Copyright (C) 2015-2017 Alexandre Spangaro + * Copyright (C) 2015-2020 Alexandre Spangaro * Copyright (C) 2015 Benoit Bruchard - * Copyright (C) 2019 Thibault FOUCART + * Copyright (C) 2019 Thibault FOUCART * * 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 @@ -431,13 +431,13 @@ if (preg_match('/fr/i', $conf->global->MAIN_INFO_SOCIETE_COUNTRY)) print ''; print ''; - print ''; + print ''; print ''; print "
Date et signature
'; } - elseif ($don->modepaymentcode=='LIQ'){ + elseif ($don->modepaymentcode == 'LIQ') { $ModePaiement = ''; } - elseif ($don->modepaymentcode=='VIR' || $don->modepaymentcode=='PRE' || $don->modepaymentcode=='CB'){ + elseif ($don->modepaymentcode == 'VIR' || $don->modepaymentcode == 'PRE' || $don->modepaymentcode == 'CB') { $ModePaiement = ''; } else @@ -150,16 +150,16 @@ class html_cerfafr extends ModeleDon /* if (empty($don->societe)) { - $CodeDon = ''; + $CodeDon = ''; } else { - $CodeDon = ''; + $CodeDon = ''; } */ // Define contents - $donmodel=DOL_DOCUMENT_ROOT ."/core/modules/dons/html_cerfafr.html"; + $donmodel = DOL_DOCUMENT_ROOT."/core/modules/dons/html_cerfafr.html"; $form = implode('', file($donmodel)); $form = str_replace('__REF__', $don->id, $form); $form = str_replace('__DATE__', dol_print_date($don->date, 'day', false, $outputlangs), $form); @@ -203,59 +203,59 @@ class html_cerfafr extends ModeleDon $form = str_replace('__ModePaiement__', $ModePaiement, $form); - $frencharticle=''; - if (preg_match('/fr/i', $outputlangs->defaultlang)) $frencharticle='Article 200, 238 bis et 885-0 V bis A du code général des impôts (CGI)'; + $frencharticle = ''; + if (preg_match('/fr/i', $outputlangs->defaultlang)) $frencharticle = 'Article 200, 238 bis et 978 du code général des impôts (CGI)'; $form = str_replace('__FrenchArticle__', $frencharticle, $form); - $frencheligibility=''; - if (preg_match('/fr/i', $outputlangs->defaultlang)) $frencheligibility='Le bénéficiaire certifie sur l\'honneur que les dons et versements qu\'il reçoit ouvrent droit à la réduction d\'impôt prévue à l\'article :'; + $frencheligibility = ''; + if (preg_match('/fr/i', $outputlangs->defaultlang)) $frencheligibility = 'Le bénéficiaire certifie sur l\'honneur que les dons et versements qu\'il reçoit ouvrent droit à la réduction d\'impôt prévue à l\'article :'; $form = str_replace('__FrenchEligibility__', $frencheligibility, $form); - $art200=''; + $art200 = ''; if (preg_match('/fr/i', $outputlangs->defaultlang)) { if ($conf->global->DONATION_ART200 >= 1) { - $art200='200 du CGI'; + $art200 = '200 du CGI'; } else { - $art200='200 du CGI'; + $art200 = '200 du CGI'; } } $form = str_replace('__ARTICLE200__', $art200, $form); - $art238=''; + $art238 = ''; if (preg_match('/fr/i', $outputlangs->defaultlang)) { if ($conf->global->DONATION_ART238 >= 1) { - $art238='238 bis du CGI'; + $art238 = '238 bis du CGI'; } else { - $art238='238 bis du CGI'; + $art238 = '238 bis du CGI'; } } $form = str_replace('__ARTICLE238__', $art238, $form); - $art885=''; + $art978 = ''; if (preg_match('/fr/i', $outputlangs->defaultlang)) { - if ($conf->global->DONATION_ART885 >= 1) + if ($conf->global->DONATION_ART978 >= 1) { - $art885='885-0 V bis du CGI'; + $art978 = '978 du CGI'; } else { - $art885='885-0 V bis du CGI'; + $art978 = '978 du CGI'; } } - $form = str_replace('__ARTICLE885__', $art885, $form); + $form = str_replace('__ARTICLE978__', $art978, $form); // Save file on disk dol_syslog("html_cerfafr::write_file $file"); - $handle=fopen($file, "w"); + $handle = fopen($file, "w"); fwrite($handle, $form); fclose($handle); - if (! empty($conf->global->MAIN_UMASK)) + if (!empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); $this->result = array('fullpath'=>$file); @@ -264,13 +264,13 @@ class html_cerfafr extends ModeleDon } else { - $this->error=$langs->trans("ErrorCanNotCreateDir", $dir); + $this->error = $langs->trans("ErrorCanNotCreateDir", $dir); return 0; } } else { - $this->error=$langs->trans("ErrorConstantNotDefined", "DON_OUTPUTDIR"); + $this->error = $langs->trans("ErrorConstantNotDefined", "DON_OUTPUTDIR"); return 0; } } @@ -288,147 +288,147 @@ class html_cerfafr extends ModeleDon $unite = array(); $dix = array(); $cent = array(); - if(empty($devise1)) $dev1='euros'; - else $dev1=$devise1; - if(empty($devise2)) $dev2='centimes'; - else $dev2=$devise2; - $valeur_entiere=intval($montant); - $valeur_decimal=intval(round($montant-intval($montant), 2)*100); - $dix_c=intval($valeur_decimal%100/10); - $cent_c=intval($valeur_decimal%1000/100); - $unite[1]=$valeur_entiere%10; - $dix[1]=intval($valeur_entiere%100/10); - $cent[1]=intval($valeur_entiere%1000/100); - $unite[2]=intval($valeur_entiere%10000/1000); - $dix[2]=intval($valeur_entiere%100000/10000); - $cent[2]=intval($valeur_entiere%1000000/100000); - $unite[3]=intval($valeur_entiere%10000000/1000000); - $dix[3]=intval($valeur_entiere%100000000/10000000); - $cent[3]=intval($valeur_entiere%1000000000/100000000); - $chif=array('', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix sept', 'dix huit', 'dix neuf'); - $secon_c=''; - $trio_c=''; - for($i=1; $i<=3; $i++) { - $prim[$i]=''; - $secon[$i]=''; - $trio[$i]=''; - if ($dix[$i]==0) { - $secon[$i]=''; - $prim[$i]=$chif[$unite[$i]]; + if (empty($devise1)) $dev1 = 'euros'; + else $dev1 = $devise1; + if (empty($devise2)) $dev2 = 'centimes'; + else $dev2 = $devise2; + $valeur_entiere = intval($montant); + $valeur_decimal = intval(round($montant - intval($montant), 2) * 100); + $dix_c = intval($valeur_decimal % 100 / 10); + $cent_c = intval($valeur_decimal % 1000 / 100); + $unite[1] = $valeur_entiere % 10; + $dix[1] = intval($valeur_entiere % 100 / 10); + $cent[1] = intval($valeur_entiere % 1000 / 100); + $unite[2] = intval($valeur_entiere % 10000 / 1000); + $dix[2] = intval($valeur_entiere % 100000 / 10000); + $cent[2] = intval($valeur_entiere % 1000000 / 100000); + $unite[3] = intval($valeur_entiere % 10000000 / 1000000); + $dix[3] = intval($valeur_entiere % 100000000 / 10000000); + $cent[3] = intval($valeur_entiere % 1000000000 / 100000000); + $chif = array('', 'un', 'deux', 'trois', 'quatre', 'cinq', 'six', 'sept', 'huit', 'neuf', 'dix', 'onze', 'douze', 'treize', 'quatorze', 'quinze', 'seize', 'dix sept', 'dix huit', 'dix neuf'); + $secon_c = ''; + $trio_c = ''; + for ($i = 1; $i <= 3; $i++) { + $prim[$i] = ''; + $secon[$i] = ''; + $trio[$i] = ''; + if ($dix[$i] == 0) { + $secon[$i] = ''; + $prim[$i] = $chif[$unite[$i]]; } - elseif ($dix[$i]==1) { - $secon[$i]=''; - $prim[$i]=$chif[($unite[$i]+10)]; + elseif ($dix[$i] == 1) { + $secon[$i] = ''; + $prim[$i] = $chif[($unite[$i] + 10)]; } - elseif ($dix[$i]==2) { - if ($unite[$i]==1) { - $secon[$i]='vingt et'; - $prim[$i]=$chif[$unite[$i]]; + elseif ($dix[$i] == 2) { + if ($unite[$i] == 1) { + $secon[$i] = 'vingt et'; + $prim[$i] = $chif[$unite[$i]]; } else { - $secon[$i]='vingt'; - $prim[$i]=$chif[$unite[$i]]; + $secon[$i] = 'vingt'; + $prim[$i] = $chif[$unite[$i]]; } } - elseif ($dix[$i]==3) { - if ($unite[$i]==1) { - $secon[$i]='trente et'; - $prim[$i]=$chif[$unite[$i]]; + elseif ($dix[$i] == 3) { + if ($unite[$i] == 1) { + $secon[$i] = 'trente et'; + $prim[$i] = $chif[$unite[$i]]; } else { - $secon[$i]='trente'; - $prim[$i]=$chif[$unite[$i]]; + $secon[$i] = 'trente'; + $prim[$i] = $chif[$unite[$i]]; } } - elseif ($dix[$i]==4) { - if ($unite[$i]==1) { - $secon[$i]='quarante et'; - $prim[$i]=$chif[$unite[$i]]; + elseif ($dix[$i] == 4) { + if ($unite[$i] == 1) { + $secon[$i] = 'quarante et'; + $prim[$i] = $chif[$unite[$i]]; } else { - $secon[$i]='quarante'; - $prim[$i]=$chif[$unite[$i]]; + $secon[$i] = 'quarante'; + $prim[$i] = $chif[$unite[$i]]; } } - elseif ($dix[$i]==5) { - if ($unite[$i]==1) { - $secon[$i]='cinquante et'; - $prim[$i]=$chif[$unite[$i]]; + elseif ($dix[$i] == 5) { + if ($unite[$i] == 1) { + $secon[$i] = 'cinquante et'; + $prim[$i] = $chif[$unite[$i]]; } else { - $secon[$i]='cinquante'; - $prim[$i]=$chif[$unite[$i]]; + $secon[$i] = 'cinquante'; + $prim[$i] = $chif[$unite[$i]]; } } - elseif ($dix[$i]==6) { - if ($unite[$i]==1) { - $secon[$i]='soixante et'; - $prim[$i]=$chif[$unite[$i]]; + elseif ($dix[$i] == 6) { + if ($unite[$i] == 1) { + $secon[$i] = 'soixante et'; + $prim[$i] = $chif[$unite[$i]]; } else { - $secon[$i]='soixante'; - $prim[$i]=$chif[$unite[$i]]; + $secon[$i] = 'soixante'; + $prim[$i] = $chif[$unite[$i]]; } } - elseif ($dix[$i]==7) { - if ($unite[$i]==1) { - $secon[$i]='soixante et'; - $prim[$i]=$chif[$unite[$i]+10]; + elseif ($dix[$i] == 7) { + if ($unite[$i] == 1) { + $secon[$i] = 'soixante et'; + $prim[$i] = $chif[$unite[$i] + 10]; } else { - $secon[$i]='soixante'; - $prim[$i]=$chif[$unite[$i]+10]; + $secon[$i] = 'soixante'; + $prim[$i] = $chif[$unite[$i] + 10]; } } - elseif ($dix[$i]==8) { - if ($unite[$i]==1) { - $secon[$i]='quatre-vingts et'; - $prim[$i]=$chif[$unite[$i]]; + elseif ($dix[$i] == 8) { + if ($unite[$i] == 1) { + $secon[$i] = 'quatre-vingts et'; + $prim[$i] = $chif[$unite[$i]]; } else { - $secon[$i]='quatre-vingt'; - $prim[$i]=$chif[$unite[$i]]; + $secon[$i] = 'quatre-vingt'; + $prim[$i] = $chif[$unite[$i]]; } } - elseif ($dix[$i]==9) { - if ($unite[$i]==1) { - $secon[$i]='quatre-vingts et'; - $prim[$i]=$chif[$unite[$i]+10]; + elseif ($dix[$i] == 9) { + if ($unite[$i] == 1) { + $secon[$i] = 'quatre-vingts et'; + $prim[$i] = $chif[$unite[$i] + 10]; } else { - $secon[$i]='quatre-vingts'; - $prim[$i]=$chif[$unite[$i]+10]; + $secon[$i] = 'quatre-vingts'; + $prim[$i] = $chif[$unite[$i] + 10]; } } - if($cent[$i]==1) $trio[$i]='cent'; - elseif($cent[$i]!=0 || $cent[$i]!='') $trio[$i]=$chif[$cent[$i]] .' cents'; + if ($cent[$i] == 1) $trio[$i] = 'cent'; + elseif ($cent[$i] != 0 || $cent[$i] != '') $trio[$i] = $chif[$cent[$i]].' cents'; } - $chif2=array('', 'dix', 'vingt', 'trente', 'quarante', 'cinquante', 'soixante', 'soixante-dix', 'quatre-vingts', 'quatre-vingts dix'); - $secon_c=$chif2[$dix_c]; - if ($cent_c==1) $trio_c='cent'; - elseif ($cent_c!=0 || $cent_c!='') $trio_c=$chif[$cent_c] .' cents'; + $chif2 = array('', 'dix', 'vingt', 'trente', 'quarante', 'cinquante', 'soixante', 'soixante-dix', 'quatre-vingts', 'quatre-vingts dix'); + $secon_c = $chif2[$dix_c]; + if ($cent_c == 1) $trio_c = 'cent'; + elseif ($cent_c != 0 || $cent_c != '') $trio_c = $chif[$cent_c].' cents'; - if (($cent[3]==0 || $cent[3]=='') && ($dix[3]==0 || $dix[3]=='') && ($unite[3]==1)) - $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]. ' million '; - elseif (($cent[3]!=0 && $cent[3]!='') || ($dix[3]!=0 && $dix[3]!='') || ($unite[3]!=0 && $unite[3]!='')) - $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]. ' millions '; + if (($cent[3] == 0 || $cent[3] == '') && ($dix[3] == 0 || $dix[3] == '') && ($unite[3] == 1)) + $somme = $trio[3].' '.$secon[3].' '.$prim[3].' million '; + elseif (($cent[3] != 0 && $cent[3] != '') || ($dix[3] != 0 && $dix[3] != '') || ($unite[3] != 0 && $unite[3] != '')) + $somme = $trio[3].' '.$secon[3].' '.$prim[3].' millions '; else - $somme = $trio[3]. ' ' .$secon[3]. ' ' . $prim[3]; + $somme = $trio[3].' '.$secon[3].' '.$prim[3]; - if (($cent[2]==0 || $cent[2]=='') && ($dix[2]==0 || $dix[2]=='') && ($unite[2]==1)) + if (($cent[2] == 0 || $cent[2] == '') && ($dix[2] == 0 || $dix[2] == '') && ($unite[2] == 1)) $somme = $somme.' mille '; - elseif (($cent[2]!=0 && $cent[2]!='') || ($dix[2]!=0 && $dix[2]!='') || ($unite[2]!=0 && $unite[2]!='')) - $somme = $somme. $trio[2]. ' ' .$secon[2]. ' ' . $prim[2]. ' milles '; + elseif (($cent[2] != 0 && $cent[2] != '') || ($dix[2] != 0 && $dix[2] != '') || ($unite[2] != 0 && $unite[2] != '')) + $somme = $somme.$trio[2].' '.$secon[2].' '.$prim[2].' milles '; else - $somme = $somme. $trio[2]. ' ' .$secon[2]. ' ' . $prim[2]; + $somme = $somme.$trio[2].' '.$secon[2].' '.$prim[2]; - $somme = $somme. $trio[1]. ' ' .$secon[1]. ' ' . $prim[1]; + $somme = $somme.$trio[1].' '.$secon[1].' '.$prim[1]; - $somme = $somme. ' '. $dev1 .' ' ; + $somme = $somme.' '.$dev1.' '; - if (($cent_c=='0' || $cent_c=='') && ($dix_c=='0' || $dix_c=='')) - return $somme. ' et zéro '. $dev2; + if (($cent_c == '0' || $cent_c == '') && ($dix_c == '0' || $dix_c == '')) + return $somme.' et zéro '.$dev2; else - return $somme. $trio_c. ' ' .$secon_c. ' ' . $dev2; + return $somme.$trio_c.' '.$secon_c.' '.$dev2; } } diff --git a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php index 52e41ea2589..6268f84d127 100644 --- a/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_espadon.modules.php @@ -313,6 +313,8 @@ class pdf_espadon extends ModelePdfExpedition $tab_height = 130; $tab_height_newpage = 150; + $this->posxdesc = $this->marge_gauche + 1; + // Incoterm $height_incoterms = 0; if ($conf->incoterm->enabled) @@ -336,7 +338,17 @@ class pdf_espadon extends ModelePdfExpedition } } - if (!empty($object->note_public) || !empty($object->tracking_number)) + // display note + $notetoshow = empty($object->note_public) ? '' : $object->note_public; + + // Extrafields in note + $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); + if (!empty($extranote)) + { + $notetoshow = dol_concatdesc($notetoshow, $extranote); + } + + if (!empty($notetoshow) || !empty($object->tracking_number)) { $tab_top = 88 + $height_incoterms; $tab_top_alt = $tab_top; @@ -375,10 +387,10 @@ class pdf_espadon extends ModelePdfExpedition } // Notes - if (!empty($object->note_public)) + if (!empty($notetoshow)) { $pdf->SetFont('', '', $default_font_size - 1); // In loop to manage multi-page - $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top_alt, dol_htmlentitiesbr($object->note_public), 0, 1); + $pdf->writeHTMLCell(190, 3, $this->posxdesc - 1, $tab_top_alt, dol_htmlentitiesbr($notetoshow), 0, 1); } $nexY = $pdf->GetY(); @@ -406,9 +418,7 @@ class pdf_espadon extends ModelePdfExpedition $pdf->rollbackTransaction(true); - $iniY = $tab_top + $this->tabTitleHeight + 2; - $curY = $tab_top + $this->tabTitleHeight + 2; - $nexY = $tab_top + $this->tabTitleHeight + 2; + $nexY = $tab_top + $this->tabTitleHeight; // Loop on each lines for ($i = 0; $i < $nblines; $i++) @@ -440,7 +450,12 @@ class pdf_espadon extends ModelePdfExpedition $pdf->setPage($pageposbefore + 1); $curY = $tab_top_newpage; - $showpricebeforepagebreak = 0; + + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } @@ -456,15 +471,15 @@ class pdf_espadon extends ModelePdfExpedition if ($this->getColumnStatus('desc')) { $pdf->startTransaction(); - pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc); - $pageposafter = $pdf->getPage(); + + $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); + + $pageposafter = $pdf->getPage(); if ($pageposafter > $pageposbefore) // There is a pagebreak { $pdf->rollbackTransaction(true); - $pageposafter = $pageposbefore; - //print $pageposafter.'-'.$pageposbefore;exit; - $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. - pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc); + + $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); $posyafter = $pdf->GetY(); @@ -482,7 +497,11 @@ class pdf_espadon extends ModelePdfExpedition else { // We found a page break - $showpricebeforepagebreak = 0; + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak @@ -516,12 +535,12 @@ class pdf_espadon extends ModelePdfExpedition $weighttxt = ''; if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->weight) { - $weighttxt = round($object->lines[$i]->weight * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "weight", $object->lines[$i]->weight_units); + $weighttxt = round($object->lines[$i]->weight * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "weight", $object->lines[$i]->weight_units, 1); } $voltxt = ''; if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->volume) { - $voltxt = round($object->lines[$i]->volume * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "volume", $object->lines[$i]->volume_units ? $object->lines[$i]->volume_units : 0); + $voltxt = round($object->lines[$i]->volume * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "volume", $object->lines[$i]->volume_units ? $object->lines[$i]->volume_units : 0, 1); } @@ -549,10 +568,17 @@ class pdf_espadon extends ModelePdfExpedition $nexY = max($pdf->GetY(), $nexY); } - - - $nexY += 3; - if ($weighttxt && $voltxt) $nexY += 2; + // Extrafields + if(!empty($object->lines[$i]->array_options)){ + foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue){ + if ($this->getColumnStatus($extrafieldColKey)) + { + $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey); + $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); + $nexY = max($pdf->GetY(), $nexY); + } + } + } // Add line if (!empty($conf->global->MAIN_PDF_DASH_BETWEEN_LINES) && $i < ($nblines - 1)) @@ -560,7 +586,7 @@ class pdf_espadon extends ModelePdfExpedition $pdf->setPage($pageposafter); $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80))); //$pdf->SetDrawColor(190,190,200); - $pdf->line($this->marge_gauche, $nexY - 1, $this->page_largeur - $this->marge_droite, $nexY - 1); + $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY); $pdf->SetLineStyle(array('dash'=>0)); } @@ -1090,7 +1116,7 @@ class pdf_espadon extends ModelePdfExpedition // Default field style for content $this->defaultContentsFieldsStyle = array( 'align' => 'R', // R,C,L - 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left ); // Default field style for content @@ -1127,10 +1153,10 @@ class pdf_espadon extends ModelePdfExpedition 'align' => 'L', // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label // 'label' => ' ', // the final label - 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + 'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left ), 'content' => array( - 'align' => 'L', + 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left ), ); @@ -1216,6 +1242,11 @@ class pdf_espadon extends ModelePdfExpedition ), ); + // Add extrafields cols + if(!empty($object->lines)) { + $line = reset($object->lines); + $this->defineColumnExtrafield($line, $outputlangs, $hidedetails); + } $parameters = array( 'object' => $object, diff --git a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php index 0e9db902662..ad0272f46a1 100644 --- a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php @@ -452,7 +452,12 @@ class pdf_rouget extends ModelePdfExpedition $pdf->setPage($pageposbefore + 1); $curY = $tab_top_newpage; - $showpricebeforepagebreak = 0; + + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } if (isset($imglinesize['width']) && isset($imglinesize['height'])) @@ -494,7 +499,12 @@ class pdf_rouget extends ModelePdfExpedition else { // We found a page break - $showpricebeforepagebreak = 0; + + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak @@ -526,12 +536,12 @@ class pdf_rouget extends ModelePdfExpedition $weighttxt = ''; if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->weight) { - $weighttxt = round($object->lines[$i]->weight * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "weight", $object->lines[$i]->weight_units); + $weighttxt = round($object->lines[$i]->weight * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "weight", $object->lines[$i]->weight_units, 1); } $voltxt = ''; if ($object->lines[$i]->fk_product_type == 0 && $object->lines[$i]->volume) { - $voltxt = round($object->lines[$i]->volume * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "volume", $object->lines[$i]->volume_units ? $object->lines[$i]->volume_units : 0); + $voltxt = round($object->lines[$i]->volume * $object->lines[$i]->qty_shipped, 5).' '.measuringUnitString(0, "volume", $object->lines[$i]->volume_units ? $object->lines[$i]->volume_units : 0, 1); } if (empty($conf->global->SHIPPING_PDF_HIDE_WEIGHT_AND_VOLUME)) diff --git a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php index 71295335460..0adf7cd2a6a 100644 --- a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php @@ -383,7 +383,11 @@ class pdf_standard extends ModeleExpenseReport else { // We found a page break - $showpricebeforepagebreak = 0; + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak @@ -572,8 +576,10 @@ class pdf_standard extends ModeleExpenseReport } $expensereporttypecode = $object->lines[$linenumber]->type_fees_code; - $expensereporttypecodetoshow = $outputlangs->trans($expensereporttypecode); - if ($expensereporttypecodetoshow == $expensereporttypecode) { + $expensereporttypecodetoshow = ($outputlangs->trans(($expensereporttypecode)) == $expensereporttypecode ? $object->lines[$linenumber]->type_fees_libelle : $outputlangs->trans($expensereporttypecode)); + + + if ($expensereporttypecodetoshow == $expensereporttypecode) { $expensereporttypecodetoshow = preg_replace('/^(EX_|TF_)/', '', $expensereporttypecodetoshow); } //$expensereporttypecodetoshow = dol_trunc($expensereporttypecodetoshow, 9); diff --git a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php index ef05b9b2df9..acbebd54da8 100644 --- a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php +++ b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php @@ -41,7 +41,7 @@ class doc_generic_invoice_odt extends ModelePDFFactures { /** * Issuer - * @var Company object that emits + * @var Societe Object that emits */ public $emetteur; @@ -435,9 +435,11 @@ class doc_generic_invoice_odt extends ModelePDFFactures } if ($foundtagforlines) { + $linenumber = 0; foreach ($object->lines as $line) { - $tmparray = $this->get_substitutionarray_lines($line, $outputlangs); + $linenumber++; + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); // Call the ODTSubstitutionLine hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index c3fc7677f80..112a3fec279 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -492,7 +492,12 @@ class pdf_crabe extends ModelePDFFactures $pdf->setPage($pageposbefore + 1); $curY = $tab_top_newpage; - $showpricebeforepagebreak = 0; + + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } if (isset($imglinesize['width']) && isset($imglinesize['height'])) @@ -532,7 +537,12 @@ class pdf_crabe extends ModelePDFFactures else { // We found a page break - $showpricebeforepagebreak = 0; + + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak @@ -1041,15 +1051,15 @@ class pdf_crabe extends ModelePDFFactures $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L'); // Show online payment link - $useonlinepayment = ((! empty($conf->paypal->enabled) || ! empty($conf->stripe->enabled) || ! empty($conf->paybox->enabled)) && !empty($conf->global->PDF_SHOW_LINK_TO_ONLINE_PAYMENT)); + $useonlinepayment = ((!empty($conf->paypal->enabled) || !empty($conf->stripe->enabled) || !empty($conf->paybox->enabled)) && !empty($conf->global->PDF_SHOW_LINK_TO_ONLINE_PAYMENT)); if (($object->mode_reglement_code == 'CB' || $object->mode_reglement_code == 'VAD') && $object->statut != Facture::STATUS_DRAFT && $useonlinepayment) { require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; global $langs; $langs->loadLangs(array('payment', 'paybox')); - $servicename=$langs->transnoentities('Online'); + $servicename = $langs->transnoentities('Online'); $paiement_url = getOnlinePaymentUrl('', 'invoice', $object->ref, '', '', ''); - $linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' '.$outputlangs->transnoentities("ClickHere").''; + $linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' '.$outputlangs->transnoentities("ClickHere").''; $pdf->writeHTMLCell(80, 10, '', '', dol_htmlentitiesbr($linktopay), 0, 1); } @@ -1105,10 +1115,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_account) || !empty($object->fk_bank) || !empty($conf->global->FACTURE_RIB_NUMBER)) - { - $bankid = (empty($object->fk_account) ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account); - if (!empty($object->fk_bank)) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank + if ($object->fk_account > 0 || $object->fk_bank > 0 || !empty($conf->global->FACTURE_RIB_NUMBER)) { + $bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account); + if ($object->fk_bank > 0) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank $account = new Account($this->db); $account->fetch($bankid); @@ -1697,6 +1706,30 @@ class pdf_crabe extends ModelePDFFactures $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R'); } + if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) + { + $object->fetch_projet(); + if (!empty($object->project->ref)) + { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R'); + } + } + + if (!empty($conf->global->PDF_SHOW_PROJECT)) + { + $object->fetch_projet(); + if (!empty($object->project->ref)) + { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->projet->ref), '', 'R'); + } + } + $objectidnext = $object->getIdReplacingInvoice('validated'); if ($object->type == 0 && $objectidnext) { diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index b5e94e62aff..220c83d5d63 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -126,10 +126,11 @@ class pdf_sponge extends ModelePDFFactures */ public $situationinvoice; + /** - * @var float X position for the situation progress column + * @var array of document table collumns */ - public $posxprogress; + public $cols; /** @@ -396,7 +397,7 @@ class pdf_sponge extends ModelePDFFactures if (!empty($tplidx)) $pdf->useTemplate($tplidx); $pagenb++; - $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs); + $top_shift = $this->_pagehead($pdf, $object, 1, $outputlangs, $outputlangsbis); $pdf->SetFont('', '', $default_font_size - 1); $pdf->MultiCell(0, 3, ''); // Set interline to 3 $pdf->SetTextColor(0, 0, 0); @@ -407,6 +408,8 @@ class pdf_sponge extends ModelePDFFactures $tab_height_newpage = 150; if (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)) $tab_height_newpage -= $top_shift; + $nexY = $tab_top - 1; + // Incoterm $height_incoterms = 0; if ($conf->incoterm->enabled) @@ -444,6 +447,13 @@ class pdf_sponge extends ModelePDFFactures } } + // Extrafields in note + $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); + if (!empty($extranote)) + { + $notetoshow = dol_concatdesc($notetoshow, $extranote); + } + $pagenb = $pdf->getPage(); if ($notetoshow) { @@ -572,9 +582,7 @@ class pdf_sponge extends ModelePDFFactures $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop); $pdf->rollbackTransaction(true); - $iniY = $tab_top + $this->tabTitleHeight + 2; - $curY = $tab_top + $this->tabTitleHeight + 2; - $nexY = $tab_top + $this->tabTitleHeight + 2; + $nexY = $tab_top + $this->tabTitleHeight; // Loop on each lines $pageposbeforeprintlines = $pdf->getPage(); @@ -595,7 +603,6 @@ class pdf_sponge extends ModelePDFFactures $showpricebeforepagebreak = 1; $posYAfterImage = 0; - $posYAfterDescription = 0; if ($this->getColumnStatus('photo')) { @@ -607,7 +614,12 @@ class pdf_sponge extends ModelePDFFactures $pdf->setPage($pageposbefore + 1); $curY = $tab_top_newpage; - $showpricebeforepagebreak = 0; + + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } if (!empty($this->cols['photo']) && isset($imglinesize['width']) && isset($imglinesize['height'])) @@ -622,15 +634,17 @@ class pdf_sponge extends ModelePDFFactures if ($this->getColumnStatus('desc')) { $pdf->startTransaction(); - pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc); + + $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); + if ($pageposafter > $pageposbefore) // There is a pagebreak { $pdf->rollbackTransaction(true); - $pageposafter = $pageposbefore; - //print $pageposafter.'-'.$pageposbefore;exit; $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. - pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc); + + $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); + $pageposafter = $pdf->getPage(); $posyafter = $pdf->GetY(); //var_dump($posyafter); var_dump(($this->page_hauteur - ($heightforfooter+$heightforfreetext+$heightforinfotot))); exit; @@ -646,17 +660,20 @@ class pdf_sponge extends ModelePDFFactures else { // We found a page break - $showpricebeforepagebreak = 0; + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak { $pdf->commitTransaction(); } - $posYAfterDescription = $pdf->GetY(); } - $nexY = $pdf->GetY(); + $nexY = $pdf->GetY(); $pageposafter = $pdf->getPage(); $pdf->setPage($pageposbefore); $pdf->setTopMargin($this->marge_haute); @@ -726,6 +743,18 @@ class pdf_sponge extends ModelePDFFactures $nexY = max($pdf->GetY(), $nexY); } + // Extrafields + if(!empty($object->lines[$i]->array_options)){ + foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue){ + if ($this->getColumnStatus($extrafieldColKey)) + { + $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey); + $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); + $nexY = max($pdf->GetY(), $nexY); + } + } + } + $parameters = array( 'object' => $object, @@ -794,21 +823,19 @@ class pdf_sponge extends ModelePDFFactures $pdf->setPage($pageposafter); $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80))); //$pdf->SetDrawColor(190,190,200); - $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1); + $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY); $pdf->SetLineStyle(array('dash'=>0)); } - $nexY += 2; // Add space between lines - // Detect if some page were added automatically and output _tableau for past pages while ($pagenb < $pageposafter) { $pdf->setPage($pagenb); if ($pagenb == $pageposbeforeprintlines) { - $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code); + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis); } else { - $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis); } $this->_pagefoot($pdf, $object, $outputlangs, 1); $pagenb++; @@ -819,11 +846,11 @@ class pdf_sponge extends ModelePDFFactures if (isset($object->lines[$i + 1]->pagebreak) && $object->lines[$i + 1]->pagebreak) { if ($pagenb == $pageposafter) { - $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code); + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforfooter, 0, $outputlangs, $hidetop, 1, $object->multicurrency_code, $outputlangsbis); } else { - $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code, $outputlangsbis); } $this->_pagefoot($pdf, $object, $outputlangs, 1); // New page @@ -837,12 +864,12 @@ class pdf_sponge extends ModelePDFFactures // Show square if ($pagenb == $pageposbeforeprintlines) { - $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code); + $this->_tableau($pdf, $tab_top, $this->page_hauteur - $tab_top - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, $hidetop, 0, $object->multicurrency_code, $outputlangsbis); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; } else { - $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code); + $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforinfotot - $heightforfreetext - $heightforfooter, 0, $outputlangs, 1, 0, $object->multicurrency_code, $outputlangsbis); $bottomlasttab = $this->page_hauteur - $heightforinfotot - $heightforfreetext - $heightforfooter + 1; } @@ -1043,7 +1070,7 @@ class pdf_sponge extends ModelePDFFactures /** * Show miscellaneous information (payment mode, payment term, ...) * - * @param PDF $pdf Object PDF + * @param tcpdf $pdf Object PDF * @param Object $object Object to show * @param int $posy Y * @param Translate $outputlangs Langs object @@ -1123,33 +1150,33 @@ class pdf_sponge extends ModelePDFFactures $pdf->SetFont('', '', $default_font_size - 2); $pdf->SetXY($posxval, $posy); - $lib_mode_reg=$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code)!=('PaymentType'.$object->mode_reglement_code)?$outputlangs->transnoentities("PaymentType".$object->mode_reglement_code):$outputlangs->convToOutputCharset($object->mode_reglement); + $lib_mode_reg = $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) != ('PaymentType'.$object->mode_reglement_code) ? $outputlangs->transnoentities("PaymentType".$object->mode_reglement_code) : $outputlangs->convToOutputCharset($object->mode_reglement); $pdf->MultiCell(80, 5, $lib_mode_reg, 0, 'L'); // Show online payment link - $useonlinepayment = ((! empty($conf->paypal->enabled) || ! empty($conf->stripe->enabled) || ! empty($conf->paybox->enabled)) && !empty($conf->global->PDF_SHOW_LINK_TO_ONLINE_PAYMENT)); + $useonlinepayment = ((!empty($conf->paypal->enabled) || !empty($conf->stripe->enabled) || !empty($conf->paybox->enabled)) && !empty($conf->global->PDF_SHOW_LINK_TO_ONLINE_PAYMENT)); if (($object->mode_reglement_code == 'CB' || $object->mode_reglement_code == 'VAD') && $object->statut != Facture::STATUS_DRAFT && $useonlinepayment) { require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; global $langs; $langs->loadLangs(array('payment', 'paybox')); - $servicename=$langs->transnoentities('Online'); + $servicename = $langs->transnoentities('Online'); $paiement_url = getOnlinePaymentUrl('', 'invoice', $object->ref, '', '', ''); - $linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' '.$outputlangs->transnoentities("ClickHere").''; + $linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' '.$outputlangs->transnoentities("ClickHere").''; $pdf->writeHTMLCell(80, 10, '', '', dol_htmlentitiesbr($linktopay), 0, 1); } - $posy=$pdf->GetY()+2; + $posy = $pdf->GetY() + 2; } // Show payment mode CHQ if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'CHQ') { // If payment mode unregulated or payment mode forced to CHQ - if (! empty($conf->global->FACTURE_CHQ_NUMBER)) + if (!empty($conf->global->FACTURE_CHQ_NUMBER)) { - $diffsizetitle=(empty($conf->global->PDF_DIFFSIZE_TITLE)?3:$conf->global->PDF_DIFFSIZE_TITLE); + $diffsizetitle = (empty($conf->global->PDF_DIFFSIZE_TITLE) ? 3 : $conf->global->PDF_DIFFSIZE_TITLE); if ($conf->global->FACTURE_CHQ_NUMBER > 0) { @@ -1190,10 +1217,9 @@ class pdf_sponge 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_account) || !empty($object->fk_bank) || !empty($conf->global->FACTURE_RIB_NUMBER)) - { - $bankid = (empty($object->fk_account) ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account); - if (!empty($object->fk_bank)) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank + if ($object->fk_account > 0 || $object->fk_bank > 0 || !empty($conf->global->FACTURE_RIB_NUMBER)) { + $bankid = ($object->fk_account <= 0 ? $conf->global->FACTURE_RIB_NUMBER : $object->fk_account); + if ($object->fk_bank > 0) $bankid = $object->fk_bank; // For backward compatibility when object->fk_account is forced with object->fk_bank $account = new Account($this->db); $account->fetch($bankid); @@ -1214,7 +1240,7 @@ class pdf_sponge extends ModelePDFFactures /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDI $pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Amount already paid (in the currency of invoice) * @param int $posy Position depart @@ -1780,7 +1806,7 @@ class pdf_sponge extends ModelePDFFactures /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param tcpdf $pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -1788,9 +1814,10 @@ class pdf_sponge extends ModelePDFFactures * @param int $hidetop 1=Hide top bar of array and title, 0=Hide nothing, -1=Hide only title * @param int $hidebottom Hide bottom bar of array * @param string $currency Currency code + * @param Translate $outputlangsbis Langs object bis * @return void */ - protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '') + protected function _tableau(&$pdf, $tab_top, $tab_height, $nexY, $outputlangs, $hidetop = 0, $hidebottom = 0, $currency = '', $outputlangsbis = null) { global $conf; @@ -1808,6 +1835,10 @@ class pdf_sponge extends ModelePDFFactures if (empty($hidetop)) { $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency)); + if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { + $titre .= ' - '.$outputlangsbis->transnoentities("AmountInCurrency", $outputlangsbis->transnoentitiesnoconv("Currency".$currency)); + } + $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top - 4); $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); @@ -1835,13 +1866,14 @@ class pdf_sponge extends ModelePDFFactures /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param Tcpdf $pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output + * @param Translate $outputlangsbis Object lang for output bis * @return void */ - protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs) + protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null) { global $conf, $langs; @@ -1911,6 +1943,17 @@ class pdf_sponge extends ModelePDFFactures if ($object->type == 3) $title = $outputlangs->transnoentities("InvoiceDeposit"); if ($object->type == 4) $title = $outputlangs->transnoentities("InvoiceProForma"); if ($this->situationinvoice) $title = $outputlangs->transnoentities("InvoiceSituation"); + if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { + $title .= ' - '; + if ($object->type == 0) { + if ($this->situationinvoice) $title .= $outputlangsbis->transnoentities("InvoiceSituation"); + $title .= $outputlangsbis->transnoentities("PdfInvoiceTitle"); + } + elseif ($object->type == 1) $title .= $outputlangsbis->transnoentities("InvoiceReplacement"); + elseif ($object->type == 2) $title .= $outputlangsbis->transnoentities("InvoiceAvoir"); + elseif ($object->type == 3) $title .= $outputlangsbis->transnoentities("InvoiceDeposit"); + elseif ($object->type == 4) $title .= $outputlangsbis->transnoentities("InvoiceProForma"); + } $pdf->MultiCell($w, 3, $title, '', 'R'); $pdf->SetFont('', 'B', $default_font_size); @@ -1937,6 +1980,30 @@ class pdf_sponge extends ModelePDFFactures $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R'); } + if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) + { + $object->fetch_projet(); + if (!empty($object->project->ref)) + { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R'); + } + } + + if (!empty($conf->global->PDF_SHOW_PROJECT)) + { + $object->fetch_projet(); + if (!empty($object->project->ref)) + { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->projet->ref), '', 'R'); + } + } + $objectidnext = $object->getIdReplacingInvoice('validated'); if ($object->type == 0 && $objectidnext) { @@ -2147,7 +2214,7 @@ class pdf_sponge extends ModelePDFFactures // Default field style for content $this->defaultContentsFieldsStyle = array( 'align' => 'R', // R,C,L - 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left ); // Default field style for content @@ -2188,6 +2255,7 @@ class pdf_sponge extends ModelePDFFactures ), 'content' => array( 'align' => 'L', + 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left ), ); @@ -2295,7 +2363,7 @@ class pdf_sponge extends ModelePDFFactures $this->cols['discount']['status'] = true; } - $rank = $rank + 10; + $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100 $this->cols['totalexcltax'] = array( 'rank' => $rank, 'width' => 26, // in mm @@ -2306,6 +2374,11 @@ class pdf_sponge extends ModelePDFFactures 'border-left' => true, // add left line separator ); + // Add extrafields cols + if(!empty($object->lines)) { + $line = reset($object->lines); + $this->defineColumnExtrafield($line, $outputlangs, $hidedetails); + } $parameters = array( 'object' => $object, diff --git a/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php b/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php index ff7bff51230..ff913d724f8 100644 --- a/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php +++ b/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php @@ -108,7 +108,7 @@ class pdf_soleil extends ModelePDFFicheinter /** * Issuer - * @var Company object that emits + * @var Societe Object that emits */ public $emetteur; diff --git a/htdocs/core/modules/fichinter/mod_arctic.php b/htdocs/core/modules/fichinter/mod_arctic.php index e8d2aeff63e..f2f3a135785 100644 --- a/htdocs/core/modules/fichinter/mod_arctic.php +++ b/htdocs/core/modules/fichinter/mod_arctic.php @@ -46,7 +46,7 @@ class mod_arctic extends ModeleNumRefFicheinter /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom = 'arctic'; diff --git a/htdocs/core/modules/fichinter/mod_pacific.php b/htdocs/core/modules/fichinter/mod_pacific.php index 97784ce0639..3ecd3d6833d 100644 --- a/htdocs/core/modules/fichinter/mod_pacific.php +++ b/htdocs/core/modules/fichinter/mod_pacific.php @@ -46,7 +46,7 @@ class mod_pacific extends ModeleNumRefFicheinter /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom='pacific'; diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php index d6c43edd5c3..6c9dd9062a8 100644 --- a/htdocs/core/modules/import/import_csv.modules.php +++ b/htdocs/core/modules/import/import_csv.modules.php @@ -123,7 +123,7 @@ class ImportCsv extends ModeleImports * Output header of an example file for this format * * @param Translate $outputlangs Output language - * @return string + * @return string Empty string */ public function write_header_example($outputlangs) { @@ -137,7 +137,7 @@ class ImportCsv extends ModeleImports * * @param Translate $outputlangs Output language * @param array $headerlinefields Array of fields name - * @return string$limittoachartaccount + * @return string String output */ public function write_title_example($outputlangs, $headerlinefields) { @@ -152,7 +152,7 @@ class ImportCsv extends ModeleImports * * @param Translate $outputlangs Output language * @param array $contentlinevalues Array of lines - * @return string + * @return string String output */ public function write_record_example($outputlangs, $contentlinevalues) { @@ -166,7 +166,7 @@ class ImportCsv extends ModeleImports * Output footer of an example file for this format * * @param Translate $outputlangs Output language - * @return string + * @return string Empty string */ public function write_footer_example($outputlangs) { @@ -175,7 +175,6 @@ class ImportCsv extends ModeleImports } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Open input file @@ -426,6 +425,7 @@ class ImportCsv extends ModeleImports // New val can be an id or ref. If it start with id: it is forced to id, if it start with ref: it is forced to ref. It not, we try to guess. $isidorref = 'id'; if (!is_numeric($newval) && $newval != '' && !preg_match('/^id:/i', $newval)) $isidorref = 'ref'; + $newval = preg_replace('/^(id|ref):/i', '', $newval); // Remove id: or ref: that was used to force if field is id or ref //print 'Val is now '.$newval.' and is type '.$isidorref."
\n"; @@ -449,8 +449,7 @@ class ImportCsv extends ModeleImports $classinstance = new $class($this->db); // Try the fetch from code or ref $param_array = array('', $newval); - if ($class == 'AccountingAccount') - { + if ($class == 'AccountingAccount') { //var_dump($arrayrecord[0]['val']); /*include_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancysystem.class.php'; $tmpchartofaccount = new AccountancySystem($this->db); @@ -465,6 +464,7 @@ class ImportCsv extends ModeleImports }*/ $param_array = array('', $newval, 0, $arrayrecord[0]['val']); // Param to fetch parent from account, in chart. } + call_user_func_array(array($classinstance, $method), $param_array); // If not found, try the fetch from label if (! ($classinstance->id != '') && $objimport->array_import_convertvalue[0][$val]['rule']=='fetchidfromcodeorlabel') diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index 03b3f941a1d..09628739494 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -130,7 +130,7 @@ class ImportXlsx extends ModeleImports * Output header of an example file for this format * * @param Translate $outputlangs Output language - * @return string + * @return string Empty string */ public function write_header_example($outputlangs) { @@ -164,7 +164,7 @@ class ImportXlsx extends ModeleImports * * @param Translate $outputlangs Output language * @param array $headerlinefields Array of fields name - * @return string + * @return string String output */ public function write_title_example($outputlangs, $headerlinefields) { @@ -190,7 +190,7 @@ class ImportXlsx extends ModeleImports * * @param Translate $outputlangs Output language * @param array $contentlinevalues Array of lines - * @return string + * @return string Empty string */ public function write_record_example($outputlangs, $contentlinevalues) { @@ -210,7 +210,7 @@ class ImportXlsx extends ModeleImports * Output footer of an example file for this format * * @param Translate $outputlangs Output language - * @return string + * @return string String output */ public function write_footer_example($outputlangs) { @@ -258,7 +258,7 @@ class ImportXlsx extends ModeleImports * Return nb of records. File must be closed. * * @param string $file Path of filename - * @return int <0 if KO, >=0 if OK + * @return int <0 if KO, >=0 if OK */ public function import_get_nb_of_lines($file) { diff --git a/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php b/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php index 1b6ddf143e0..cdbb2cd0bb7 100644 --- a/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php +++ b/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php @@ -107,7 +107,7 @@ class pdf_typhon extends ModelePDFDeliveryOrder /** * Issuer - * @var Company object that emits + * @var Societe Object that emits */ public $emetteur; @@ -407,7 +407,11 @@ class pdf_typhon extends ModelePDFDeliveryOrder else { // We found a page break - $showpricebeforepagebreak = 0; + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak diff --git a/htdocs/core/modules/mailings/modules_mailings.php b/htdocs/core/modules/mailings/modules_mailings.php index d6cae560298..ffba2571d23 100644 --- a/htdocs/core/modules/mailings/modules_mailings.php +++ b/htdocs/core/modules/mailings/modules_mailings.php @@ -39,9 +39,9 @@ class MailingTargets // This can't be abstract as it is used for some method /** * @var string Error code (or message) */ - public $error=''; + public $error = ''; - public $tooltip=''; + public $tooltip = ''; /** @@ -64,12 +64,12 @@ class MailingTargets // This can't be abstract as it is used for some method global $langs, $form; $langs->load("mails"); - $transstring="MailingModuleDesc".$this->name; - $s=''; + $transstring = "MailingModuleDesc".$this->name; + $s = ''; - if ($langs->trans($this->name) != $this->name) $s=$langs->trans($this->name); - elseif ($langs->trans($transstring) != $transstring) $s=$langs->trans($transstring); - else $s=$this->desc; + if ($langs->trans($this->name) != $this->name) $s = $langs->trans($this->name); + elseif ($langs->trans($transstring) != $transstring) $s = $langs->trans($transstring); + else $s = $this->desc; if ($this->tooltip && is_object($form)) $s .= ' '.$form->textwithpicto('', $langs->trans($this->tooltip), 1, 1); return $s; @@ -93,7 +93,7 @@ class MailingTargets // This can't be abstract as it is used for some method */ public function getNbOfRecipients($sql) { - $result=$this->db->query($sql); + $result = $this->db->query($sql); if ($result) { $obj = $this->db->fetch_object($result); @@ -101,7 +101,7 @@ class MailingTargets // This can't be abstract as it is used for some method } else { - $this->error=$this->db->lasterror(); + $this->error = $this->db->lasterror(); return -1; } } @@ -130,18 +130,18 @@ class MailingTargets // This can't be abstract as it is used for some method // Mise a jour nombre de destinataire dans table des mailings $sql = "SELECT COUNT(*) nb FROM ".MAIN_DB_PREFIX."mailing_cibles"; $sql .= " WHERE fk_mailing = ".$mailing_id; - $result=$this->db->query($sql); + $result = $this->db->query($sql); if ($result) { - $obj=$this->db->fetch_object($result); - $nb=$obj->nb; + $obj = $this->db->fetch_object($result); + $nb = $obj->nb; $sql = "UPDATE ".MAIN_DB_PREFIX."mailing"; $sql .= " SET nbemail = ".$nb." WHERE rowid = ".$mailing_id; if (!$this->db->query($sql)) { dol_syslog($this->db->error()); - $this->error=$this->db->error(); + $this->error = $this->db->error(); return -1; } } @@ -169,26 +169,26 @@ class MailingTargets // This can't be abstract as it is used for some method $num = count($cibles); foreach ($cibles as $targetarray) { - if (! empty($targetarray['email'])) // avoid empty email address + if (!empty($targetarray['email'])) // avoid empty email address { $sql = "INSERT INTO ".MAIN_DB_PREFIX."mailing_cibles"; - $sql.= " (fk_mailing,"; - $sql.= " fk_contact,"; - $sql.= " lastname, firstname, email, other, source_url, source_id,"; - $sql.= " tag,"; - $sql.= " source_type)"; - $sql.= " VALUES (".$mailing_id.","; - $sql.= (empty($targetarray['fk_contact']) ? '0' : "'".$targetarray['fk_contact']."'") .","; - $sql.= "'".$this->db->escape($targetarray['lastname'])."',"; - $sql.= "'".$this->db->escape($targetarray['firstname'])."',"; - $sql.= "'".$this->db->escape($targetarray['email'])."',"; - $sql.= "'".$this->db->escape($targetarray['other'])."',"; - $sql.= "'".$this->db->escape($targetarray['source_url'])."',"; - $sql.= (empty($targetarray['source_id']) ? 'null' : "'".$this->db->escape($targetarray['source_id'])."'").","; + $sql .= " (fk_mailing,"; + $sql .= " fk_contact,"; + $sql .= " lastname, firstname, email, other, source_url, source_id,"; + $sql .= " tag,"; + $sql .= " source_type)"; + $sql .= " VALUES (".$mailing_id.","; + $sql .= (empty($targetarray['fk_contact']) ? '0' : "'".$targetarray['fk_contact']."'").","; + $sql .= "'".$this->db->escape($targetarray['lastname'])."',"; + $sql .= "'".$this->db->escape($targetarray['firstname'])."',"; + $sql .= "'".$this->db->escape($targetarray['email'])."',"; + $sql .= "'".$this->db->escape($targetarray['other'])."',"; + $sql .= "'".$this->db->escape($targetarray['source_url'])."',"; + $sql .= (empty($targetarray['source_id']) ? 'null' : "'".$this->db->escape($targetarray['source_id'])."'").","; $sql .= "'".$this->db->escape(dol_hash($targetarray['email'].';'.$targetarray['lastname'].';'.$mailing_id.';'.$conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY))."',"; $sql .= "'".$this->db->escape($targetarray['source_type'])."')"; - dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG); - $result=$this->db->query($sql); + dol_syslog(__METHOD__, LOG_DEBUG); + $result = $this->db->query($sql); if ($result) { $j++; @@ -199,7 +199,7 @@ class MailingTargets // This can't be abstract as it is used for some method { // Si erreur autre que doublon dol_syslog($this->db->error().' : '.$targetarray['email']); - $this->error=$this->db->error().' : '.$targetarray['email']; + $this->error = $this->db->error().' : '.$targetarray['email']; $this->db->rollback(); return -1; } @@ -207,7 +207,7 @@ class MailingTargets // This can't be abstract as it is used for some method } } - dol_syslog(get_class($this)."::".__METHOD__.": mailing ".$j." targets added"); + dol_syslog(__METHOD__.": mailing ".$j." targets added"); /* //Update the status to show thirdparty mail that don't want to be contacted anymore' @@ -215,7 +215,7 @@ class MailingTargets // This can't be abstract as it is used for some method $sql .= " SET statut=3"; $sql .= " WHERE fk_mailing=".$mailing_id." AND email in (SELECT email FROM ".MAIN_DB_PREFIX."societe where fk_stcomm=-1)"; $sql .= " AND source_type='thirdparty'"; - dol_syslog(get_class($this)."::".__METHOD__.": mailing update status to display thirdparty mail that do not want to be contacted"); + dol_syslog(__METHOD__.": mailing update status to display thirdparty mail that do not want to be contacted"); $result=$this->db->query($sql); //Update the status to show contact mail that don't want to be contacted anymore' @@ -223,7 +223,7 @@ class MailingTargets // This can't be abstract as it is used for some method $sql .= " SET statut=3"; $sql .= " WHERE fk_mailing=".$mailing_id." AND source_type='contact' AND (email in (SELECT sc.email FROM ".MAIN_DB_PREFIX."socpeople AS sc "; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe s ON s.rowid=sc.fk_soc WHERE s.fk_stcomm=-1 OR no_email=1))"; - dol_syslog(get_class($this)."::".__METHOD__.": mailing update status to display contact mail that do not want to be contacted",LOG_DEBUG); + dol_syslog(__METHOD__.": mailing update status to display contact mail that do not want to be contacted",LOG_DEBUG); $result=$this->db->query($sql); */ @@ -231,9 +231,9 @@ class MailingTargets // This can't be abstract as it is used for some method $sql .= " SET statut=3"; $sql .= " WHERE fk_mailing=".$mailing_id." AND email IN (SELECT mu.email FROM ".MAIN_DB_PREFIX."mailing_unsubscribe AS mu WHERE mu.entity IN ('".getEntity('mailing')."'))"; - dol_syslog(get_class($this)."::".__METHOD__.":mailing update status to display emails that do not want to be contacted anymore", LOG_DEBUG); - $result=$this->db->query($sql); - if (! $result) + dol_syslog(__METHOD__.":mailing update status to display emails that do not want to be contacted anymore", LOG_DEBUG); + $result = $this->db->query($sql); + if (!$result) { dol_print_error($this->db); } @@ -258,7 +258,7 @@ class MailingTargets // This can't be abstract as it is used for some method $sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_cibles"; $sql .= " WHERE fk_mailing = ".$mailing_id; - if (! $this->db->query($sql)) + if (!$this->db->query($sql)) { dol_syslog($this->db->error()); } diff --git a/htdocs/core/modules/modAccounting.class.php b/htdocs/core/modules/modAccounting.class.php index 70b461d6048..2ab0429fe5f 100644 --- a/htdocs/core/modules/modAccounting.class.php +++ b/htdocs/core/modules/modAccounting.class.php @@ -258,9 +258,9 @@ class modAccounting extends DolibarrModules $this->export_label[$r]='Chartofaccounts'; $this->export_icon[$r]='accounting'; $this->export_permission[$r]=array(array("accounting","chartofaccount")); - $this->export_fields_array[$r]=array('ac.rowid'=>'ChartofaccountsId','ac.pcg_version'=>'Chartofaccounts','aa.rowid'=>'Id','aa.account_number'=>"AccountAccounting",'aa.label'=>"Label",'aa.account_parent'=>"Accountparent",'aa.pcg_type'=>"Pcgtype",'aa.pcg_subtype'=>'Pcgsubtype','aa.active'=>'Status'); - $this->export_TypeFields_array[$r]=array('ac.rowid'=>'List:accounting_system:pcg_version','aa.account_number'=>"Text",'aa.label'=>"Text",'aa.account_parent'=>"Text",'aa.pcg_type'=>'Text','aa.pcg_subtype'=>'Text','aa.active'=>'Status'); - $this->export_entities_array[$r]=array('ac.rowid'=>"Accounting",'ac.pcg_version'=>"Accounting",'aa.rowid'=>'Accounting','aa.account_number'=>"Accounting",'aa.label'=>"Accounting",'aa.accountparent'=>"Accounting",'aa.pcg_type'=>"Accounting",'aa.pcgsubtype'=>"Accounting",'aa_active'=>"Accounting"); + $this->export_fields_array[$r]=array('ac.rowid'=>'ChartofaccountsId','ac.pcg_version'=>'Chartofaccounts','aa.rowid'=>'Id','aa.account_number'=>"AccountAccounting",'aa.label'=>"Label",'aa.account_parent'=>"Accountparent",'aa.pcg_type'=>"Pcgtype",'aa.active'=>'Status'); + $this->export_TypeFields_array[$r]=array('ac.rowid'=>'List:accounting_system:pcg_version','aa.account_number'=>"Text",'aa.label'=>"Text",'aa.account_parent'=>"Text",'aa.pcg_type'=>'Text','aa.active'=>'Status'); + $this->export_entities_array[$r]=array('ac.rowid'=>"Accounting",'ac.pcg_version'=>"Accounting",'aa.rowid'=>'Accounting','aa.account_number'=>"Accounting",'aa.label'=>"Accounting",'aa.accountparent'=>"Accounting",'aa.pcg_type'=>"Accounting",'aa_active'=>"Accounting"); $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'accounting_account as aa'; @@ -320,13 +320,13 @@ class modAccounting extends DolibarrModules $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r]=array('aa'=>MAIN_DB_PREFIX.'accounting_account'); $this->import_tables_creator_array[$r]=array('aa'=>'fk_user_author'); // Fields to store import user id - $this->import_fields_array[$r]=array('aa.fk_pcg_version'=>"Chartofaccounts*",'aa.account_number'=>"AccountAccounting*",'aa.label'=>"Label*",'aa.account_parent'=>"Accountparent","aa.fk_accounting_category"=>"AccountingCategory","aa.pcg_type"=>"Pcgtype*",'aa.pcg_subtype'=>'Pcgsubtype*','aa.active'=>'Status*','aa.datec'=>"DateCreation"); - $this->import_regex_array[$r]=array('aa.fk_pcg_version'=>'pcg_version@'.MAIN_DB_PREFIX.'accounting_system','aa.account_number'=>'^.{1,32}$','aa.label'=>'^.{1,255}$','aa.account_parent'=>'^.{0,32}$','aa.fk_accounting_category'=>'rowid@'.MAIN_DB_PREFIX.'c_accounting_category','aa.pcg_type'=>'^.{1,20}$','aa.pcg_subtype'=>'^.{1,20}$','aa.active'=>'^0|1$','aa.datec'=>'^\d{4}-\d{2}-\d{2}$'); + $this->import_fields_array[$r]=array('aa.fk_pcg_version'=>"Chartofaccounts*",'aa.account_number'=>"AccountAccounting*",'aa.label'=>"Label*",'aa.account_parent'=>"Accountparent","aa.fk_accounting_category"=>"AccountingCategory","aa.pcg_type"=>"Pcgtype*",'aa.active'=>'Status*','aa.datec'=>"DateCreation"); + $this->import_regex_array[$r]=array('aa.fk_pcg_version'=>'pcg_version@'.MAIN_DB_PREFIX.'accounting_system','aa.account_number'=>'^.{1,32}$','aa.label'=>'^.{1,255}$','aa.account_parent'=>'^.{0,32}$','aa.fk_accounting_category'=>'rowid@'.MAIN_DB_PREFIX.'c_accounting_category','aa.pcg_type'=>'^.{1,20}$','aa.active'=>'^0|1$','aa.datec'=>'^\d{4}-\d{2}-\d{2}$'); $this->import_convertvalue_array[$r]=array( 'aa.account_parent'=>array('rule'=>'fetchidfromref','classfile'=>'/accountancy/class/accountingaccount.class.php','class'=>'AccountingAccount','method'=>'fetch','element'=>'AccountingAccount'), 'aa.fk_accounting_category'=>array('rule'=>'fetchidfromcodeorlabel','classfile'=>'/accountancy/class/accountancycategory.class.php','class'=>'AccountancyCategory','method'=>'fetch','dict'=>'DictionaryAccountancyCategory'), ); - $this->import_examplevalues_array[$r]=array('aa.fk_pcg_version'=>"PCG99-ABREGE",'aa.account_number'=>"707",'aa.label'=>"Product sales",'aa.account_parent'=>"ref:7 or id:1407","aa.fk_accounting_category"=>"","aa.pcg_type"=>"PROD",'aa.pcg_subtype'=>'PRODUCT','aa.active'=>'1','aa.datec'=>"2017-04-28"); + $this->import_examplevalues_array[$r]=array('aa.fk_pcg_version'=>"PCG99-ABREGE",'aa.account_number'=>"707",'aa.label'=>"Product sales",'aa.account_parent'=>"ref:7 or id:1407","aa.fk_accounting_category"=>"","aa.pcg_type"=>"PROD",'aa.active'=>'1','aa.datec'=>"2017-04-28"); $this->import_updatekeys_array[$r]=array('aa.fk_pcg_version'=>'Chartofaccounts','aa.account_number'=>'AccountAccounting'); } } diff --git a/htdocs/core/modules/modCategorie.class.php b/htdocs/core/modules/modCategorie.class.php index b53a9630598..61a4dd67d5c 100644 --- a/htdocs/core/modules/modCategorie.class.php +++ b/htdocs/core/modules/modCategorie.class.php @@ -24,7 +24,7 @@ * \ingroup category * \brief Fichier de description et activation du module Categorie */ -include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; +include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php'; /** @@ -64,11 +64,11 @@ class modCategorie extends DolibarrModules // Config pages $this->config_page_url = array('categorie.php@categories'); - $this->langfiles = array("products","companies","categories","members"); + $this->langfiles = array("products", "companies", "categories", "members"); // Constants $this->const = array(); - $r=0; + $r = 0; $this->const[$r][0] = "CATEGORIE_RECURSIV_ADD"; $this->const[$r][1] = "yesno"; $this->const[$r][2] = "0"; @@ -83,7 +83,7 @@ class modCategorie extends DolibarrModules $this->rights = array(); $this->rights_class = 'categorie'; - $r=0; + $r = 0; $this->rights[$r][0] = 241; // id de la permission $this->rights[$r][1] = 'Lire les categories'; // libelle de la permission @@ -109,115 +109,115 @@ class modCategorie extends DolibarrModules // Menus //------- - $this->menu = 1; // This module add menu entries. They are coded into menu manager. + $this->menu = 1; // This module add menu entries. They are coded into menu manager. // Exports //-------- - $r=0; + $r = 0; $r++; - $this->export_code[$r]='category_'.$r; - $this->export_label[$r]='CatSupList'; - $this->export_icon[$r]='category'; - $this->export_enabled[$r]='$conf->fournisseur->enabled'; - $this->export_permission[$r]=array(array("categorie","lire"),array("fournisseur","lire")); - $this->export_fields_array[$r]=array( - 'u.rowid'=>"CategId",'u.label'=>"Label",'u.description'=>"Description",'s.rowid'=>'IdThirdParty','s.nom'=>'Name','s.prefix_comm'=>"Prefix", - 's.client'=>"Customer",'s.datec'=>"DateCreation",'s.tms'=>"DateLastModification",'s.code_client'=>"CustomerCode",'s.address'=>"Address", - 's.zip'=>"Zip",'s.town'=>"Town",'c.label'=>"Country",'c.code'=>"CountryCode",'s.phone'=>"Phone",'s.fax'=>"Fax",'s.url'=>"Url",'s.email'=>"Email", - 's.siret'=>"ProfId1",'s.siren'=>"ProfId2",'s.ape'=>"ProfId3",'s.idprof4'=>"ProfId4",'s.tva_intra'=>"VATIntraShort",'s.capital'=>"Capital", + $this->export_code[$r] = 'category_'.$r; + $this->export_label[$r] = 'CatSupList'; + $this->export_icon[$r] = 'category'; + $this->export_enabled[$r] = '$conf->fournisseur->enabled'; + $this->export_permission[$r] = array(array("categorie", "lire"), array("fournisseur", "lire")); + $this->export_fields_array[$r] = array( + 'u.rowid'=>"CategId", 'u.label'=>"Label", 'u.description'=>"Description", 's.rowid'=>'IdThirdParty', 's.nom'=>'Name', 's.prefix_comm'=>"Prefix", + 's.client'=>"Customer", 's.datec'=>"DateCreation", 's.tms'=>"DateLastModification", 's.code_client'=>"CustomerCode", 's.address'=>"Address", + 's.zip'=>"Zip", 's.town'=>"Town", 'c.label'=>"Country", 'c.code'=>"CountryCode", 's.phone'=>"Phone", 's.fax'=>"Fax", 's.url'=>"Url", 's.email'=>"Email", + 's.siret'=>"ProfId1", 's.siren'=>"ProfId2", 's.ape'=>"ProfId3", 's.idprof4'=>"ProfId4", 's.tva_intra'=>"VATIntraShort", 's.capital'=>"Capital", 's.note_public'=>"NotePublic" ); - $this->export_TypeFields_array[$r]=array( - 'u.label'=>"Text",'u.description'=>"Text",'s.rowid'=>'List:societe:nom','s.nom'=>'Text','s.prefix_comm'=>"Text",'s.client'=>"Text",'s.datec'=>"Date", - 's.tms'=>"Date",'s.code_client'=>"Text",'s.address'=>"Text",'s.zip'=>"Text",'s.town'=>"Text",'c.label'=>"List:c_country:label:label",'c.code'=>"Text", - 's.phone'=>"Text",'s.fax'=>"Text",'s.url'=>"Text",'s.email'=>"Text",'s.siret'=>"Text",'s.siren'=>"Text",'s.ape'=>"Text",'s.idprof4'=>"Text", - 's.tva_intra'=>"Text",'s.capital'=>"Numeric",'s.note_public'=>"Text" + $this->export_TypeFields_array[$r] = array( + 'u.label'=>"Text", 'u.description'=>"Text", 's.rowid'=>'List:societe:nom', 's.nom'=>'Text', 's.prefix_comm'=>"Text", 's.client'=>"Text", 's.datec'=>"Date", + 's.tms'=>"Date", 's.code_client'=>"Text", 's.address'=>"Text", 's.zip'=>"Text", 's.town'=>"Text", 'c.label'=>"List:c_country:label:label", 'c.code'=>"Text", + 's.phone'=>"Text", 's.fax'=>"Text", 's.url'=>"Text", 's.email'=>"Text", 's.siret'=>"Text", 's.siren'=>"Text", 's.ape'=>"Text", 's.idprof4'=>"Text", + 's.tva_intra'=>"Text", 's.capital'=>"Numeric", 's.note_public'=>"Text" ); - $this->export_entities_array[$r]=array( - 's.rowid'=>'company','s.nom'=>'company','s.prefix_comm'=>"company",'s.client'=>"company",'s.datec'=>"company",'s.tms'=>"company", - 's.code_client'=>"company",'s.address'=>"company",'s.zip'=>"company",'s.town'=>"company",'c.label'=>"company",'c.code'=>"company", - 's.phone'=>"company",'s.fax'=>"company",'s.url'=>"company",'s.email'=>"company",'s.siret'=>"company",'s.siren'=>"company",'s.ape'=>"company", - 's.idprof4'=>"company",'s.tva_intra'=>"company",'s.capital'=>"company",'s.note_public'=>"company" - ); // We define here only fields that use another picto - $this->export_sql_start[$r]='SELECT DISTINCT '; - $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'categorie as u, '; + $this->export_entities_array[$r] = array( + 's.rowid'=>'company', 's.nom'=>'company', 's.prefix_comm'=>"company", 's.client'=>"company", 's.datec'=>"company", 's.tms'=>"company", + 's.code_client'=>"company", 's.address'=>"company", 's.zip'=>"company", 's.town'=>"company", 'c.label'=>"company", 'c.code'=>"company", + 's.phone'=>"company", 's.fax'=>"company", 's.url'=>"company", 's.email'=>"company", 's.siret'=>"company", 's.siren'=>"company", 's.ape'=>"company", + 's.idprof4'=>"company", 's.tva_intra'=>"company", 's.capital'=>"company", 's.note_public'=>"company" + ); // We define here only fields that use another picto + $this->export_sql_start[$r] = 'SELECT DISTINCT '; + $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'categorie as u, '; $this->export_sql_end[$r] .= MAIN_DB_PREFIX.'categorie_fournisseur as cf, '; $this->export_sql_end[$r] .= MAIN_DB_PREFIX.'societe as s LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as ce ON s.fk_effectif = ce.id LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON s.fk_forme_juridique = cfj.code'; - $this->export_sql_end[$r] .=' WHERE u.rowid = cf.fk_categorie AND cf.fk_soc = s.rowid'; - $this->export_sql_end[$r] .=' AND u.entity IN ('.getEntity('category').')'; - $this->export_sql_end[$r] .=' AND u.type = 1'; // Supplier categories + $this->export_sql_end[$r] .= ' WHERE u.rowid = cf.fk_categorie AND cf.fk_soc = s.rowid'; + $this->export_sql_end[$r] .= ' AND u.entity IN ('.getEntity('category').')'; + $this->export_sql_end[$r] .= ' AND u.type = 1'; // Supplier categories $r++; - $this->export_code[$r]='category_'.$r; - $this->export_label[$r]='CatCusList'; - $this->export_icon[$r]='category'; - $this->export_enabled[$r]='$conf->societe->enabled'; - $this->export_permission[$r]=array(array("categorie","lire"),array("societe","lire")); - $this->export_fields_array[$r]=array( - 'u.rowid'=>"CategId",'u.label'=>"Label",'u.description'=>"Description",'s.rowid'=>'IdThirdParty','s.nom'=>'Name','s.prefix_comm'=>"Prefix", - 's.client'=>"Customer",'s.datec'=>"DateCreation",'s.tms'=>"DateLastModification",'s.code_client'=>"CustomerCode",'s.address'=>"Address", - 's.zip'=>"Zip",'s.town'=>"Town",'c.label'=>"Country",'c.code'=>"CountryCode",'s.phone'=>"Phone",'s.fax'=>"Fax",'s.url'=>"Url",'s.email'=>"Email", - 's.siret'=>"ProfId1",'s.siren'=>"ProfId2",'s.ape'=>"ProfId3",'s.idprof4'=>"ProfId4",'s.tva_intra'=>"VATIntraShort",'s.capital'=>"Capital", - 's.note_public'=>"NotePublic",'s.fk_prospectlevel'=>'ProspectLevel','s.fk_stcomm'=>'ProspectStatus' + $this->export_code[$r] = 'category_'.$r; + $this->export_label[$r] = 'CatCusList'; + $this->export_icon[$r] = 'category'; + $this->export_enabled[$r] = '$conf->societe->enabled'; + $this->export_permission[$r] = array(array("categorie", "lire"), array("societe", "lire")); + $this->export_fields_array[$r] = array( + 'u.rowid'=>"CategId", 'u.label'=>"Label", 'u.description'=>"Description", 's.rowid'=>'IdThirdParty', 's.nom'=>'Name', 's.prefix_comm'=>"Prefix", + 's.client'=>"Customer", 's.datec'=>"DateCreation", 's.tms'=>"DateLastModification", 's.code_client'=>"CustomerCode", 's.address'=>"Address", + 's.zip'=>"Zip", 's.town'=>"Town", 'c.label'=>"Country", 'c.code'=>"CountryCode", 's.phone'=>"Phone", 's.fax'=>"Fax", 's.url'=>"Url", 's.email'=>"Email", + 's.siret'=>"ProfId1", 's.siren'=>"ProfId2", 's.ape'=>"ProfId3", 's.idprof4'=>"ProfId4", 's.tva_intra'=>"VATIntraShort", 's.capital'=>"Capital", + 's.note_public'=>"NotePublic", 's.fk_prospectlevel'=>'ProspectLevel', 's.fk_stcomm'=>'ProspectStatus' ); - $this->export_TypeFields_array[$r]=array( - 'u.label'=>"Text",'u.description'=>"Text",'s.rowid'=>'List:societe:nom','s.nom'=>'Text','s.prefix_comm'=>"Text",'s.client'=>"Text", - 's.datec'=>"Date",'s.tms'=>"Date",'s.code_client'=>"Text",'s.address'=>"Text",'s.zip'=>"Text",'s.town'=>"Text",'c.label'=>"List:c_country:label:label", - 'c.code'=>"Text",'s.phone'=>"Text",'s.fax'=>"Text",'s.url'=>"Text",'s.email'=>"Text",'s.siret'=>"Text",'s.siren'=>"Text",'s.ape'=>"Text", - 's.idprof4'=>"Text",'s.tva_intra'=>"Text",'s.capital'=>"Numeric",'s.note_public'=>"Text",'s.fk_prospectlevel'=>'List:c_prospectlevel:label:code', + $this->export_TypeFields_array[$r] = array( + 'u.label'=>"Text", 'u.description'=>"Text", 's.rowid'=>'List:societe:nom', 's.nom'=>'Text', 's.prefix_comm'=>"Text", 's.client'=>"Text", + 's.datec'=>"Date", 's.tms'=>"Date", 's.code_client'=>"Text", 's.address'=>"Text", 's.zip'=>"Text", 's.town'=>"Text", 'c.label'=>"List:c_country:label:label", + 'c.code'=>"Text", 's.phone'=>"Text", 's.fax'=>"Text", 's.url'=>"Text", 's.email'=>"Text", 's.siret'=>"Text", 's.siren'=>"Text", 's.ape'=>"Text", + 's.idprof4'=>"Text", 's.tva_intra'=>"Text", 's.capital'=>"Numeric", 's.note_public'=>"Text", 's.fk_prospectlevel'=>'List:c_prospectlevel:label:code', 's.fk_stcomm'=>'List:c_stcomm:libelle:code' ); - $this->export_entities_array[$r]=array( - 's.rowid'=>'company','s.nom'=>'company','s.prefix_comm'=>"company",'s.client'=>"company",'s.datec'=>"company",'s.tms'=>"company", - 's.code_client'=>"company",'s.address'=>"company",'s.zip'=>"company",'s.town'=>"company",'c.label'=>"company",'c.code'=>"company", - 's.phone'=>"company",'s.fax'=>"company",'s.url'=>"company",'s.email'=>"company",'s.siret'=>"company",'s.siren'=>"company",'s.ape'=>"company", - 's.idprof4'=>"company",'s.tva_intra'=>"company",'s.capital'=>"company",'s.note_public'=>"company",'s.fk_prospectlevel'=>'company', + $this->export_entities_array[$r] = array( + 's.rowid'=>'company', 's.nom'=>'company', 's.prefix_comm'=>"company", 's.client'=>"company", 's.datec'=>"company", 's.tms'=>"company", + 's.code_client'=>"company", 's.address'=>"company", 's.zip'=>"company", 's.town'=>"company", 'c.label'=>"company", 'c.code'=>"company", + 's.phone'=>"company", 's.fax'=>"company", 's.url'=>"company", 's.email'=>"company", 's.siret'=>"company", 's.siren'=>"company", 's.ape'=>"company", + 's.idprof4'=>"company", 's.tva_intra'=>"company", 's.capital'=>"company", 's.note_public'=>"company", 's.fk_prospectlevel'=>'company', 's.fk_stcomm'=>'company' - ); // We define here only fields that use another picto - $this->export_sql_start[$r]='SELECT DISTINCT '; - $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'categorie as u, '; + ); // We define here only fields that use another picto + $this->export_sql_start[$r] = 'SELECT DISTINCT '; + $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'categorie as u, '; $this->export_sql_end[$r] .= MAIN_DB_PREFIX.'categorie_societe as cf, '; $this->export_sql_end[$r] .= MAIN_DB_PREFIX.'societe as s LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as ce ON s.fk_effectif = ce.id LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON s.fk_forme_juridique = cfj.code LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extra ON s.rowid = extra.fk_object '; - $this->export_sql_end[$r] .=' WHERE u.rowid = cf.fk_categorie AND cf.fk_soc = s.rowid'; - $this->export_sql_end[$r] .=' AND u.entity IN ('.getEntity('category').')'; - $this->export_sql_end[$r] .=' AND u.type = 2'; // Customer/Prospect categories + $this->export_sql_end[$r] .= ' WHERE u.rowid = cf.fk_categorie AND cf.fk_soc = s.rowid'; + $this->export_sql_end[$r] .= ' AND u.entity IN ('.getEntity('category').')'; + $this->export_sql_end[$r] .= ' AND u.type = 2'; // Customer/Prospect categories // Add extra fields - $sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'societe' AND entity IN (0, ".$conf->entity.")"; - $resql=$this->db->query($sql); + $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'societe' AND entity IN (0, ".$conf->entity.")"; + $resql = $this->db->query($sql); if ($resql) // This can fail when class is used on old database (during migration for example) { - while ($obj=$this->db->fetch_object($resql)) + while ($obj = $this->db->fetch_object($resql)) { - $fieldname='extra.'.$obj->name; - $fieldlabel=ucfirst($obj->label); - $typeFilter="Text"; - switch($obj->type) + $fieldname = 'extra.'.$obj->name; + $fieldlabel = ucfirst($obj->label); + $typeFilter = "Text"; + switch ($obj->type) { case 'int': case 'double': case 'price': - $typeFilter="Numeric"; + $typeFilter = "Numeric"; break; case 'date': case 'datetime': - $typeFilter="Date"; + $typeFilter = "Date"; break; case 'boolean': - $typeFilter="Boolean"; + $typeFilter = "Boolean"; break; case 'sellist': - $typeFilter="List:".$obj->param; + $typeFilter = "List:".$obj->param; break; case 'select': - $typeFilter="Select:".$obj->param; + $typeFilter = "Select:".$obj->param; break; } - $this->export_fields_array[$r][$fieldname]=$fieldlabel; - $this->export_TypeFields_array[$r][$fieldname]=$typeFilter; - $this->export_entities_array[$r][$fieldname]='company'; + $this->export_fields_array[$r][$fieldname] = $fieldlabel; + $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; + $this->export_entities_array[$r][$fieldname] = 'company'; } } // End add axtra fields @@ -227,42 +227,42 @@ class modCategorie extends DolibarrModules $r++; - $this->export_code[$r]='category_'.$r; - $this->export_label[$r]='CatProdList'; - $this->export_icon[$r]='category'; - $this->export_enabled[$r]='$conf->product->enabled || $conf->service->enabled'; - $this->export_permission[$r]=array(array("categorie","lire"),array("produit","lire")); - $this->export_fields_array[$r]=array('u.rowid'=>"CategId",'u.label'=>"Label",'u.description'=>"Description",'p.rowid'=>'ProductId','p.ref'=>'Ref'); - $this->export_TypeFields_array[$r]=array('u.label'=>"Text",'u.description'=>"Text",'p.ref'=>'Text'); - $this->export_entities_array[$r]=array('p.rowid'=>'product','p.ref'=>'product'); // We define here only fields that use another picto - $this->export_sql_start[$r]='SELECT DISTINCT '; - $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'categorie as u, '.MAIN_DB_PREFIX.'categorie_product as cp, '.MAIN_DB_PREFIX.'product as p'; - $this->export_sql_end[$r] .=' WHERE u.rowid = cp.fk_categorie AND cp.fk_product = p.rowid'; - $this->export_sql_end[$r] .=' AND u.entity IN ('.getEntity('category').')'; - $this->export_sql_end[$r] .=' AND u.type = 0'; // Supplier categories + $this->export_code[$r] = 'category_'.$r; + $this->export_label[$r] = 'CatProdList'; + $this->export_icon[$r] = 'category'; + $this->export_enabled[$r] = '$conf->product->enabled || $conf->service->enabled'; + $this->export_permission[$r] = array(array("categorie", "lire"), array("produit", "lire")); + $this->export_fields_array[$r] = array('u.rowid'=>"CategId", 'u.label'=>"Label", 'u.description'=>"Description", 'p.rowid'=>'ProductId', 'p.ref'=>'Ref'); + $this->export_TypeFields_array[$r] = array('u.label'=>"Text", 'u.description'=>"Text", 'p.ref'=>'Text'); + $this->export_entities_array[$r] = array('p.rowid'=>'product', 'p.ref'=>'product'); // We define here only fields that use another picto + $this->export_sql_start[$r] = 'SELECT DISTINCT '; + $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'categorie as u, '.MAIN_DB_PREFIX.'categorie_product as cp, '.MAIN_DB_PREFIX.'product as p'; + $this->export_sql_end[$r] .= ' WHERE u.rowid = cp.fk_categorie AND cp.fk_product = p.rowid'; + $this->export_sql_end[$r] .= ' AND u.entity IN ('.getEntity('category').')'; + $this->export_sql_end[$r] .= ' AND u.type = 0'; // Supplier categories $r++; - $this->export_code[$r]='category_'.$r; - $this->export_label[$r]='CatMemberList'; - $this->export_icon[$r]='category'; - $this->export_enabled[$r]='$conf->adherent->enabled'; - $this->export_permission[$r]=array(array("categorie","lire"),array("adherent","lire")); - $this->export_fields_array[$r]=array('u.rowid'=>"CategId",'u.label'=>"Label",'u.description'=>"Description",'p.rowid'=>'MemberId','p.lastname'=>'LastName','p.firstname'=>'Firstname'); - $this->export_TypeFields_array[$r]=array('u.label'=>"Text",'u.description'=>"Text",'p.lastname'=>'Text','p.firstname'=>'Text'); - $this->export_entities_array[$r]=array('p.rowid'=>'member','p.lastname'=>'member','p.firstname'=>'member'); // We define here only fields that use another picto - $this->export_sql_start[$r]='SELECT DISTINCT '; - $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'categorie as u, '.MAIN_DB_PREFIX.'categorie_member as cp, '.MAIN_DB_PREFIX.'adherent as p'; - $this->export_sql_end[$r] .=' WHERE u.rowid = cp.fk_categorie AND cp.fk_member = p.rowid'; - $this->export_sql_end[$r] .=' AND u.entity IN ('.getEntity('category').')'; - $this->export_sql_end[$r] .=' AND u.type = 3'; // Member categories + $this->export_code[$r] = 'category_'.$r; + $this->export_label[$r] = 'CatMemberList'; + $this->export_icon[$r] = 'category'; + $this->export_enabled[$r] = '$conf->adherent->enabled'; + $this->export_permission[$r] = array(array("categorie", "lire"), array("adherent", "lire")); + $this->export_fields_array[$r] = array('u.rowid'=>"CategId", 'u.label'=>"Label", 'u.description'=>"Description", 'p.rowid'=>'MemberId', 'p.lastname'=>'LastName', 'p.firstname'=>'Firstname'); + $this->export_TypeFields_array[$r] = array('u.label'=>"Text", 'u.description'=>"Text", 'p.lastname'=>'Text', 'p.firstname'=>'Text'); + $this->export_entities_array[$r] = array('p.rowid'=>'member', 'p.lastname'=>'member', 'p.firstname'=>'member'); // We define here only fields that use another picto + $this->export_sql_start[$r] = 'SELECT DISTINCT '; + $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'categorie as u, '.MAIN_DB_PREFIX.'categorie_member as cp, '.MAIN_DB_PREFIX.'adherent as p'; + $this->export_sql_end[$r] .= ' WHERE u.rowid = cp.fk_categorie AND cp.fk_member = p.rowid'; + $this->export_sql_end[$r] .= ' AND u.entity IN ('.getEntity('category').')'; + $this->export_sql_end[$r] .= ' AND u.type = 3'; // Member categories $r++; - $this->export_code[$r]='category_'.$r; - $this->export_label[$r]='CatContactList'; - $this->export_icon[$r]='category'; - $this->export_enabled[$r]='$conf->societe->enabled'; - $this->export_permission[$r]=array(array("categorie", "lire"), array ("societe", "lire")); - $this->export_fields_array[$r]=array ( + $this->export_code[$r] = 'category_'.$r; + $this->export_label[$r] = 'CatContactList'; + $this->export_icon[$r] = 'category'; + $this->export_enabled[$r] = '$conf->societe->enabled'; + $this->export_permission[$r] = array(array("categorie", "lire"), array("societe", "lire")); + $this->export_fields_array[$r] = array( 'u.rowid' => "CategId", 'u.label' => "Label", 'u.description' => "Description", @@ -297,7 +297,7 @@ class modCategorie extends DolibarrModules 's.url'=>"Url", 's.email'=>"Email" ); - $this->export_TypeFields_array[$r] = array ( + $this->export_TypeFields_array[$r] = array( 'u.label' => "Text", 'u.description' => "Text", 'p.lastname' => 'Text', @@ -313,7 +313,7 @@ class modCategorie extends DolibarrModules 's.url'=>"Text", 's.email'=>"Text" ); - $this->export_entities_array[$r] = array ( + $this->export_entities_array[$r] = array( 'u.rowid' => "category", 'u.label' => "category", 'u.description' => "category", @@ -350,67 +350,67 @@ class modCategorie extends DolibarrModules ); // We define here only fields that use another picto // Add extra fields - $sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'socpeople' AND entity IN (0, ".$conf->entity.")"; - $resql=$this->db->query($sql); + $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'socpeople' AND entity IN (0, ".$conf->entity.")"; + $resql = $this->db->query($sql); if ($resql) // This can fail when class is used on old database (during migration for example) { - while ($obj=$this->db->fetch_object($resql)) + while ($obj = $this->db->fetch_object($resql)) { - $fieldname='extra.'.$obj->name; - $fieldlabel=ucfirst($obj->label); - $typeFilter="Text"; - switch($obj->type) + $fieldname = 'extra.'.$obj->name; + $fieldlabel = ucfirst($obj->label); + $typeFilter = "Text"; + switch ($obj->type) { case 'int': case 'double': case 'price': - $typeFilter="Numeric"; + $typeFilter = "Numeric"; break; case 'date': case 'datetime': - $typeFilter="Date"; + $typeFilter = "Date"; break; case 'boolean': - $typeFilter="Boolean"; + $typeFilter = "Boolean"; break; case 'sellist': - $typeFilter="List:".$obj->param; + $typeFilter = "List:".$obj->param; break; case 'select': - $typeFilter="Select:".$obj->param; + $typeFilter = "Select:".$obj->param; break; } - $this->export_fields_array[$r][$fieldname]=$fieldlabel; - $this->export_TypeFields_array[$r][$fieldname]=$typeFilter; - $this->export_entities_array[$r][$fieldname]='contact'; + $this->export_fields_array[$r][$fieldname] = $fieldlabel; + $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; + $this->export_entities_array[$r][$fieldname] = 'contact'; } } // End add axtra fields $this->export_sql_start[$r] = 'SELECT DISTINCT '; - $this->export_sql_end[$r] = ' FROM ' . MAIN_DB_PREFIX . 'categorie as u, '.MAIN_DB_PREFIX . 'categorie_contact as cp, '.MAIN_DB_PREFIX . 'socpeople as p'; - $this->export_sql_end[$r] .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_country as country ON p.fk_pays = country.rowid'; - $this->export_sql_end[$r] .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'societe as s ON s.rowid = p.fk_soc'; - $this->export_sql_end[$r] .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'socpeople_extrafields as extra ON extra.fk_object = p.rowid'; + $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'categorie as u, '.MAIN_DB_PREFIX.'categorie_contact as cp, '.MAIN_DB_PREFIX.'socpeople as p'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as country ON p.fk_pays = country.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON s.rowid = p.fk_soc'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'socpeople_extrafields as extra ON extra.fk_object = p.rowid'; $this->export_sql_end[$r] .= ' WHERE u.rowid = cp.fk_categorie AND cp.fk_socpeople = p.rowid AND u.entity IN ('.getEntity('category').')'; $this->export_sql_end[$r] .= ' AND u.type = 4'; // contact categories // Imports //-------- - $r=0; + $r = 0; $r++; - $this->import_code[$r]=$this->rights_class.'_'.$r; - $this->import_label[$r]="CatList"; // Translation key - $this->import_icon[$r]=$this->picto; - $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon - $this->import_tables_array[$r]=array('ca'=>MAIN_DB_PREFIX.'categorie'); - $this->import_fields_array[$r]=array( - 'ca.label'=>"Label*",'ca.type'=>"Type*",'ca.description'=>"Description", + $this->import_code[$r] = $this->rights_class.'_'.$r; + $this->import_label[$r] = "CatList"; // Translation key + $this->import_icon[$r] = $this->picto; + $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon + $this->import_tables_array[$r] = array('ca'=>MAIN_DB_PREFIX.'categorie'); + $this->import_fields_array[$r] = array( + 'ca.label'=>"Label*", 'ca.type'=>"Type*", 'ca.description'=>"Description", 'ca.fk_parent' => 'Parent' ); - $this->import_regex_array[$r]=array('ca.type'=>'^[0|1|2|3]'); + $this->import_regex_array[$r] = array('ca.type'=>'^[0|1|2|3]'); $this->import_convertvalue_array[$r] = array( 'ca.fk_parent' => array( 'rule' => 'fetchidfromcodeandlabel', @@ -421,77 +421,96 @@ class modCategorie extends DolibarrModules 'codefromfield' => 'ca.type' ) ); - $typeexample=""; - if ($conf->product->enabled) { $typeexample.=($typeexample?"/":"")."0=Product"; } - if ($conf->fournisseur->enabled) { $typeexample.=($typeexample?"/":"")."1=Supplier"; } - if ($conf->societe->enabled) { $typeexample.=($typeexample?"/":"")."2=Customer-Prospect"; } - if ($conf->adherent->enabled) { $typeexample.=($typeexample?"/":"")."3=Member"; } + $typeexample = ""; + if ($conf->product->enabled) { $typeexample .= ($typeexample ? "/" : "")."0=Product"; } + if ($conf->fournisseur->enabled) { $typeexample .= ($typeexample ? "/" : "")."1=Supplier"; } + if ($conf->societe->enabled) { $typeexample .= ($typeexample ? "/" : "")."2=Customer-Prospect"; } + if ($conf->adherent->enabled) { $typeexample .= ($typeexample ? "/" : "")."3=Member"; } $this->import_examplevalues_array[$r] = array( - 'ca.label'=>"Supplier Category",'ca.type'=>$typeexample,'ca.description'=>"My Category description", + 'ca.label'=>"Supplier Category", 'ca.type'=>$typeexample, 'ca.description'=>"My Category description", 'ca.fk_parent' => '0' ); - if (! empty($conf->product->enabled)) + if (!empty($conf->product->enabled)) { //Products $r++; - $this->import_code[$r]=$this->rights_class.'_'.$r; - $this->import_label[$r]="CatProdLinks"; // Translation key - $this->import_icon[$r]=$this->picto; - $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon - $this->import_tables_array[$r]=array('cp'=>MAIN_DB_PREFIX.'categorie_product'); - $this->import_fields_array[$r]=array('cp.fk_categorie'=>"Category*",'cp.fk_product'=>"Product*"); - $this->import_regex_array[$r]=array('cp.fk_categorie'=>'rowid@'.MAIN_DB_PREFIX.'categorie:type=0'); + $this->import_code[$r] = $this->rights_class.'_'.$r; + $this->import_label[$r] = "CatProdLinks"; // Translation key + $this->import_icon[$r] = $this->picto; + $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon + $this->import_tables_array[$r] = array('cp'=>MAIN_DB_PREFIX.'categorie_product'); + $this->import_fields_array[$r] = array('cp.fk_categorie'=>"Category*", 'cp.fk_product'=>"Product*"); + $this->import_regex_array[$r] = array('cp.fk_categorie'=>'rowid@'.MAIN_DB_PREFIX.'categorie:type=0'); - $this->import_convertvalue_array[$r]=array( - 'cp.fk_categorie'=>array('rule'=>'fetchidfromref','classfile'=>'/categories/class/categorie.class.php','class'=>'Categorie','method'=>'fetch','element'=>'category'), - 'cp.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'product') + $this->import_convertvalue_array[$r] = array( + 'cp.fk_categorie'=>array('rule'=>'fetchidfromref', 'classfile'=>'/categories/class/categorie.class.php', 'class'=>'Categorie', 'method'=>'fetch', 'element'=>'category'), + 'cp.fk_product'=>array('rule'=>'fetchidfromref', 'classfile'=>'/product/class/product.class.php', 'class'=>'Product', 'method'=>'fetch', 'element'=>'product') ); - $this->import_examplevalues_array[$r]=array('cp.fk_categorie'=>"Imported category",'cp.fk_product'=>"PREF123456"); + $this->import_examplevalues_array[$r] = array('cp.fk_categorie'=>"Imported category", 'cp.fk_product'=>"PREF123456"); } - if (! empty($conf->societe->enabled)) + if (!empty($conf->societe->enabled)) { - //Customers + // Customers $r++; - $this->import_code[$r]=$this->rights_class.'_'.$r; - $this->import_label[$r]="CatCusLinks"; // Translation key - $this->import_icon[$r]=$this->picto; - $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon - $this->import_tables_array[$r]=array('cs'=>MAIN_DB_PREFIX.'categorie_societe'); - $this->import_fields_array[$r]=array('cs.fk_categorie'=>"Category*",'cs.fk_soc'=>"ThirdParty*"); - $this->import_regex_array[$r]=array( + $this->import_code[$r] = $this->rights_class.'_'.$r; + $this->import_label[$r] = "CatCusLinks"; // Translation key + $this->import_icon[$r] = $this->picto; + $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon + $this->import_tables_array[$r] = array('cs'=>MAIN_DB_PREFIX.'categorie_societe'); + $this->import_fields_array[$r] = array('cs.fk_categorie'=>"Category*", 'cs.fk_soc'=>"ThirdParty*"); + $this->import_regex_array[$r] = array( 'cs.fk_categorie'=>'rowid@'.MAIN_DB_PREFIX.'categorie:type=2', 'cs.fk_soc'=>'rowid@'.MAIN_DB_PREFIX.'societe:client>0' ); - $this->import_convertvalue_array[$r]=array( - 'cs.fk_categorie'=>array('rule'=>'fetchidfromref','classfile'=>'/categories/class/categorie.class.php','class'=>'Categorie','method'=>'fetch','element'=>'category'), - 'cs.fk_soc'=>array('rule'=>'fetchidfromref','classfile'=>'/societe/class/societe.class.php','class'=>'Societe','method'=>'fetch','element'=>'ThirdParty') + $this->import_convertvalue_array[$r] = array( + 'cs.fk_categorie'=>array('rule'=>'fetchidfromref', 'classfile'=>'/categories/class/categorie.class.php', 'class'=>'Categorie', 'method'=>'fetch', 'element'=>'category'), + 'cs.fk_soc'=>array('rule'=>'fetchidfromref', 'classfile'=>'/societe/class/societe.class.php', 'class'=>'Societe', 'method'=>'fetch', 'element'=>'ThirdParty') ); - $this->import_examplevalues_array[$r]=array('cs.fk_categorie'=>"Imported category",'cs.fk_soc'=>"MyBigCompany"); + $this->import_examplevalues_array[$r] = array('cs.fk_categorie'=>"Imported category", 'cs.fk_soc'=>"MyBigCompany"); + + // Contacts/Addresses + $r++; + $this->import_code[$r] = $this->rights_class.'_'.$r; + $this->import_label[$r] = "CatContactsLinks"; // Translation key + $this->import_icon[$r] = $this->picto; + $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon + $this->import_tables_array[$r] = array('cs'=>MAIN_DB_PREFIX.'categorie_contact'); + $this->import_fields_array[$r] = array('cs.fk_categorie'=>"Category*", 'cs.fk_socpeople'=>"Contact ID*"); + $this->import_regex_array[$r] = array( + 'cs.fk_categorie'=>'rowid@'.MAIN_DB_PREFIX.'categorie:type=4' + //'cs.fk_socpeople'=>'rowid@'.MAIN_DB_PREFIX.'socpeople' + ); + + $this->import_convertvalue_array[$r] = array( + 'cs.fk_categorie'=>array('rule'=>'fetchidfromref', 'classfile'=>'/categories/class/categorie.class.php', 'class'=>'Categorie', 'method'=>'fetch', 'element'=>'category') + //'cs.fk_socpeople'=>array('rule'=>'fetchidfromref','classfile'=>'/contact/class/contact.class.php','class'=>'Contact','method'=>'fetch','element'=>'Contact') + ); + $this->import_examplevalues_array[$r] = array('cs.fk_categorie'=>"Imported category", 'cs.fk_socpeople'=>"123"); } - if (! empty($conf->fournisseur->enabled)) + if (!empty($conf->fournisseur->enabled)) { // Suppliers $r++; - $this->import_code[$r]=$this->rights_class.'_'.$r; - $this->import_label[$r]="CatSupLinks"; // Translation key - $this->import_icon[$r]=$this->picto; - $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon - $this->import_tables_array[$r]=array('cs'=>MAIN_DB_PREFIX.'categorie_fournisseur'); - $this->import_fields_array[$r]=array('cs.fk_categorie'=>"Category*",'cs.fk_soc'=>"Supplier*"); - $this->import_regex_array[$r]=array( + $this->import_code[$r] = $this->rights_class.'_'.$r; + $this->import_label[$r] = "CatSupLinks"; // Translation key + $this->import_icon[$r] = $this->picto; + $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon + $this->import_tables_array[$r] = array('cs'=>MAIN_DB_PREFIX.'categorie_fournisseur'); + $this->import_fields_array[$r] = array('cs.fk_categorie'=>"Category*", 'cs.fk_soc'=>"Supplier*"); + $this->import_regex_array[$r] = array( 'cs.fk_categorie'=>'rowid@'.MAIN_DB_PREFIX.'categorie:type=1', 'cs.fk_soc'=>'rowid@'.MAIN_DB_PREFIX.'societe:fournisseur>0' ); - $this->import_convertvalue_array[$r]=array( - 'cs.fk_categorie'=>array('rule'=>'fetchidfromref','classfile'=>'/categories/class/categorie.class.php','class'=>'Categorie','method'=>'fetch','element'=>'category'), - 'cs.fk_soc'=>array('rule'=>'fetchidfromref','classfile'=>'/societe/class/societe.class.php','class'=>'Societe','method'=>'fetch','element'=>'ThirdParty') + $this->import_convertvalue_array[$r] = array( + 'cs.fk_categorie'=>array('rule'=>'fetchidfromref', 'classfile'=>'/categories/class/categorie.class.php', 'class'=>'Categorie', 'method'=>'fetch', 'element'=>'category'), + 'cs.fk_soc'=>array('rule'=>'fetchidfromref', 'classfile'=>'/societe/class/societe.class.php', 'class'=>'Societe', 'method'=>'fetch', 'element'=>'ThirdParty') ); - $this->import_examplevalues_array[$r]=array('cs.fk_categorie'=>"Imported category",'cs.fk_soc'=>"MyBigCompany"); + $this->import_examplevalues_array[$r] = array('cs.fk_categorie'=>"Imported category", 'cs.fk_soc'=>"MyBigCompany"); } } diff --git a/htdocs/core/modules/modContrat.class.php b/htdocs/core/modules/modContrat.class.php index fe846c1fd4c..3b8a7aa3f8b 100644 --- a/htdocs/core/modules/modContrat.class.php +++ b/htdocs/core/modules/modContrat.class.php @@ -165,7 +165,7 @@ 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'=>"Id",'co.ref'=>"Ref",'co.datec'=>"DateCreation",'co.date_contrat'=>"DateContract",'co.mise_en_service'=>"ContractStartDate", + 'co.rowid'=>"Id",'co.ref'=>"Ref",'co.datec'=>"DateCreation",'co.date_contrat'=>"DateContract", '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", @@ -175,7 +175,7 @@ class modContrat extends DolibarrModules $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.rowid'=>"contract",'co.ref'=>"contract",'co.datec'=>"contract",'co.date_contrat'=>"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", @@ -185,7 +185,7 @@ class modContrat extends DolibarrModules $this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text', 's.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text', 's.code_compta_fournisseur'=>'Text','s.tva_intra'=>'Text', - 'co.ref'=>"Text",'co.datec'=>"Date",'co.date_contrat'=>"Date",'co.mise_en_service'=>"Date", + 'co.ref'=>"Text",'co.datec'=>"Date",'co.date_contrat'=>"Date", 'co.fin_validite'=>"Date",'co.date_cloture'=>"Date",'co.note_private'=>"Text",'co.note_public'=>"Text", 'cod.label'=>"Text",'cod.description'=>"Text",'cod.price_ht'=>"Numeric",'cod.tva_tx'=>"Numeric", 'cod.qty'=>"Numeric",'cod.total_ht'=>"Numeric",'cod.total_tva'=>"Numeric",'cod.total_ttc'=>"Numeric", diff --git a/htdocs/core/modules/modDon.class.php b/htdocs/core/modules/modDon.class.php index 42b4a8ef2b2..f4999f309c2 100644 --- a/htdocs/core/modules/modDon.class.php +++ b/htdocs/core/modules/modDon.class.php @@ -91,10 +91,10 @@ class modDon extends DolibarrModules $this->const[$r][4] = 0; $r++; - $this->const[$r][0] = "DONATION_ART885"; + $this->const[$r][0] = "DONATION_ART978"; $this->const[$r][1] = "yesno"; $this->const[$r][2] = "0"; - $this->const[$r][3] = 'Option Française - Eligibilité Art885-0 V bis du CGI'; + $this->const[$r][3] = 'Option Française - Eligibilité Art978 du CGI'; $this->const[$r][4] = 0; $r++; diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php index 2042e8b35da..b8bc72d423f 100644 --- a/htdocs/core/modules/modFournisseur.class.php +++ b/htdocs/core/modules/modFournisseur.class.php @@ -25,7 +25,7 @@ * \ingroup fournisseur * \brief Description and activation file for module Supplier */ -include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; +include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php'; /** @@ -58,7 +58,7 @@ class modFournisseur extends DolibarrModules $this->version = 'dolibarr'; $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); - $this->picto='company'; + $this->picto = 'company'; // Data directories to create when module is enabled $this->dirs = array( @@ -71,7 +71,7 @@ class modFournisseur extends DolibarrModules // Dependencies $this->depends = array("modSociete"); - $this->requiredby = array(); + $this->requiredby = array("modSupplierProposal"); $this->langfiles = array('bills', 'companies', 'suppliers', 'orders', 'sendings'); // Config pages @@ -79,7 +79,7 @@ class modFournisseur extends DolibarrModules // Constants $this->const = array(); - $r=0; + $r = 0; $this->const[$r][0] = "COMMANDE_SUPPLIER_ADDON_PDF"; $this->const[$r][1] = "chaine"; @@ -120,19 +120,19 @@ class modFournisseur extends DolibarrModules // Boxes $this->boxes = array( - 0=>array('file'=>'box_graph_invoices_supplier_permonth.php','enabledbydefaulton'=>'Home'), - 1=>array('file'=>'box_graph_orders_supplier_permonth.php','enabledbydefaulton'=>'Home'), - 2=>array('file'=>'box_fournisseurs.php','enabledbydefaulton'=>'Home'), - 3=>array('file'=>'box_factures_fourn_imp.php','enabledbydefaulton'=>'Home'), - 4=>array('file'=>'box_factures_fourn.php','enabledbydefaulton'=>'Home'), - 5=>array('file'=>'box_supplier_orders.php','enabledbydefaulton'=>'Home'), - 6=>array('file'=>'box_supplier_orders_awaiting_reception.php','enabledbydefaulton'=>'Home'), + 0=>array('file'=>'box_graph_invoices_supplier_permonth.php', 'enabledbydefaulton'=>'Home'), + 1=>array('file'=>'box_graph_orders_supplier_permonth.php', 'enabledbydefaulton'=>'Home'), + 2=>array('file'=>'box_fournisseurs.php', 'enabledbydefaulton'=>'Home'), + 3=>array('file'=>'box_factures_fourn_imp.php', 'enabledbydefaulton'=>'Home'), + 4=>array('file'=>'box_factures_fourn.php', 'enabledbydefaulton'=>'Home'), + 5=>array('file'=>'box_supplier_orders.php', 'enabledbydefaulton'=>'Home'), + 6=>array('file'=>'box_supplier_orders_awaiting_reception.php', 'enabledbydefaulton'=>'Home'), ); // Permissions $this->rights = array(); $this->rights_class = 'fournisseur'; - $r=0; + $r = 0; $r++; $this->rights[$r][0] = 1181; @@ -205,11 +205,11 @@ class modFournisseur extends DolibarrModules $this->rights[$r][4] = 'commande'; $this->rights[$r][5] = 'supprimer'; - if (! empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED)) + if (!empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED)) { $r++; $this->rights[$r][0] = 1190; - $this->rights[$r][1] = 'Approve supplier order (second level)'; // $langs->trans("Permission1190"); + $this->rights[$r][1] = 'Approve supplier order (second level)'; // $langs->trans("Permission1190"); $this->rights[$r][2] = 'w'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'commande'; @@ -275,27 +275,28 @@ class modFournisseur extends DolibarrModules // Menus //------- - $this->menu = 1; // This module add menu entries. They are coded into menu manager. + $this->menu = 1; // This module add menu entries. They are coded into menu manager. // Exports //-------- - $r=0; + $r = 0; $r++; - $this->export_code[$r]=$this->rights_class.'_'.$r; - $this->export_label[$r]='Vendor invoices and lines of invoices'; - $this->export_icon[$r]='bill'; - $this->export_permission[$r]=array(array("fournisseur","facture","export")); - $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.idprof5'=>'ProfId5','s.idprof6'=>'ProfId6','s.tva_intra'=>'VATIntra', - 'f.rowid'=>"InvoiceId",'f.ref'=>"InvoiceRef",'f.ref_supplier'=>"RefSupplier",'f.datec'=>"InvoiceDateCreation",'f.datef'=>"DateInvoice",'f.date_lim_reglement'=>'DateMaxPayment', - 'f.total_ht'=>"TotalHT",'f.total_ttc'=>"TotalTTC",'f.total_tva'=>"TotalVAT",'f.paye'=>"InvoicePaid",'f.fk_statut'=>'InvoiceStatus','f.note_public'=>"InvoiceNote", - 'fd.rowid'=>'LineId','fd.description'=>"LineDescription",'fd.tva_tx'=>"LineVATRate",'fd.qty'=>"LineQty",'fd.remise_percent'=>"Discount",'fd.total_ht'=>"LineTotalHT", - 'fd.total_ttc'=>"LineTotalTTC",'fd.tva'=>"LineTotalVAT",'fd.product_type'=>'TypeOfLineServiceOrProduct','fd.fk_product'=>'ProductId', - 'p.ref'=>'ProductRef','p.label'=>'ProductLabel','p.accountancy_code_buy'=>'ProductAccountancyBuyCode','project.rowid'=>'ProjectId', - 'project.ref'=>'ProjectRef','project.title'=>'ProjectLabel' + $this->export_code[$r] = $this->rights_class.'_'.$r; + $this->export_label[$r] = 'Vendor invoices and lines of invoices'; + $this->export_icon[$r] = 'bill'; + $this->export_permission[$r] = array(array("fournisseur", "facture", "export")); + $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.idprof5'=>'ProfId5', 's.idprof6'=>'ProfId6', + 's.code_compta'=>'CustomerAccountancyCode', 's.code_compta_fournisseur'=>'SupplierAccountancyCode', 's.tva_intra'=>'VATIntra', + 'f.rowid'=>"InvoiceId", 'f.ref'=>"InvoiceRef", 'f.ref_supplier'=>"RefSupplier", 'f.datec'=>"InvoiceDateCreation", 'f.datef'=>"DateInvoice", 'f.date_lim_reglement'=>'DateMaxPayment', + 'f.total_ht'=>"TotalHT", 'f.total_ttc'=>"TotalTTC", 'f.total_tva'=>"TotalVAT", 'f.paye'=>"InvoicePaid", 'f.fk_statut'=>'InvoiceStatus', 'f.note_public'=>"InvoiceNote", + 'fd.rowid'=>'LineId', 'fd.description'=>"LineDescription", 'fd.tva_tx'=>"LineVATRate", 'fd.qty'=>"LineQty", 'fd.remise_percent'=>"Discount", 'fd.total_ht'=>"LineTotalHT", + 'fd.total_ttc'=>"LineTotalTTC", 'fd.tva'=>"LineTotalVAT", 'fd.product_type'=>'TypeOfLineServiceOrProduct', 'fd.fk_product'=>'ProductId', + 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel', 'p.accountancy_code_buy'=>'ProductAccountancyBuyCode', 'project.rowid'=>'ProjectId', + 'project.ref'=>'ProjectRef', 'project.title'=>'ProjectLabel' ); //$this->export_TypeFields_array[$r]=array( // 's.rowid'=>"List:societe:CompanyName",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text', @@ -303,122 +304,123 @@ class modFournisseur extends DolibarrModules // 'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_public'=>"Text",'fd.description'=>"Text",'fd.tva_tx'=>"Text",'fd.qty'=>"Numeric",'fd.total_ht'=>"Numeric",'fd.total_ttc'=>"Numeric", // 'fd.tva'=>"Numeric",'fd.product_type'=>'Numeric','fd.fk_product'=>'List:product:label','p.ref'=>'Text','p.label'=>'Text' //); - $this->export_TypeFields_array[$r]=array( - 's.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text', - 's.tva_intra'=>'Text','f.ref'=>"Text",'f.ref_supplier'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.date_lim_reglement'=>'Date','f.total_ht'=>"Numeric",'f.total_ttc'=>"Numeric", - 'f.total_tva'=>"Numeric",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_public'=>"Text",'fd.description'=>"Text",'fd.tva_tx'=>"Text",'fd.qty'=>"Numeric",'fd.total_ht'=>"Numeric", - 'fd.total_ttc'=>"Numeric",'fd.tva'=>"Numeric",'fd.product_type'=>'Numeric','fd.fk_product'=>'List:product:label', - 'p.ref'=>'Text','p.label'=>'Text','project.ref'=>'Text','project.title'=>'Text' + $this->export_TypeFields_array[$r] = array( + 's.nom'=>'Text', 's.address'=>'Text', 's.zip'=>'Text', 's.town'=>'Text', 'c.code'=>'Text', 's.phone'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', 's.ape'=>'Text', 's.idprof4'=>'Text', 's.idprof5'=>'Text', 's.idprof6'=>'Text', + 's.code_compta'=>'Text', 's.code_compta_fournisseur'=>'Text', 's.tva_intra'=>'Text', 'f.ref'=>"Text", 'f.ref_supplier'=>"Text", 'f.datec'=>"Date", 'f.datef'=>"Date", 'f.date_lim_reglement'=>'Date', + 'f.total_ht'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.total_tva'=>"Numeric", 'f.paye'=>"Boolean", 'f.fk_statut'=>'Status', 'f.note_public'=>"Text", 'fd.description'=>"Text", 'fd.tva_tx'=>"Text", + 'fd.qty'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.tva'=>"Numeric", 'fd.product_type'=>'Numeric', 'fd.fk_product'=>'List:product:label', + 'p.ref'=>'Text', 'p.label'=>'Text', 'project.ref'=>'Text', 'project.title'=>'Text' ); - $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.idprof5'=>'company','s.idprof6'=>'company','s.tva_intra'=>'company','f.rowid'=>"invoice",'f.ref'=>"invoice",'f.ref_supplier'=>"invoice", - 'f.datec'=>"invoice",'f.datef'=>"invoice",'f.date_lim_reglement'=>'invoice','f.total_ht'=>"invoice",'f.total_ttc'=>"invoice",'f.total_tva'=>"invoice",'f.paye'=>"invoice",'f.fk_statut'=>'invoice', - 'f.note_public'=>"invoice",'fd.rowid'=>'invoice_line','fd.description'=>"invoice_line",'fd.tva_tx'=>"invoice_line",'fd.qty'=>"invoice_line",'fd.remise_percent'=>"invoice_line", - 'fd.total_ht'=>"invoice_line",'fd.total_ttc'=>"invoice_line",'fd.tva'=>"invoice_line",'fd.product_type'=>'invoice_line','fd.fk_product'=>'product', - 'p.ref'=>'product','p.label'=>'product','p.accountancy_code_buy'=>'product','project.rowid'=>'project','project.ref'=>'project','project.title'=>'project' + $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.idprof5'=>'company', 's.idprof6'=>'company', 's.code_compta'=>'company', 's.code_compta_fournisseur'=>'company', 's.tva_intra'=>'company', 'f.rowid'=>"invoice", + 'f.ref'=>"invoice", 'f.ref_supplier'=>"invoice", 'f.datec'=>"invoice", 'f.datef'=>"invoice", 'f.date_lim_reglement'=>'invoice', 'f.total_ht'=>"invoice", 'f.total_ttc'=>"invoice", 'f.total_tva'=>"invoice", + 'f.paye'=>"invoice", 'f.fk_statut'=>'invoice', 'f.note_public'=>"invoice", 'fd.rowid'=>'invoice_line', 'fd.description'=>"invoice_line", 'fd.tva_tx'=>"invoice_line", 'fd.qty'=>"invoice_line", + 'fd.remise_percent'=>"invoice_line", 'fd.total_ht'=>"invoice_line", 'fd.total_ttc'=>"invoice_line", 'fd.tva'=>"invoice_line", 'fd.product_type'=>'invoice_line', 'fd.fk_product'=>'product', + 'p.ref'=>'product', 'p.label'=>'product', 'p.accountancy_code_buy'=>'product', 'project.rowid'=>'project', 'project.ref'=>'project', 'project.title'=>'project' ); - $this->export_dependencies_array[$r]=array('invoice_line'=>'fd.rowid','product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them + $this->export_dependencies_array[$r] = array('invoice_line'=>'fd.rowid', 'product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them // Add extra fields object - $sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn' AND entity IN (0, ".$conf->entity.")"; - $resql=$this->db->query($sql); + $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn' AND entity IN (0, ".$conf->entity.")"; + $resql = $this->db->query($sql); if ($resql) // This can fail when class is used on old database (during migration for example) { - while ($obj=$this->db->fetch_object($resql)) + while ($obj = $this->db->fetch_object($resql)) { - $fieldname='extra.'.$obj->name; - $fieldlabel=ucfirst($obj->label); - $typeFilter="Text"; - switch($obj->type) + $fieldname = 'extra.'.$obj->name; + $fieldlabel = ucfirst($obj->label); + $typeFilter = "Text"; + switch ($obj->type) { case 'int': case 'double': case 'price': - $typeFilter="Numeric"; + $typeFilter = "Numeric"; break; case 'date': case 'datetime': - $typeFilter="Date"; + $typeFilter = "Date"; break; case 'boolean': - $typeFilter="Boolean"; + $typeFilter = "Boolean"; break; case 'sellist': - $tmp=''; - $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null - if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp=array_shift(array_keys($tmpparam['options'])); - if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp; + $tmp = ''; + $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null + if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp = array_shift(array_keys($tmpparam['options'])); + if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter = "List:".$tmp; break; } - $this->export_fields_array[$r][$fieldname]=$fieldlabel; - $this->export_TypeFields_array[$r][$fieldname]=$typeFilter; - $this->export_entities_array[$r][$fieldname]='invoice'; + $this->export_fields_array[$r][$fieldname] = $fieldlabel; + $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; + $this->export_entities_array[$r][$fieldname] = 'invoice'; } } // End add extra fields // Add extra fields line - $sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn_det' AND entity IN (0, ".$conf->entity.")"; - $resql=$this->db->query($sql); + $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn_det' AND entity IN (0, ".$conf->entity.")"; + $resql = $this->db->query($sql); if ($resql) // This can fail when class is used on old database (during migration for example) { - while ($obj=$this->db->fetch_object($resql)) + while ($obj = $this->db->fetch_object($resql)) { - $fieldname='extraline.'.$obj->name; - $fieldlabel=ucfirst($obj->label); - $typeFilter="Text"; - switch($obj->type) + $fieldname = 'extraline.'.$obj->name; + $fieldlabel = ucfirst($obj->label); + $typeFilter = "Text"; + switch ($obj->type) { case 'int': case 'double': case 'price': - $typeFilter="Numeric"; + $typeFilter = "Numeric"; break; case 'date': case 'datetime': - $typeFilter="Date"; + $typeFilter = "Date"; break; case 'boolean': - $typeFilter="Boolean"; + $typeFilter = "Boolean"; break; case 'sellist': - $tmp=''; - $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null - if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp=array_shift(array_keys($tmpparam['options'])); - if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp; + $tmp = ''; + $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null + if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp = array_shift(array_keys($tmpparam['options'])); + if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter = "List:".$tmp; break; } - $this->export_fields_array[$r][$fieldname]=$fieldlabel; - $this->export_TypeFields_array[$r][$fieldname]=$typeFilter; - $this->export_entities_array[$r][$fieldname]='invoice_line'; + $this->export_fields_array[$r][$fieldname] = $fieldlabel; + $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; + $this->export_entities_array[$r][$fieldname] = 'invoice_line'; } } // End add extra fields line - $this->export_sql_start[$r]='SELECT DISTINCT '; - $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'societe as s'; - if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid,'; - $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'facture_fourn as f'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'projet as project on (f.fk_projet = project.rowid)'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn_extrafields as extra ON f.rowid = extra.fk_object'; - $this->export_sql_end[$r] .=' , '.MAIN_DB_PREFIX.'facture_fourn_det as fd'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn_det_extrafields as extraline ON fd.rowid = extraline.fk_object'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product as p on (fd.fk_product = p.rowid)'; - $this->export_sql_end[$r] .=' WHERE f.fk_soc = s.rowid AND f.rowid = fd.fk_facture_fourn'; - $this->export_sql_end[$r] .=' AND f.entity IN ('.getEntity('supplier_invoice').')'; - if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' AND sc.fk_user = '.$user->id; + $this->export_sql_start[$r] = 'SELECT DISTINCT '; + $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'societe as s'; + if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid,'; + $this->export_sql_end[$r] .= ' '.MAIN_DB_PREFIX.'facture_fourn as f'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as project on (f.fk_projet = project.rowid)'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn_extrafields as extra ON f.rowid = extra.fk_object'; + $this->export_sql_end[$r] .= ' , '.MAIN_DB_PREFIX.'facture_fourn_det as fd'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn_det_extrafields as extraline ON fd.rowid = extraline.fk_object'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p on (fd.fk_product = p.rowid)'; + $this->export_sql_end[$r] .= ' WHERE f.fk_soc = s.rowid AND f.rowid = fd.fk_facture_fourn'; + $this->export_sql_end[$r] .= ' AND f.entity IN ('.getEntity('supplier_invoice').')'; + if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' AND sc.fk_user = '.$user->id; $r++; - $this->export_code[$r]=$this->rights_class.'_'.$r; - $this->export_label[$r]='Factures fournisseurs et reglements'; - $this->export_icon[$r]='bill'; - $this->export_permission[$r]=array(array("fournisseur","facture","export")); - $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.idprof5'=>'ProfId5','s.idprof6'=>'ProfId6', - 's.tva_intra'=>'VATIntra','f.rowid'=>"InvoiceId",'f.ref'=>"InvoiceRef",'f.ref_supplier'=>"RefSupplier",'f.datec'=>"InvoiceDateCreation", - 'f.datef'=>"DateInvoice",'f.total_ht'=>"TotalHT",'f.total_ttc'=>"TotalTTC",'f.total_tva'=>"TotalVAT",'f.paye'=>"InvoicePaid", - 'f.fk_statut'=>'InvoiceStatus','f.note_public'=>"InvoiceNote",'p.rowid'=>'PaymentId','pf.amount'=>'AmountPayment', - 'p.datep'=>'DatePayment','p.num_paiement'=>'PaymentNumber','project.rowid'=>'ProjectId','project.ref'=>'ProjectRef','project.title'=>'ProjectLabel' + $this->export_code[$r] = $this->rights_class.'_'.$r; + $this->export_label[$r] = 'Factures fournisseurs et reglements'; + $this->export_icon[$r] = 'bill'; + $this->export_permission[$r] = array(array("fournisseur", "facture", "export")); + $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.idprof5'=>'ProfId5', 's.idprof6'=>'ProfId6', + 's.code_compta'=>'CustomerAccountancyCode', 's.code_compta_fournisseur'=>'SupplierAccountancyCode', 's.tva_intra'=>'VATIntra', + 'f.rowid'=>"InvoiceId", 'f.ref'=>"InvoiceRef", 'f.ref_supplier'=>"RefSupplier", 'f.datec'=>"InvoiceDateCreation", + 'f.datef'=>"DateInvoice", 'f.total_ht'=>"TotalHT", 'f.total_ttc'=>"TotalTTC", 'f.total_tva'=>"TotalVAT", 'f.paye'=>"InvoicePaid", + 'f.fk_statut'=>'InvoiceStatus', 'f.note_public'=>"InvoiceNote", 'p.rowid'=>'PaymentId', 'pf.amount'=>'AmountPayment', + 'p.datep'=>'DatePayment', 'p.num_paiement'=>'PaymentNumber', 'project.rowid'=>'ProjectId', 'project.ref'=>'ProjectRef', 'project.title'=>'ProjectLabel' ); //$this->export_TypeFields_array[$r]=array( // 's.rowid'=>"List:societe:CompanyName",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text', @@ -426,200 +428,201 @@ class modFournisseur extends DolibarrModules // 'f.total_ht'=>"Numeric",'f.total_ttc'=>"Numeric",'f.total_tva'=>"Numeric",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_public'=>"Text", // 'pf.amount'=>'Numeric','p.datep'=>'Date','p.num_paiement'=>'Numeric' //); - $this->export_TypeFields_array[$r]=array( - 's.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','c.code'=>'Text','s.phone'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text', - 's.idprof4'=>'Text','s.tva_intra'=>'Text','f.ref'=>"Text",'f.ref_supplier'=>"Text",'f.datec'=>"Date",'f.datef'=>"Date",'f.total_ht'=>"Numeric", - 'f.total_ttc'=>"Numeric",'f.total_tva'=>"Numeric",'f.paye'=>"Boolean",'f.fk_statut'=>'Status','f.note_public'=>"Text",'pf.amount'=>'Numeric', - 'p.datep'=>'Date','p.num_paiement'=>'Numeric','project.ref'=>'Text','project.title'=>'Text' + $this->export_TypeFields_array[$r] = array( + 's.nom'=>'Text', 's.address'=>'Text', 's.zip'=>'Text', 's.town'=>'Text', 'c.code'=>'Text', 's.phone'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', 's.ape'=>'Text', + 's.idprof4'=>'Text', 's.code_compta'=>'Text', 's.code_compta_fournisseur'=>'Text', 's.tva_intra'=>'Text', 'f.ref'=>"Text", 'f.ref_supplier'=>"Text", 'f.datec'=>"Date", 'f.datef'=>"Date", 'f.total_ht'=>"Numeric", + 'f.total_ttc'=>"Numeric", 'f.total_tva'=>"Numeric", 'f.paye'=>"Boolean", 'f.fk_statut'=>'Status', 'f.note_public'=>"Text", 'pf.amount'=>'Numeric', + 'p.datep'=>'Date', 'p.num_paiement'=>'Numeric', 'project.ref'=>'Text', 'project.title'=>'Text' ); - $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.idprof5'=>'company','s.idprof6'=>'company','s.tva_intra'=>'company', - 'f.rowid'=>"invoice",'f.ref'=>"invoice",'f.ref_supplier'=>"invoice",'f.datec'=>"invoice",'f.datef'=>"invoice",'f.total_ht'=>"invoice", - 'f.total_ttc'=>"invoice",'f.total_tva'=>"invoice",'f.paye'=>"invoice",'f.fk_statut'=>'invoice','f.note_public'=>"invoice",'p.rowid'=>'payment','pf.amount'=>'payment', - 'p.datep'=>'payment','p.num_paiement'=>'payment','project.rowid'=>'project','project.ref'=>'project','project.title'=>'project'); - $this->export_dependencies_array[$r]=array('payment'=>'p.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them + $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.idprof5'=>'company', 's.idprof6'=>'company', + 's.code_compta'=>'company', 's.code_compta_fournisseur'=>'company', 's.tva_intra'=>'company', + 'f.rowid'=>"invoice", 'f.ref'=>"invoice", 'f.ref_supplier'=>"invoice", 'f.datec'=>"invoice", 'f.datef'=>"invoice", 'f.total_ht'=>"invoice", + 'f.total_ttc'=>"invoice", 'f.total_tva'=>"invoice", 'f.paye'=>"invoice", 'f.fk_statut'=>'invoice', 'f.note_public'=>"invoice", 'p.rowid'=>'payment', 'pf.amount'=>'payment', + 'p.datep'=>'payment', 'p.num_paiement'=>'payment', 'project.rowid'=>'project', 'project.ref'=>'project', 'project.title'=>'project'); + $this->export_dependencies_array[$r] = array('payment'=>'p.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them // Add extra fields object - $sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn' AND entity IN (0, ".$conf->entity.")"; - $resql=$this->db->query($sql); + $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn' AND entity IN (0, ".$conf->entity.")"; + $resql = $this->db->query($sql); if ($resql) // This can fail when class is used on old database (during migration for example) { - while ($obj=$this->db->fetch_object($resql)) + while ($obj = $this->db->fetch_object($resql)) { - $fieldname='extra.'.$obj->name; - $fieldlabel=ucfirst($obj->label); - $typeFilter="Text"; - switch($obj->type) + $fieldname = 'extra.'.$obj->name; + $fieldlabel = ucfirst($obj->label); + $typeFilter = "Text"; + switch ($obj->type) { case 'int': case 'double': case 'price': - $typeFilter="Numeric"; + $typeFilter = "Numeric"; break; case 'date': case 'datetime': - $typeFilter="Date"; + $typeFilter = "Date"; break; case 'boolean': - $typeFilter="Boolean"; + $typeFilter = "Boolean"; break; case 'sellist': - $tmp=''; - $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null - if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp=array_shift(array_keys($tmpparam['options'])); - if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp; + $tmp = ''; + $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null + if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp = array_shift(array_keys($tmpparam['options'])); + if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter = "List:".$tmp; break; } - $this->export_fields_array[$r][$fieldname]=$fieldlabel; - $this->export_TypeFields_array[$r][$fieldname]=$typeFilter; - $this->export_entities_array[$r][$fieldname]='invoice'; + $this->export_fields_array[$r][$fieldname] = $fieldlabel; + $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; + $this->export_entities_array[$r][$fieldname] = 'invoice'; } } // End add extra fields object - $this->export_sql_start[$r]='SELECT DISTINCT '; - $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'societe as s'; - if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid,'; - $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'facture_fourn as f'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'projet as project on (f.fk_projet = project.rowid)'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn_extrafields as extra ON f.rowid = extra.fk_object'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_facturefourn = f.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn as p ON pf.fk_paiementfourn = p.rowid'; - $this->export_sql_end[$r] .=' WHERE f.fk_soc = s.rowid'; - $this->export_sql_end[$r] .=' AND f.entity IN ('.getEntity('supplier_invoice').')'; - if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' AND sc.fk_user = '.$user->id; + $this->export_sql_start[$r] = 'SELECT DISTINCT '; + $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'societe as s'; + if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid,'; + $this->export_sql_end[$r] .= ' '.MAIN_DB_PREFIX.'facture_fourn as f'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as project on (f.fk_projet = project.rowid)'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn_extrafields as extra ON f.rowid = extra.fk_object'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_facturefourn = f.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn as p ON pf.fk_paiementfourn = p.rowid'; + $this->export_sql_end[$r] .= ' WHERE f.fk_soc = s.rowid'; + $this->export_sql_end[$r] .= ' AND f.entity IN ('.getEntity('supplier_invoice').')'; + if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' AND sc.fk_user = '.$user->id; // Order $r++; - $this->export_code[$r]=$this->rights_class.'_'.$r; - $this->export_label[$r]='Purchase Orders and lines of purchase orders'; - $this->export_icon[$r]='order'; - $this->export_permission[$r]=array(array("fournisseur","commande","export")); - $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.idprof5'=>'ProfId5','s.idprof6'=>'ProfId6','s.tva_intra'=>'VATIntra', - 'f.rowid'=>"OrderId",'f.ref'=>"Ref",'f.ref_supplier'=>"RefSupplier",'f.date_creation'=>"DateCreation",'f.date_commande'=>"OrderDate",'f.date_livraison'=>"DateDeliveryPlanned", - 'f.total_ht'=>"TotalHT",'f.total_ttc'=>"TotalTTC",'f.tva'=>"TotalVAT",'f.fk_statut'=>'Status','f.date_approve'=>'DateApprove','f.date_approve2'=>'DateApprove2', - 'f.note_public'=>"NotePublic",'f.note_private'=>"NotePrivate",'ua1.login'=>'ApprovedBy','ua2.login'=>'ApprovedBy2','fd.rowid'=>'LineId','fd.description'=>"LineDescription", - 'fd.tva_tx'=>"LineVATRate",'fd.qty'=>"LineQty",'fd.remise_percent'=>"Discount",'fd.total_ht'=>"LineTotalHT",'fd.total_ttc'=>"LineTotalTTC", - 'fd.total_tva'=>"LineTotalVAT",'fd.product_type'=>'TypeOfLineServiceOrProduct','fd.ref'=>'RefSupplier','fd.fk_product'=>'ProductId', - 'p.ref'=>'ProductRef','p.label'=>'ProductLabel','project.rowid'=>'ProjectId','project.ref'=>'ProjectRef','project.title'=>'ProjectLabel' + $this->export_code[$r] = $this->rights_class.'_'.$r; + $this->export_label[$r] = 'Purchase Orders and lines of purchase orders'; + $this->export_icon[$r] = 'order'; + $this->export_permission[$r] = array(array("fournisseur", "commande", "export")); + $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.idprof5'=>'ProfId5', 's.idprof6'=>'ProfId6', 's.tva_intra'=>'VATIntra', + 'f.rowid'=>"OrderId", 'f.ref'=>"Ref", 'f.ref_supplier'=>"RefSupplier", 'f.date_creation'=>"DateCreation", 'f.date_commande'=>"OrderDate", 'f.date_livraison'=>"DateDeliveryPlanned", + 'f.total_ht'=>"TotalHT", 'f.total_ttc'=>"TotalTTC", 'f.tva'=>"TotalVAT", 'f.fk_statut'=>'Status', 'f.date_approve'=>'DateApprove', 'f.date_approve2'=>'DateApprove2', + 'f.note_public'=>"NotePublic", 'f.note_private'=>"NotePrivate", 'ua1.login'=>'ApprovedBy', 'ua2.login'=>'ApprovedBy2', 'fd.rowid'=>'LineId', 'fd.description'=>"LineDescription", + 'fd.tva_tx'=>"LineVATRate", 'fd.qty'=>"LineQty", 'fd.remise_percent'=>"Discount", 'fd.total_ht'=>"LineTotalHT", 'fd.total_ttc'=>"LineTotalTTC", + 'fd.total_tva'=>"LineTotalVAT", 'fd.product_type'=>'TypeOfLineServiceOrProduct', 'fd.ref'=>'RefSupplier', 'fd.fk_product'=>'ProductId', + 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel', 'project.rowid'=>'ProjectId', 'project.ref'=>'ProjectRef', 'project.title'=>'ProjectLabel' ); if (empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED)) { unset($this->export_fields_array['f.date_approve2']); unset($this->export_fields_array['ua2.login']); } - $this->export_TypeFields_array[$r]=array( - 's.rowid'=>"company",'s.nom'=>'Text','s.address'=>'Text','s.cp'=>'Text','s.ville'=>'Text','c.code'=>'Text','s.tel'=>'Text','s.siren'=>'Text', - 's.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.idprof5'=>'Text','s.idprof6'=>'Text','s.tva_intra'=>'Text','f.ref'=>"Text",'f.ref_supplier'=>"Text", - 'f.date_creation'=>"Date",'f.date_commande'=>"Date",'f.date_livraison'=>"Date",'f.total_ht'=>"Numeric",'f.total_ttc'=>"Numeric",'f.tva'=>"Numeric", - 'f.fk_statut'=>'Status','f.date_approve'=>'Date','f.date_approve2'=>'Date','f.note_public'=>"Text",'f.note_private'=>"Text",'fd.description'=>"Text", - 'fd.tva_tx'=>"Numeric",'fd.qty'=>"Numeric",'fd.remise_percent'=>"Numeric",'fd.total_ht'=>"Numeric",'fd.total_ttc'=>"Numeric",'fd.total_tva'=>"Numeric", - 'fd.product_type'=>'Numeric','fd.ref'=>'Text','fd.fk_product'=>'List:product:label','p.ref'=>'Text','p.label'=>'Text','project.ref'=>'Text','project.title'=>'Text' + $this->export_TypeFields_array[$r] = array( + 's.rowid'=>"company", 's.nom'=>'Text', 's.address'=>'Text', 's.cp'=>'Text', 's.ville'=>'Text', 'c.code'=>'Text', 's.tel'=>'Text', 's.siren'=>'Text', + 's.siret'=>'Text', 's.ape'=>'Text', 's.idprof4'=>'Text', 's.idprof5'=>'Text', 's.idprof6'=>'Text', 's.tva_intra'=>'Text', 'f.ref'=>"Text", 'f.ref_supplier'=>"Text", + 'f.date_creation'=>"Date", 'f.date_commande'=>"Date", 'f.date_livraison'=>"Date", 'f.total_ht'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.tva'=>"Numeric", + 'f.fk_statut'=>'Status', 'f.date_approve'=>'Date', 'f.date_approve2'=>'Date', 'f.note_public'=>"Text", 'f.note_private'=>"Text", 'fd.description'=>"Text", + 'fd.tva_tx'=>"Numeric", 'fd.qty'=>"Numeric", 'fd.remise_percent'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.total_tva'=>"Numeric", + 'fd.product_type'=>'Numeric', 'fd.ref'=>'Text', 'fd.fk_product'=>'List:product:label', 'p.ref'=>'Text', 'p.label'=>'Text', 'project.ref'=>'Text', 'project.title'=>'Text' ); - $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.idprof5'=>'company','s.idprof6'=>'company','s.tva_intra'=>'company','ua1.login'=>'user', - 'ua2.login'=>'user','fd.rowid'=>'order_line','fd.description'=>"order_line",'fd.tva_tx'=>"order_line",'fd.qty'=>"order_line",'fd.remise_percent'=>"order_line", - 'fd.total_ht'=>"order_line",'fd.total_ttc'=>"order_line",'fd.total_tva'=>"order_line",'fd.product_type'=>'order_line','fd.ref'=>'order_line','fd.fk_product'=>'product', - 'p.ref'=>'product','p.label'=>'product','project.rowid'=>'project','project.ref'=>'project','project.title'=>'project' + $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.idprof5'=>'company', 's.idprof6'=>'company', 's.tva_intra'=>'company', 'ua1.login'=>'user', + 'ua2.login'=>'user', 'fd.rowid'=>'order_line', 'fd.description'=>"order_line", 'fd.tva_tx'=>"order_line", 'fd.qty'=>"order_line", 'fd.remise_percent'=>"order_line", + 'fd.total_ht'=>"order_line", 'fd.total_ttc'=>"order_line", 'fd.total_tva'=>"order_line", 'fd.product_type'=>'order_line', 'fd.ref'=>'order_line', 'fd.fk_product'=>'product', + 'p.ref'=>'product', 'p.label'=>'product', 'project.rowid'=>'project', 'project.ref'=>'project', 'project.title'=>'project' ); - $this->export_dependencies_array[$r]=array('order_line'=>'fd.rowid','product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them + $this->export_dependencies_array[$r] = array('order_line'=>'fd.rowid', 'product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them // Add extra fields object - $sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande_fournisseur' AND entity IN (0, ".$conf->entity.")"; - $resql=$this->db->query($sql); + $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande_fournisseur' AND entity IN (0, ".$conf->entity.")"; + $resql = $this->db->query($sql); if ($resql) // This can fail when class is used on old database (during migration for example) { - while ($obj=$this->db->fetch_object($resql)) + while ($obj = $this->db->fetch_object($resql)) { - $fieldname='extra.'.$obj->name; - $fieldlabel=ucfirst($obj->label); - $typeFilter="Text"; - switch($obj->type) + $fieldname = 'extra.'.$obj->name; + $fieldlabel = ucfirst($obj->label); + $typeFilter = "Text"; + switch ($obj->type) { case 'int': case 'double': case 'price': - $typeFilter="Numeric"; + $typeFilter = "Numeric"; break; case 'date': case 'datetime': - $typeFilter="Date"; + $typeFilter = "Date"; break; case 'boolean': - $typeFilter="Boolean"; + $typeFilter = "Boolean"; break; case 'sellist': - $tmp=''; - $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null - $tmpkey=array_keys($tmpparam['options']); - if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp=array_shift($tmpkey); - if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp; + $tmp = ''; + $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null + $tmpkey = array_keys($tmpparam['options']); + if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp = array_shift($tmpkey); + if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter = "List:".$tmp; break; } - $this->export_fields_array[$r][$fieldname]=$fieldlabel; - $this->export_TypeFields_array[$r][$fieldname]=$typeFilter; - $this->export_entities_array[$r][$fieldname]='order'; + $this->export_fields_array[$r][$fieldname] = $fieldlabel; + $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; + $this->export_entities_array[$r][$fieldname] = 'order'; } } // End add extra fields object // Add extra fields line - $sql="SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande_fournisseurdet' AND entity IN (0, ".$conf->entity.")"; - $resql=$this->db->query($sql); + $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande_fournisseurdet' AND entity IN (0, ".$conf->entity.")"; + $resql = $this->db->query($sql); if ($resql) // This can fail when class is used on old database (during migration for example) { - while ($obj=$this->db->fetch_object($resql)) + while ($obj = $this->db->fetch_object($resql)) { - $fieldname='extraline.'.$obj->name; - $fieldlabel=ucfirst($obj->label); - $typeFilter="Text"; - switch($obj->type) + $fieldname = 'extraline.'.$obj->name; + $fieldlabel = ucfirst($obj->label); + $typeFilter = "Text"; + switch ($obj->type) { case 'int': case 'double': case 'price': - $typeFilter="Numeric"; + $typeFilter = "Numeric"; break; case 'date': case 'datetime': - $typeFilter="Date"; + $typeFilter = "Date"; break; case 'boolean': - $typeFilter="Boolean"; + $typeFilter = "Boolean"; break; case 'sellist': - $tmp=''; - $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null + $tmp = ''; + $tmpparam = unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null if ($tmpparam['options'] && is_array($tmpparam['options'])) { - $tmpparam_param_key=array_keys($tmpparam['options']); - $tmp=array_shift($tmpparam_param_key); + $tmpparam_param_key = array_keys($tmpparam['options']); + $tmp = array_shift($tmpparam_param_key); } - if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp; + if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter = "List:".$tmp; break; } - $this->export_fields_array[$r][$fieldname]=$fieldlabel; - $this->export_TypeFields_array[$r][$fieldname]=$typeFilter; - $this->export_entities_array[$r][$fieldname]='order_line'; + $this->export_fields_array[$r][$fieldname] = $fieldlabel; + $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; + $this->export_entities_array[$r][$fieldname] = 'order_line'; } } // End add extra fields line - $this->export_sql_start[$r]='SELECT DISTINCT '; - $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'societe as s'; - if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid,'; - $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'commande_fournisseur as f'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'projet as project on (f.fk_projet = project.rowid)'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'user as ua1 ON ua1.rowid = f.fk_user_approve'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'user as ua2 ON ua2.rowid = f.fk_user_approve2'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'commande_fournisseur_extrafields as extra ON f.rowid = extra.fk_object,'; - $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'commande_fournisseurdet as fd'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'commande_fournisseurdet_extrafields as extraline ON fd.rowid = extraline.fk_object'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product as p on (fd.fk_product = p.rowid)'; - $this->export_sql_end[$r] .=' WHERE f.fk_soc = s.rowid AND f.rowid = fd.fk_commande'; - $this->export_sql_end[$r] .=' AND f.entity IN ('.getEntity('supplier_order').')'; - if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' AND sc.fk_user = '.$user->id; + $this->export_sql_start[$r] = 'SELECT DISTINCT '; + $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'societe as s'; + if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid,'; + $this->export_sql_end[$r] .= ' '.MAIN_DB_PREFIX.'commande_fournisseur as f'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as project on (f.fk_projet = project.rowid)'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'user as ua1 ON ua1.rowid = f.fk_user_approve'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'user as ua2 ON ua2.rowid = f.fk_user_approve2'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'commande_fournisseur_extrafields as extra ON f.rowid = extra.fk_object,'; + $this->export_sql_end[$r] .= ' '.MAIN_DB_PREFIX.'commande_fournisseurdet as fd'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'commande_fournisseurdet_extrafields as extraline ON fd.rowid = extraline.fk_object'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p on (fd.fk_product = p.rowid)'; + $this->export_sql_end[$r] .= ' WHERE f.fk_soc = s.rowid AND f.rowid = fd.fk_commande'; + $this->export_sql_end[$r] .= ' AND f.entity IN ('.getEntity('supplier_order').')'; + if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' AND sc.fk_user = '.$user->id; } @@ -638,19 +641,19 @@ class modFournisseur extends DolibarrModules $this->remove($options); //ODT template - $src=DOL_DOCUMENT_ROOT.'/install/doctemplates/supplier_orders/template_supplier_order.odt'; - $dirodt=DOL_DATA_ROOT.'/doctemplates/supplier_orders'; - $dest=$dirodt.'/template_supplier_order.odt'; + $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/supplier_orders/template_supplier_order.odt'; + $dirodt = DOL_DATA_ROOT.'/doctemplates/supplier_orders'; + $dest = $dirodt.'/template_supplier_order.odt'; - if (file_exists($src) && ! file_exists($dest)) + if (file_exists($src) && !file_exists($dest)) { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; dol_mkdir($dirodt); - $result=dol_copy($src, $dest, 0, 0); + $result = dol_copy($src, $dest, 0, 0); if ($result < 0) { $langs->load("errors"); - $this->error=$langs->trans('ErrorFailToCopyFile', $src, $dest); + $this->error = $langs->trans('ErrorFailToCopyFile', $src, $dest); return 0; } } diff --git a/htdocs/core/modules/modMrp.class.php b/htdocs/core/modules/modMrp.class.php index 1ca8e380aa4..73df7523843 100644 --- a/htdocs/core/modules/modMrp.class.php +++ b/htdocs/core/modules/modMrp.class.php @@ -62,7 +62,7 @@ class modMrp extends DolibarrModules // Used only if file README.md and README-LL.md not found. $this->descriptionlong = "Module to Manage Manufacturing Orders (MO)"; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' - $this->version = 'experimental'; + $this->version = 'dolibarr'; // Url to the file with your last numberversion of this module //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index 9c094aa122e..4f9558de8ae 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -7,6 +7,7 @@ * Copyright (C) 2012-2013 Juanjo Menent * Copyright (C) 2014 Christophe Battarel * Copyright (C) 2014 Cedric Gross + * Copyright (C) 2020 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 @@ -181,6 +182,7 @@ class modProduct extends DolibarrModules 'p.customcode'=>'CustomCode','p.fk_country'=>'IDCountry', 'p.accountancy_code_sell'=>"ProductAccountancySellCode", 'p.accountancy_code_sell_intra'=>"ProductAccountancySellIntraCode", 'p.accountancy_code_sell_export'=>"ProductAccountancySellExportCode", 'p.accountancy_code_buy'=>"ProductAccountancyBuyCode", + 'p.accountancy_code_buy_intra'=>"ProductAccountancyBuyIntraCode", 'p.accountancy_code_buy_export'=>"ProductAccountancyBuyExportCode", 'p.note'=>"NotePrivate",'p.note_public'=>'NotePublic', 'p.weight'=>"Weight", 'p.weight_units'=>"WeightUnits", 'p.length'=>"Length", 'p.length_units'=>"LengthUnits", 'p.width'=>"Width", 'p.width_units'=>"WidthUnits", 'p.height'=>"Height", 'p.height_units'=>"HeightUnits", 'p.surface'=>"Surface", 'p.surface_units'=>"SurfaceUnits", 'p.volume'=>"Volume", 'p.volume_units'=>"VolumeUnits", @@ -203,8 +205,9 @@ class modProduct extends DolibarrModules $this->export_TypeFields_array[$r]=array( 'p.ref'=>"Text",'p.label'=>"Text", 'p.fk_product_type'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean", - 'p.description'=>"Text",'p.url'=>"Text",'p.accountancy_code_sell'=>"Text", - 'p.accountancy_code_sell_intra'=>"Text",'p.accountancy_code_sell_export'=>"Text",'p.accountancy_code_buy'=>"Text", + 'p.description'=>"Text",'p.url'=>"Text", + 'p.accountancy_code_sell'=>"Text", 'p.accountancy_code_sell_intra'=>"Text",'p.accountancy_code_sell_export'=>"Text", + 'p.accountancy_code_buy'=>"Text", 'p.accountancy_code_buy_intra'=>"Text",'p.accountancy_code_buy_export'=>"Text", 'p.note'=>"Text",'p.note_public'=>"Text", 'p.weight'=>"Numeric",'p.length'=>"Numeric",'p.width'=>"Numeric",'p.height'=>"Numeric",'p.surface'=>"Numeric",'p.volume'=>"Numeric", 'p.customcode'=>'Text', @@ -315,6 +318,7 @@ class modProduct extends DolibarrModules 'p.rowid'=>"Id",'p.ref'=>"Ref",'p.label'=>"Label",'p.description'=>"Description",'p.url'=>"PublicUrl", 'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_sell_intra'=>"ProductAccountancySellIntraCode", 'p.accountancy_code_sell_export'=>"ProductAccountancySellExportCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode", + 'p.accountancy_code_buy_intra'=>"ProductAccountancyBuyIntraCode",'p.accountancy_code_buy_export'=>"ProductAccountancyBuyExportCode", 'p.note'=>"NotePrivate",'p.note_public'=>'NotePublic', 'p.weight'=>"Weight",'p.length'=>"Length",'p.surface'=>"Surface",'p.volume'=>"Volume",'p.customcode'=>'CustomCode', 'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell", @@ -325,7 +329,8 @@ class modProduct extends DolibarrModules $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('pa.qty'=>'Qty','pa.incdec'=>'ComposedProductIncDecStock')); $this->export_TypeFields_array[$r]=array( 'p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.url'=>"Text", - 'p.accountancy_code_sell'=>"Text",'p.accountancy_code_sell_intra'=>"Text",'p.accountancy_code_sell_export'=>"Text",'p.accountancy_code_buy'=>"Text", + 'p.accountancy_code_sell'=>"Text",'p.accountancy_code_sell_intra'=>"Text",'p.accountancy_code_sell_export'=>"Text", + 'p.accountancy_code_buy'=>"Text",'p.accountancy_code_buy_intra'=>"Text",'p.accountancy_code_buy_export'=>"Text", 'p.note'=>"Text",'p.note_public'=>"Text", 'p.weight'=>"Numeric",'p.length'=>"Numeric",'p.surface'=>"Numeric",'p.volume'=>"Numeric",'p.customcode'=>'Text', 'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean", @@ -337,7 +342,8 @@ class modProduct extends DolibarrModules $this->export_entities_array[$r]=array( 'p.rowid'=>"virtualproduct",'p.ref'=>"virtualproduct",'p.label'=>"virtualproduct",'p.description'=>"virtualproduct",'p.url'=>"virtualproduct", 'p.accountancy_code_sell'=>'virtualproduct','p.accountancy_code_sell_intra'=>'virtualproduct','p.accountancy_code_sell_export'=>'virtualproduct', - 'p.accountancy_code_buy'=>'virtualproduct','p.note'=>"virtualproduct",'p.length'=>"virtualproduct", + 'p.accountancy_code_buy'=>'virtualproduct','p.accountancy_code_buy_intra'=>'virtualproduct','p.accountancy_code_buy_export'=>'virtualproduct', + 'p.note'=>"virtualproduct",'p.length'=>"virtualproduct", 'p.surface'=>"virtualproduct",'p.volume'=>"virtualproduct",'p.weight'=>"virtualproduct",'p.customcode'=>'virtualproduct', 'p.price_base_type'=>"virtualproduct",'p.price'=>"virtualproduct",'p.price_ttc'=>"virtualproduct",'p.tva_tx'=>"virtualproduct", 'p.tosell'=>"virtualproduct",'p.tobuy'=>"virtualproduct",'p.datec'=>"virtualproduct",'p.tms'=>"virtualproduct" @@ -384,6 +390,8 @@ class modProduct extends DolibarrModules 'p.accountancy_code_sell_intra' => "ProductAccountancySellIntraCode", 'p.accountancy_code_sell_export' => "ProductAccountancySellExportCode", 'p.accountancy_code_buy' => "ProductAccountancyBuyCode", + 'p.accountancy_code_buy_intra' => "ProductAccountancyBuyIntraCode", + 'p.accountancy_code_buy_export' => "ProductAccountancyBuyExportCode", 'p.note_public' => "NotePublic", 'p.note' => "NotePrivate", 'p.weight' => "Weight", @@ -533,6 +541,8 @@ class modProduct extends DolibarrModules 'p.accountancy_code_sell_intra' => "", 'p.accountancy_code_sell_export' => "", 'p.accountancy_code_buy' => "", + 'p.accountancy_code_buy_intra' => "", + 'p.accountancy_code_buy_export' => "", 'p.weight' => "", 'p.weight_units' => 'kg', // Use a unit of measure from the dictionary. g/Kg/T etc....matches field "Short label" for unit type "weight" in table "' . MAIN_DB_PREFIX . 'c_units', 'p.length' => "", diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php index 5489e2b92ca..77d339da035 100644 --- a/htdocs/core/modules/modProjet.class.php +++ b/htdocs/core/modules/modProjet.class.php @@ -28,7 +28,7 @@ * \ingroup projet * \brief Fichier de description et activation du module Projet */ -include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; +include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php'; /** @@ -58,22 +58,22 @@ class modProjet extends DolibarrModules $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); $this->config_page_url = array("project.php@projet"); - $this->picto='project'; + $this->picto = 'project'; // Data directories to create when module is enabled $this->dirs = array("/projet/temp"); // Dependencies - $this->hidden = false; // A condition to hide module - $this->depends = array(); // List of module class names as string that must be enabled if this module is enabled - $this->requiredby = array(); // List of module ids to disable if this one is disabled - $this->conflictwith = array(); // List of module class names as string this module is in conflict with - $this->phpmin = array(5,4); // Minimum version of PHP required by module + $this->hidden = false; // A condition to hide module + $this->depends = array(); // List of module class names as string that must be enabled if this module is enabled + $this->requiredby = array(); // List of module ids to disable if this one is disabled + $this->conflictwith = array(); // List of module class names as string this module is in conflict with + $this->phpmin = array(5, 4); // Minimum version of PHP required by module $this->langfiles = array('projects'); // Constants $this->const = array(); - $r=0; + $r = 0; $this->const[$r][0] = "PROJECT_ADDON_PDF"; $this->const[$r][1] = "chaine"; @@ -139,7 +139,7 @@ class modProjet extends DolibarrModules // Boxes $this->boxes = array(); - $r=0; + $r = 0; $this->boxes[$r][1] = "box_project.php"; $r++; $this->boxes[$r][1] = "box_task.php"; @@ -148,7 +148,7 @@ class modProjet extends DolibarrModules // Permissions $this->rights = array(); $this->rights_class = 'projet'; - $r=0; + $r = 0; $r++; $this->rights[$r][0] = 41; // id de la permission @@ -205,34 +205,43 @@ class modProjet extends DolibarrModules // Menus //------- - $this->menu = 1; // This module add menu entries. They are coded into menu manager. + $this->menu = 1; // This module add menu entries. They are coded into menu manager. //Exports //-------- - $r=1; + $r = 1; - $this->export_code[$r]=$this->rights_class.'_'.$r; - $this->export_label[$r]='ProjectsAndTasksLines'; // Translation key (used only if key ExportDataset_xxx_z not found) - $this->export_permission[$r]=array(array("projet","export")); - $this->export_dependencies_array[$r]=array('projecttask'=>'pt.rowid', 'task_time'=>'ptt.rowid'); + $this->export_code[$r] = $this->rights_class.'_'.$r; + $this->export_label[$r] = 'ProjectsAndTasksLines'; // Translation key (used only if key ExportDataset_xxx_z not found) + $this->export_permission[$r] = array(array("projet", "export")); + $this->export_dependencies_array[$r] = array('projecttask'=>'pt.rowid', 'task_time'=>'ptt.rowid'); - $this->export_TypeFields_array[$r]=array('s.rowid'=>"List:societe:nom::thirdparty",'s.nom'=>'Text','s.address'=>'Text','s.zip'=>'Text','s.town'=>'Text','s.fk_pays'=>'List:c_country:label', - 's.phone'=>'Text','s.email'=>'Text','s.siren'=>'Text','s.siret'=>'Text','s.ape'=>'Text','s.idprof4'=>'Text','s.code_compta'=>'Text','s.code_compta_fournisseur'=>'Text', - 'p.rowid'=>"List:projet:ref::project",'p.ref'=>"Text",'p.title'=>"Text",'p.datec'=>"Date",'p.dateo'=>"Date",'p.datee'=>"Date",'p.fk_statut'=>'Status','cls.code'=>"Text",'p.opp_percent'=>'Numeric','p.opp_amount'=>'Numeric','p.description'=>"Text",'p.entity'=>'Numeric', - 'pt.rowid'=>'Numeric','pt.ref'=>'Text','pt.label'=>'Text','pt.dateo'=>"Date",'pt.datee'=>"Date",'pt.duration_effective'=>"Duree",'pt.planned_workload'=>"Numeric",'pt.progress'=>"Numeric",'pt.description'=>"Text", - 'ptt.rowid'=>'Numeric','ptt.task_date'=>'Date','ptt.task_duration'=>"Duree",'ptt.fk_user'=>"List:user:CONCAT(lastname,' ',firstname)",'ptt.note'=>"Text"); - $this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company','s.town'=>'company','s.fk_pays'=>'company', - 's.phone'=>'company','s.email'=>'company','s.siren'=>'company','s.siret'=>'company','s.ape'=>'company','s.idprof4'=>'company','s.code_compta'=>'company','s.code_compta_fournisseur'=>'company'); - - $this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','s.fk_pays'=>'Country', - 's.phone'=>'Phone','s.email'=>'Email','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.code_compta'=>'CustomerAccountancyCode','s.code_compta_fournisseur'=>'SupplierAccountancyCode', - 'p.rowid'=>"ProjectId",'p.ref'=>"RefProject",'p.title'=>'ProjectLabel', 'p.datec'=>"DateCreation",'p.dateo'=>"DateStart",'p.datee'=>"DateEnd",'p.fk_statut'=>'ProjectStatus','cls.code'=>'OpportunityStatus','p.opp_percent'=>'OpportunityProbability','p.opp_amount'=>'OpportunityAmount','p.description'=>"Description"); + $this->export_TypeFields_array[$r] = array( + 's.rowid'=>"List:societe:nom::thirdparty", 's.nom'=>'Text', 's.address'=>'Text', 's.zip'=>'Text', 's.town'=>'Text', 's.fk_pays'=>'List:c_country:label', + 's.phone'=>'Text', 's.email'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', 's.ape'=>'Text', 's.idprof4'=>'Text', 's.code_compta'=>'Text', 's.code_compta_fournisseur'=>'Text', + 'p.rowid'=>"List:projet:ref::project", 'p.ref'=>"Text", 'p.title'=>"Text", + 'p.usage_opportunity'=>'Boolean', 'p.usage_task'=>'Boolean', 'p.usage_bill_time'=>'Boolean', + 'p.datec'=>"Date", 'p.dateo'=>"Date", 'p.datee'=>"Date", 'p.fk_statut'=>'Status', 'cls.code'=>"Text", 'p.opp_percent'=>'Numeric', 'p.opp_amount'=>'Numeric', 'p.description'=>"Text", 'p.entity'=>'Numeric', + 'pt.rowid'=>'Numeric', 'pt.ref'=>'Text', 'pt.label'=>'Text', 'pt.dateo'=>"Date", 'pt.datee'=>"Date", 'pt.duration_effective'=>"Duree", 'pt.planned_workload'=>"Numeric", 'pt.progress'=>"Numeric", 'pt.description'=>"Text", + 'ptt.rowid'=>'Numeric', 'ptt.task_date'=>'Date', 'ptt.task_duration'=>"Duree", 'ptt.fk_user'=>"List:user:CONCAT(lastname,' ',firstname)", 'ptt.note'=>"Text" + ); + $this->export_entities_array[$r] = array( + 's.rowid'=>"company", 's.nom'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 's.fk_pays'=>'company', + 's.phone'=>'company', 's.email'=>'company', 's.siren'=>'company', 's.siret'=>'company', 's.ape'=>'company', 's.idprof4'=>'company', 's.code_compta'=>'company', 's.code_compta_fournisseur'=>'company' + ); + $this->export_fields_array[$r] = array( + 's.rowid'=>"IdCompany", 's.nom'=>'CompanyName', 's.address'=>'Address', 's.zip'=>'Zip', 's.town'=>'Town', 's.fk_pays'=>'Country', + 's.phone'=>'Phone', 's.email'=>'Email', 's.siren'=>'ProfId1', 's.siret'=>'ProfId2', 's.ape'=>'ProfId3', 's.idprof4'=>'ProfId4', 's.code_compta'=>'CustomerAccountancyCode', 's.code_compta_fournisseur'=>'SupplierAccountancyCode', + 'p.rowid'=>"ProjectId", 'p.ref'=>"RefProject", 'p.title'=>'ProjectLabel', + 'p.usage_opportunity'=>'ProjectFollowOpportunity', 'p.usage_task'=>'ProjectFollowTasks', 'p.usage_bill_time'=>'BillTime', + 'p.datec'=>"DateCreation", 'p.dateo'=>"DateStart", 'p.datee'=>"DateEnd", 'p.fk_statut'=>'ProjectStatus', 'cls.code'=>'OpportunityStatus', 'p.opp_percent'=>'OpportunityProbability', 'p.opp_amount'=>'OpportunityAmount', 'p.description'=>"Description" + ); // Add multicompany field - if (! empty($conf->global->MULTICOMPANY_ENTITY_IN_EXPORT_IF_SHARED)) + if (!empty($conf->global->MULTICOMPANY_ENTITY_IN_EXPORT_IF_SHARED)) { - $nbofallowedentities=count(explode(',', getEntity('project'))); // If project are shared, nb will be > 1 - if (! empty($conf->multicompany->enabled) && $nbofallowedentities > 1) $this->export_fields_array[$r]+=array('p.entity'=>'Entity'); + $nbofallowedentities = count(explode(',', getEntity('project'))); // If project are shared, nb will be > 1 + if (!empty($conf->multicompany->enabled) && $nbofallowedentities > 1) $this->export_fields_array[$r] += array('p.entity'=>'Entity'); } if (empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { @@ -242,62 +251,68 @@ class modProjet extends DolibarrModules } // Add fields for project - $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array()); + $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array()); // Add extra fields for project - $keyforselect='projet'; $keyforelement='project'; $keyforaliasextra='extra'; + $keyforselect = 'projet'; $keyforelement = 'project'; $keyforaliasextra = 'extra'; include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; // Add fields for tasks - $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('pt.rowid'=>'TaskId', 'pt.ref'=>'RefTask', 'pt.label'=>'LabelTask', 'pt.dateo'=>"TaskDateStart", 'pt.datee'=>"TaskDateEnd", 'pt.duration_effective'=>"DurationEffective", 'pt.planned_workload'=>"PlannedWorkload", 'pt.progress'=>"Progress", 'pt.description'=>"TaskDescription")); - $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('pt.rowid'=>'projecttask', 'pt.ref'=>'projecttask', 'pt.label'=>'projecttask', 'pt.dateo'=>"projecttask", 'pt.datee'=>"projecttask", 'pt.duration_effective'=>"projecttask", 'pt.planned_workload'=>"projecttask", 'pt.progress'=>"projecttask", 'pt.description'=>"projecttask")); + $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('pt.rowid'=>'TaskId', 'pt.ref'=>'RefTask', 'pt.label'=>'LabelTask', 'pt.dateo'=>"TaskDateStart", 'pt.datee'=>"TaskDateEnd", 'pt.duration_effective'=>"DurationEffective", 'pt.planned_workload'=>"PlannedWorkload", 'pt.progress'=>"Progress", 'pt.description'=>"TaskDescription")); + $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('pt.rowid'=>'projecttask', 'pt.ref'=>'projecttask', 'pt.label'=>'projecttask', 'pt.dateo'=>"projecttask", 'pt.datee'=>"projecttask", 'pt.duration_effective'=>"projecttask", 'pt.planned_workload'=>"projecttask", 'pt.progress'=>"projecttask", 'pt.description'=>"projecttask")); // Add extra fields for task - $keyforselect='projet_task'; $keyforelement='projecttask'; $keyforaliasextra='extra2'; + $keyforselect = 'projet_task'; $keyforelement = 'projecttask'; $keyforaliasextra = 'extra2'; include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; // End add extra fields - $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('ptt.rowid'=>'IdTaskTime','ptt.task_date'=>'TaskTimeDate','ptt.task_duration'=>"TimesSpent",'ptt.fk_user'=>"TaskTimeUser",'ptt.note'=>"TaskTimeNote")); - $this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('ptt.rowid'=>'task_time','ptt.task_date'=>'task_time','ptt.task_duration'=>"task_time",'ptt.fk_user'=>"task_time",'ptt.note'=>"task_time")); - - $this->export_sql_start[$r]='SELECT DISTINCT '; - $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'projet as p'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'projet_extrafields as extra ON p.rowid = extra.fk_object'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_lead_status as cls ON p.fk_opp_status = cls.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX."projet_task as pt ON p.rowid = pt.fk_projet"; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'projet_task_extrafields as extra2 ON pt.rowid = extra2.fk_object'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX."projet_task_time as ptt ON pt.rowid = ptt.fk_task"; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON p.fk_soc = s.rowid'; - $this->export_sql_end[$r] .=" WHERE p.entity IN (".getEntity('project').")"; + $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('ptt.rowid'=>'IdTaskTime', 'ptt.task_date'=>'TaskTimeDate', 'ptt.task_duration'=>"TimesSpent", 'ptt.fk_user'=>"TaskTimeUser", 'ptt.note'=>"TaskTimeNote")); + $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('ptt.rowid'=>'task_time', 'ptt.task_date'=>'task_time', 'ptt.task_duration'=>"task_time", 'ptt.fk_user'=>"task_time", 'ptt.note'=>"task_time")); + if (empty($conf->global->PROJECT_HIDE_TASKS)) { + $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('f.ref'=>"Billed")); + $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('f.ref'=>"task_time")); + } + $this->export_sql_start[$r] = 'SELECT DISTINCT '; + $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'projet as p'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet_extrafields as extra ON p.rowid = extra.fk_object'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_lead_status as cls ON p.fk_opp_status = cls.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX."projet_task as pt ON p.rowid = pt.fk_projet"; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet_task_extrafields as extra2 ON pt.rowid = extra2.fk_object'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX."projet_task_time as ptt ON pt.rowid = ptt.fk_task"; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON p.fk_soc = s.rowid'; + if (empty($conf->global->PROJECT_HIDE_TASKS)) { + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'facture as f ON ptt.invoice_id = f.rowid'; + } + $this->export_sql_end[$r] .= " WHERE p.entity IN (".getEntity('project').")"; // Import list of tasks if (empty($conf->global->PROJECT_HIDE_TASKS)) { $r++; - $this->import_code[$r]='tasksofprojects'; - $this->import_label[$r]='ImportDatasetTasks'; - $this->import_icon[$r]='task'; - $this->import_entities_array[$r]=array('t.fk_projet'=>'project'); // We define here only fields that use another icon that the one defined into import_icon - $this->import_tables_array[$r]=array('t'=>MAIN_DB_PREFIX.'projet_task','extra'=>MAIN_DB_PREFIX.'projet_task_extrafields'); // List of tables to insert into (insert done in same order) - $this->import_fields_array[$r]=array('t.fk_projet'=>'ProjectRef*','t.ref'=>'RefTask*','t.label'=>'LabelTask*','t.dateo'=>"DateStart",'t.datee'=>"DateEnd",'t.planned_workload'=>"PlannedWorkload",'t.progress'=>"Progress",'t.note_private'=>"NotePrivate",'t.note_public'=>"NotePublic",'t.datec'=>"DateCreation"); + $this->import_code[$r] = 'tasksofprojects'; + $this->import_label[$r] = 'ImportDatasetTasks'; + $this->import_icon[$r] = 'task'; + $this->import_entities_array[$r] = array('t.fk_projet'=>'project'); // We define here only fields that use another icon that the one defined into import_icon + $this->import_tables_array[$r] = array('t'=>MAIN_DB_PREFIX.'projet_task', 'extra'=>MAIN_DB_PREFIX.'projet_task_extrafields'); // List of tables to insert into (insert done in same order) + $this->import_fields_array[$r] = array('t.fk_projet'=>'ProjectRef*', 't.ref'=>'RefTask*', 't.label'=>'LabelTask*', 't.dateo'=>"DateStart", 't.datee'=>"DateEnd", 't.planned_workload'=>"PlannedWorkload", 't.progress'=>"Progress", 't.note_private'=>"NotePrivate", 't.note_public'=>"NotePublic", 't.datec'=>"DateCreation"); // Add extra fields - $sql="SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'projet_task' AND entity IN (0,".$conf->entity.")"; - $resql=$this->db->query($sql); + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'projet_task' AND entity IN (0,".$conf->entity.")"; + $resql = $this->db->query($sql); if ($resql) // This can fail when class is used on old database (during migration for example) { - while ($obj=$this->db->fetch_object($resql)) + while ($obj = $this->db->fetch_object($resql)) { - $fieldname='extra.'.$obj->name; - $fieldlabel=ucfirst($obj->label); - $this->import_fields_array[$r][$fieldname]=$fieldlabel.($obj->fieldrequired?'*':''); + $fieldname = 'extra.'.$obj->name; + $fieldlabel = ucfirst($obj->label); + $this->import_fields_array[$r][$fieldname] = $fieldlabel.($obj->fieldrequired ? '*' : ''); } } // End add extra fields - $this->import_fieldshidden_array[$r]=array('t.fk_user_creat'=>'user->id','extra.fk_object'=>'lastrowid-'.MAIN_DB_PREFIX.'projet_task'); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent) - $this->import_convertvalue_array[$r]=array( - 't.fk_projet'=>array('rule'=>'fetchidfromref','classfile'=>'/projet/class/project.class.php','class'=>'Project','method'=>'fetch','element'=>'Project'), + $this->import_fieldshidden_array[$r] = array('t.fk_user_creat'=>'user->id', 'extra.fk_object'=>'lastrowid-'.MAIN_DB_PREFIX.'projet_task'); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent) + $this->import_convertvalue_array[$r] = array( + 't.fk_projet'=>array('rule'=>'fetchidfromref', 'classfile'=>'/projet/class/project.class.php', 'class'=>'Project', 'method'=>'fetch', 'element'=>'Project'), 't.ref'=>array('rule'=>'getrefifauto') ); //$this->import_convertvalue_array[$r]=array('s.fk_soc'=>array('rule'=>'lastrowid',table='t'); - $this->import_regex_array[$r]=array('t.dateo'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$','t.datee'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$','t.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]( [0-9][0-9]:[0-9][0-9]:[0-9][0-9])?$'); - $this->import_examplevalues_array[$r]=array('t.fk_projet'=>'MyProjectRef','t.ref'=>"auto or TK2010-1234",'t.label'=>"My task",'t.progress'=>"0 (not started) to 100 (finished)",'t.datec'=>'1972-10-10','t.note_private'=>"My private note",'t.note_public'=>"My public note"); + $this->import_regex_array[$r] = array('t.dateo'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$', 't.datee'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$', 't.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]( [0-9][0-9]:[0-9][0-9]:[0-9][0-9])?$'); + $this->import_examplevalues_array[$r] = array('t.fk_projet'=>'MyProjectRef', 't.ref'=>"auto or TK2010-1234", 't.label'=>"My task", 't.progress'=>"0 (not started) to 100 (finished)", 't.datec'=>'1972-10-10', 't.note_private'=>"My private note", 't.note_public'=>"My public note"); } } @@ -312,54 +327,54 @@ class modProjet extends DolibarrModules */ public function init($options = '') { - global $conf,$langs; + global $conf, $langs; // Permissions $this->remove($options); //ODT template for project - $src=DOL_DOCUMENT_ROOT.'/install/doctemplates/projects/template_project.odt'; - $dirodt=DOL_DATA_ROOT.'/doctemplates/projects'; - $dest=$dirodt.'/template_project.odt'; + $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/projects/template_project.odt'; + $dirodt = DOL_DATA_ROOT.'/doctemplates/projects'; + $dest = $dirodt.'/template_project.odt'; - if (file_exists($src) && ! file_exists($dest)) + if (file_exists($src) && !file_exists($dest)) { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; dol_mkdir($dirodt); - $result=dol_copy($src, $dest, 0, 0); + $result = dol_copy($src, $dest, 0, 0); if ($result < 0) { $langs->load("errors"); - $this->error=$langs->trans('ErrorFailToCopyFile', $src, $dest); + $this->error = $langs->trans('ErrorFailToCopyFile', $src, $dest); return 0; } } //ODT template for tasks - $src=DOL_DOCUMENT_ROOT.'/install/doctemplates/tasks/template_task_summary.odt'; - $dirodt=DOL_DATA_ROOT.'/doctemplates/tasks'; - $dest=$dirodt.'/template_task_summary.odt'; + $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/tasks/template_task_summary.odt'; + $dirodt = DOL_DATA_ROOT.'/doctemplates/tasks'; + $dest = $dirodt.'/template_task_summary.odt'; - if (file_exists($src) && ! file_exists($dest)) + if (file_exists($src) && !file_exists($dest)) { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; dol_mkdir($dirodt); - $result=dol_copy($src, $dest, 0, 0); + $result = dol_copy($src, $dest, 0, 0); if ($result < 0) { $langs->load("errors"); - $this->error=$langs->trans('ErrorFailToCopyFile', $src, $dest); + $this->error = $langs->trans('ErrorFailToCopyFile', $src, $dest); return 0; } } $sql = array(); - $sql[] ="DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = '".$this->db->escape($this->const[3][2])."' AND type = 'task' AND entity = ".$conf->entity; - $sql[] ="INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('".$this->db->escape($this->const[3][2])."','task',".$conf->entity.")"; - $sql[] ="DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'beluga' AND type = 'project' AND entity = ".$conf->entity; - $sql[] ="INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('beluga','project',".$conf->entity.")"; - $sql[] ="DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'baleine' AND type = 'project' AND entity = ".$conf->entity; - $sql[] ="INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('baleine','project',".$conf->entity.")"; + $sql[] = "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = '".$this->db->escape($this->const[3][2])."' AND type = 'task' AND entity = ".$conf->entity; + $sql[] = "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('".$this->db->escape($this->const[3][2])."','task',".$conf->entity.")"; + $sql[] = "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'beluga' AND type = 'project' AND entity = ".$conf->entity; + $sql[] = "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('beluga','project',".$conf->entity.")"; + $sql[] = "DELETE FROM ".MAIN_DB_PREFIX."document_model WHERE nom = 'baleine' AND type = 'project' AND entity = ".$conf->entity; + $sql[] = "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity) VALUES('baleine','project',".$conf->entity.")"; return $this->_init($sql, $options); diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php index 4fb5cb175b0..822c6bf699f 100644 --- a/htdocs/core/modules/modService.class.php +++ b/htdocs/core/modules/modService.class.php @@ -4,6 +4,7 @@ * Copyright (C) 2004 Sebastien Di Cintio * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2020 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 @@ -148,6 +149,7 @@ class modService extends DolibarrModules 'p.customcode'=>'CustomCode','p.fk_country'=>'IDCountry', 'p.accountancy_code_sell'=>"ProductAccountancySellCode", 'p.accountancy_code_sell_intra'=>"ProductAccountancySellIntraCode", 'p.accountancy_code_sell_export'=>"ProductAccountancySellExportCode", 'p.accountancy_code_buy'=>"ProductAccountancyBuyCode", + 'p.accountancy_code_buy_intra'=>"ProductAccountancyBuyIntraCode", 'p.accountancy_code_buy_export'=>"ProductAccountancyBuyExportCode", 'p.note'=>"NotePrivate",'p.note_public'=>'NotePublic', 'p.weight'=>"Weight",'p.length'=>"Length",'p.width'=>"Width",'p.height'=>"Height",'p.surface'=>"Surface",'p.volume'=>"Volume", 'p.duration'=>"Duration", @@ -171,6 +173,7 @@ class modService extends DolibarrModules 'p.fk_product_type'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean", 'p.description'=>"Text",'p.url'=>"Text",'p.accountancy_code_sell'=>"Text", 'p.accountancy_code_sell_intra'=>"Text",'p.accountancy_code_sell_export'=>"Text",'p.accountancy_code_buy'=>"Text", + 'p.accountancy_code_buy_intra'=>"Text", 'p.accountancy_code_buy_export'=>"Text", 'p.note'=>"Text",'p.note_public'=>"Text", 'p.weight'=>"Numeric",'p.length'=>"Numeric",'p.width'=>"Numeric",'p.height'=>"Numeric",'p.surface'=>"Numeric",'p.volume'=>"Numeric", 'p.customcode'=>'Text', @@ -283,6 +286,7 @@ class modService extends DolibarrModules 'p.rowid'=>"Id",'p.ref'=>"Ref",'p.label'=>"Label",'p.description'=>"Description",'p.url'=>"PublicUrl", 'p.accountancy_code_sell'=>"ProductAccountancySellCode",'p.accountancy_code_sell_intra'=>"ProductAccountancySellIntraCode", 'p.accountancy_code_sell_export'=>"ProductAccountancySellExportCode",'p.accountancy_code_buy'=>"ProductAccountancyBuyCode", + 'p.accountancy_code_buy_intra'=>"ProductAccountancyBuyIntraCode",'p.accountancy_code_buy_export'=>"ProductAccountancyBuyExportCode", 'p.note'=>"NotePrivate",'p.note_public'=>'NotePublic', 'p.weight'=>"Weight",'p.length'=>"Length",'p.surface'=>"Surface",'p.volume'=>"Volume",'p.customcode'=>'CustomCode', 'p.price_base_type'=>"PriceBase",'p.price'=>"UnitPriceHT",'p.price_ttc'=>"UnitPriceTTC",'p.tva_tx'=>'VATRate','p.tosell'=>"OnSell", @@ -293,7 +297,8 @@ class modService extends DolibarrModules $this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('pa.qty'=>'Qty','pa.incdec'=>'ComposedProductIncDecStock')); $this->export_TypeFields_array[$r]=array( 'p.ref'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.url'=>"Text", - 'p.accountancy_code_sell'=>"Text",'p.accountancy_code_sell_intra'=>"Text",'p.accountancy_code_sell_export'=>"Text",'p.accountancy_code_buy'=>"Text", + 'p.accountancy_code_sell'=>"Text",'p.accountancy_code_sell_intra'=>"Text",'p.accountancy_code_sell_export'=>"Text", + 'p.accountancy_code_buy'=>"Text",'p.accountancy_code_buy_intra'=>"Text",'p.accountancy_code_buy_export'=>"Text", 'p.note'=>"Text",'p.note_public'=>"Text", 'p.weight'=>"Numeric",'p.length'=>"Numeric",'p.surface'=>"Numeric",'p.volume'=>"Numeric",'p.customcode'=>'Text', 'p.price_base_type'=>"Text",'p.price'=>"Numeric",'p.price_ttc'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean", @@ -305,7 +310,8 @@ class modService extends DolibarrModules $this->export_entities_array[$r]=array( 'p.rowid'=>"virtualproduct",'p.ref'=>"virtualproduct",'p.label'=>"virtualproduct",'p.description'=>"virtualproduct",'p.url'=>"virtualproduct", 'p.accountancy_code_sell'=>'virtualproduct','p.accountancy_code_sell_intra'=>'virtualproduct','p.accountancy_code_sell_export'=>'virtualproduct', - 'p.accountancy_code_buy'=>'virtualproduct','p.note'=>"virtualproduct",'p.length'=>"virtualproduct", + 'p.accountancy_code_buy'=>'virtualproduct','p.accountancy_code_buy_intra'=>'virtualproduct','p.accountancy_code_buy_export'=>'virtualproduct', + 'p.note'=>"virtualproduct",'p.length'=>"virtualproduct", 'p.surface'=>"virtualproduct",'p.volume'=>"virtualproduct",'p.weight'=>"virtualproduct",'p.customcode'=>'virtualproduct', 'p.price_base_type'=>"virtualproduct",'p.price'=>"virtualproduct",'p.price_ttc'=>"virtualproduct",'p.tva_tx'=>"virtualproduct", 'p.tosell'=>"virtualproduct",'p.tobuy'=>"virtualproduct",'p.datec'=>"virtualproduct",'p.tms'=>"virtualproduct" @@ -353,6 +359,8 @@ class modService extends DolibarrModules 'p.accountancy_code_sell_intra' => "ProductAccountancySellIntraCode", 'p.accountancy_code_sell_export' => "ProductAccountancySellExportCode", 'p.accountancy_code_buy' => "ProductAccountancyBuyCode", + 'p.accountancy_code_buy_intra' => "ProductAccountancyBuyIntraCode", + 'p.accountancy_code_buy_export' => "ProductAccountancyBuyExportCode", 'p.note_public' => "NotePublic", 'p.note' => "NotePrivate", 'p.weight' => "Weight", @@ -500,6 +508,8 @@ class modService extends DolibarrModules 'p.accountancy_code_sell_intra' => "", 'p.accountancy_code_sell_export' => "", 'p.accountancy_code_buy' => "", + 'p.accountancy_code_buy_intra' => "", + 'p.accountancy_code_buy_export' => "", 'p.weight' => "", 'p.weight_units' => 'kg', // Use a unit of measure from the dictionary. g/Kg/T etc....matches field "Short label" for unit type "weight" in table "' . MAIN_DB_PREFIX . 'c_units', 'p.length' => "", diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index 2cc525bd8aa..11c9f72c4c3 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -247,39 +247,39 @@ class modSociete extends DolibarrModules // Menus //------- - $this->menu = 1; // This module add menu entries. They are coded into menu manager. + $this->menu = 1; // This module add menu entries. They are coded into menu manager. // Exports //-------- - $r=0; + $r = 0; // Export list of third parties and attributes $r++; - $this->export_code[$r]=$this->rights_class.'_'.$r; - $this->export_label[$r]='ExportDataset_company_1'; - $this->export_icon[$r]='company'; - $this->export_permission[$r]=array(array("societe","export")); - $this->export_fields_array[$r]=array( - 's.rowid'=>"Id",'s.nom'=>"Name",'s.name_alias'=>"AliasNameShort",'s.status'=>"Status",'s.client'=>"Customer",'s.fournisseur'=>"Supplier",'s.datec'=>"DateCreation",'s.tms'=>"DateLastModification", - 's.code_client'=>"CustomerCode",'s.code_fournisseur'=>"SupplierCode",'s.code_compta'=>"AccountancyCode",'s.code_compta_fournisseur'=>"SupplierAccountancyCode", - 's.address'=>"Address",'s.zip'=>"Zip",'s.town'=>"Town",'d.nom'=>'State','c.label'=>"Country",'c.code'=>"CountryCode",'s.phone'=>"Phone",'s.fax'=>"Fax", - 's.url'=>"Url",'s.email'=>"Email",'s.default_lang'=>"DefaultLang",'s.siren'=>"ProfId1",'s.siret'=>"ProfId2",'s.ape'=>"ProfId3",'s.idprof4'=>"ProfId4", - 's.idprof5'=>"ProfId5",'s.idprof6'=>"ProfId6",'s.tva_intra'=>"VATIntraShort",'s.capital'=>"Capital",'s.note_private'=>"NotePrivate",'s.note_public'=>"NotePublic", - 't.libelle'=>"ThirdPartyType",'ce.code'=>"Staff","cfj.libelle"=>"JuridicalStatus",'s.fk_prospectlevel'=>'ProspectLevel', - 'st.code'=>'ProspectStatus','payterm.libelle'=>'PaymentConditions','paymode.libelle'=>'PaymentMode' + $this->export_code[$r] = $this->rights_class.'_'.$r; + $this->export_label[$r] = 'ExportDataset_company_1'; + $this->export_icon[$r] = 'company'; + $this->export_permission[$r] = array(array("societe", "export")); + $this->export_fields_array[$r] = array( + 's.rowid'=>"Id", 's.nom'=>"Name", 's.name_alias'=>"AliasNameShort", 's.status'=>"Status", 's.client'=>"Customer", 's.fournisseur'=>"Supplier", 's.datec'=>"DateCreation", 's.tms'=>"DateLastModification", + 's.code_client'=>"CustomerCode", 's.code_fournisseur'=>"SupplierCode", 's.code_compta'=>"AccountancyCode", 's.code_compta_fournisseur'=>"SupplierAccountancyCode", + 's.address'=>"Address", 's.zip'=>"Zip", 's.town'=>"Town", 'd.nom'=>'State', 'c.label'=>"Country", 'c.code'=>"CountryCode", 's.phone'=>"Phone", 's.fax'=>"Fax", + 's.url'=>"Url", 's.email'=>"Email", 's.default_lang'=>"DefaultLang", 's.siren'=>"ProfId1", 's.siret'=>"ProfId2", 's.ape'=>"ProfId3", 's.idprof4'=>"ProfId4", + 's.idprof5'=>"ProfId5", 's.idprof6'=>"ProfId6", 's.tva_intra'=>"VATIntraShort", 's.capital'=>"Capital", 's.note_private'=>"NotePrivate", 's.note_public'=>"NotePublic", + 't.libelle'=>"ThirdPartyType", 'ce.code'=>"Staff", "cfj.libelle"=>"JuridicalStatus", 's.fk_prospectlevel'=>'ProspectLevel', + 'st.code'=>'ProspectStatus', 'payterm.libelle'=>'PaymentConditions', 'paymode.libelle'=>'PaymentMode' ); - if (! empty($conf->global->SOCIETE_USEPREFIX)) $this->export_fields_array[$r]['s.prefix']='Prefix'; - if (! empty($conf->global->PRODUIT_MULTIPRICES)) $this->export_fields_array[$r]['s.price_level']='PriceLevel'; + if (!empty($conf->global->SOCIETE_USEPREFIX)) $this->export_fields_array[$r]['s.prefix'] = 'Prefix'; + if (!empty($conf->global->PRODUIT_MULTIPRICES)) $this->export_fields_array[$r]['s.price_level'] = 'PriceLevel'; // Add multicompany field - if (! empty($conf->global->MULTICOMPANY_ENTITY_IN_EXPORT_IF_SHARED)) + if (!empty($conf->global->MULTICOMPANY_ENTITY_IN_EXPORT_IF_SHARED)) { - $nbofallowedentities=count(explode(',', getEntity('societe'))); // If project are shared, nb will be > 1 - if (! empty($conf->multicompany->enabled) && $nbofallowedentities > 1) $this->export_fields_array[$r]+=array('s.entity'=>'Entity'); + $nbofallowedentities = count(explode(',', getEntity('societe'))); // If project are shared, nb will be > 1 + if (!empty($conf->multicompany->enabled) && $nbofallowedentities > 1) $this->export_fields_array[$r] += array('s.entity'=>'Entity'); } - $keyforselect='societe'; $keyforelement='company'; $keyforaliasextra='extra'; + $keyforselect = 'societe'; $keyforelement = 'company'; $keyforaliasextra = 'extra'; include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; - $this->export_fields_array[$r]+=array('u.login'=>'SaleRepresentativeLogin','u.firstname'=>'SaleRepresentativeFirstname', 'u.lastname'=>'SaleRepresentativeLastname'); + $this->export_fields_array[$r] += array('u.login'=>'SaleRepresentativeLogin', 'u.firstname'=>'SaleRepresentativeFirstname', 'u.lastname'=>'SaleRepresentativeLastname'); //$this->export_TypeFields_array[$r]=array( // 's.rowid'=>"List:societe:nom",'s.nom'=>"Text",'s.status'=>"Text",'s.client'=>"Boolean",'s.fournisseur'=>"Boolean",'s.datec'=>"Date",'s.tms'=>"Date", // 's.code_client'=>"Text",'s.code_fournisseur'=>"Text",'s.address'=>"Text",'s.zip'=>"Text",'s.town'=>"Text",'c.label'=>"List:c_country:label:label", @@ -288,101 +288,104 @@ class modSociete extends DolibarrModules // 't.libelle'=>"Text",'ce.code'=>"List:c_effectif:libelle:code","cfj.libelle"=>"Text",'s.fk_prospectlevel'=>'List:c_prospectlevel:label:code', // 's.fk_stcomm'=>'List:c_stcomm:libelle:code','d.nom'=>'List:c_departements:nom:rowid' //); - $this->export_TypeFields_array[$r]=array( - 's.rowid'=>"Numeric", 's.nom'=>"Text",'s.name_alias'=>"Text",'s.status'=>"Numeric",'s.client'=>"Numeric",'s.fournisseur'=>"Boolean",'s.datec'=>"Date",'s.tms'=>"Date", - 's.code_client'=>"Text",'s.code_fournisseur'=>"Text",'s.code_compta'=>"Text",'s.code_compta_fournisseur'=>"Text",'s.address'=>"Text",'s.zip'=>"Text", - 's.town'=>"Text",'c.label'=>"List:c_country:label:label",'c.code'=>"Text",'s.phone'=>"Text",'s.fax'=>"Text",'s.url'=>"Text",'s.email'=>"Text", - 's.default_lang'=>"Text",'s.siret'=>"Text",'s.siren'=>"Text",'s.ape'=>"Text",'s.idprof4'=>"Text",'s.idprof5'=>"Text",'s.idprof6'=>"Text", - 's.tva_intra'=>"Text",'s.capital'=>"Numeric",'s.note_private'=>"Text",'s.note_public'=>"Text",'t.libelle'=>"Text", - 'ce.code'=>"List:c_effectif:libelle:code","cfj.libelle"=>"Text",'s.fk_prospectlevel'=>'List:c_prospectlevel:label:code', - 'st.code'=>'List:c_stcomm:libelle:code','d.nom'=>'Text','u.login'=>'Text','u.firstname'=>'Text','u.lastname'=>'Text','payterm.libelle'=>'Text', - 'paymode.libelle'=>'Text','s.entity'=>'Numeric', + $this->export_TypeFields_array[$r] = array( + 's.rowid'=>"Numeric", 's.nom'=>"Text", 's.name_alias'=>"Text", 's.status'=>"Numeric", 's.client'=>"Numeric", 's.fournisseur'=>"Boolean", 's.datec'=>"Date", 's.tms'=>"Date", + 's.code_client'=>"Text", 's.code_fournisseur'=>"Text", 's.code_compta'=>"Text", 's.code_compta_fournisseur'=>"Text", 's.address'=>"Text", 's.zip'=>"Text", + 's.town'=>"Text", 'c.label'=>"List:c_country:label:label", 'c.code'=>"Text", 's.phone'=>"Text", 's.fax'=>"Text", 's.url'=>"Text", 's.email'=>"Text", + 's.default_lang'=>"Text", 's.siret'=>"Text", 's.siren'=>"Text", 's.ape'=>"Text", 's.idprof4'=>"Text", 's.idprof5'=>"Text", 's.idprof6'=>"Text", + 's.tva_intra'=>"Text", 's.capital'=>"Numeric", 's.note_private'=>"Text", 's.note_public'=>"Text", 't.libelle'=>"Text", + 'ce.code'=>"List:c_effectif:libelle:code", "cfj.libelle"=>"Text", 's.fk_prospectlevel'=>'List:c_prospectlevel:label:code', + 'st.code'=>'List:c_stcomm:libelle:code', 'd.nom'=>'Text', 'u.login'=>'Text', 'u.firstname'=>'Text', 'u.lastname'=>'Text', 'payterm.libelle'=>'Text', + 'paymode.libelle'=>'Text', 's.entity'=>'Numeric', 's.price_level'=>'Numeric' ); - $this->export_entities_array[$r]=array('u.login'=>'user','u.firstname'=>'user','u.lastname'=>'user'); // We define here only fields that use another picto - $this->export_examplevalues_array[$r]=array('s.client'=>'0 (no customer no prospect)/1 (customer)/2 (prospect)/3 (customer and prospect)','s.fournisseur'=>'0 (not a supplier) or 1 (supplier)'); - $this->export_sql_start[$r]='SELECT DISTINCT '; - $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'societe as s'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extra ON s.rowid = extra.fk_object'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as ce ON s.fk_effectif = ce.id'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON s.fk_forme_juridique = cfj.code'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON s.fk_departement = d.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_stcomm as st ON s.fk_stcomm = st.id'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid LEFT JOIN '.MAIN_DB_PREFIX.'user as u ON sc.fk_user = u.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as payterm ON s.cond_reglement = payterm.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as paymode ON s.mode_reglement = paymode.id'; - $this->export_sql_end[$r] .=' WHERE s.entity IN ('.getEntity('societe').')'; + $this->export_entities_array[$r] = array('u.login'=>'user', 'u.firstname'=>'user', 'u.lastname'=>'user'); // We define here only fields that use another picto + $this->export_examplevalues_array[$r] = array('s.client'=>'0 (no customer no prospect)/1 (customer)/2 (prospect)/3 (customer and prospect)', 's.fournisseur'=>'0 (not a supplier) or 1 (supplier)'); + $this->export_sql_start[$r] = 'SELECT DISTINCT '; + $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'societe as s'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extra ON s.rowid = extra.fk_object'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as ce ON s.fk_effectif = ce.id'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON s.fk_forme_juridique = cfj.code'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON s.fk_departement = d.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_stcomm as st ON s.fk_stcomm = st.id'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid LEFT JOIN '.MAIN_DB_PREFIX.'user as u ON sc.fk_user = u.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as payterm ON s.cond_reglement = payterm.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as paymode ON s.mode_reglement = paymode.id'; + $this->export_sql_end[$r] .= ' WHERE s.entity IN ('.getEntity('societe').')'; if (is_object($user) && empty($user->rights->societe->client->voir)) { - $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' '; - if (! empty($conf->global->SOCIETE_EXPORT_SUBORDINATES_CHILDS)) { + $this->export_sql_end[$r] .= ' AND (sc.fk_user = '.$user->id.' '; + if (!empty($conf->global->SOCIETE_EXPORT_SUBORDINATES_CHILDS)) { $subordinatesids = $user->getAllChildIds(); - $this->export_sql_end[$r] .=count($subordinatesids)>0 ? ' OR (sc.fk_user IN ('.implode(',', $subordinatesids).')' : ''; + $this->export_sql_end[$r] .= count($subordinatesids) > 0 ? ' OR (sc.fk_user IN ('.implode(',', $subordinatesids).')' : ''; } - $this->export_sql_end[$r] .=')'; + $this->export_sql_end[$r] .= ')'; } // Export list of contacts and attributes $r++; - $this->export_code[$r]=$this->rights_class.'_'.$r; - $this->export_label[$r]='ExportDataset_company_2'; - $this->export_icon[$r]='contact'; - $this->export_permission[$r]=array(array("societe","contact","export")); - $this->export_fields_array[$r]=array( - 'c.rowid'=>"IdContact",'c.civility'=>"CivilityCode",'c.lastname'=>'Lastname','c.firstname'=>'Firstname','c.poste'=>'PostOrFunction', - 'c.datec'=>"DateCreation",'c.tms'=>"DateLastModification",'c.priv'=>"ContactPrivate",'c.address'=>"Address",'c.zip'=>"Zip",'c.town'=>"Town", - 'd.nom'=>'State','co.label'=>"Country",'co.code'=>"CountryCode",'c.phone'=>"Phone",'c.fax'=>"Fax",'c.phone_mobile'=>"Mobile",'c.email'=>"EMail", + $this->export_code[$r] = $this->rights_class.'_'.$r; + $this->export_label[$r] = 'ExportDataset_company_2'; + $this->export_icon[$r] = 'contact'; + $this->export_permission[$r] = array(array("societe", "contact", "export")); + $this->export_fields_array[$r] = array( + 'c.rowid'=>"IdContact", 'c.civility'=>"CivilityCode", 'c.lastname'=>'Lastname', 'c.firstname'=>'Firstname', 'c.poste'=>'PostOrFunction', + 'c.datec'=>"DateCreation", 'c.tms'=>"DateLastModification", 'c.priv'=>"ContactPrivate", 'c.address'=>"Address", 'c.zip'=>"Zip", 'c.town'=>"Town", + 'd.nom'=>'State', 'co.label'=>"Country", 'co.code'=>"CountryCode", 'c.phone'=>"Phone", 'c.fax'=>"Fax", 'c.phone_mobile'=>"Mobile", 'c.email'=>"EMail", 'c.statut'=>"Status", - 's.rowid'=>"IdCompany",'s.nom'=>"CompanyName",'s.status'=>"Status",'s.code_client'=>"CustomerCode",'s.code_fournisseur'=>"SupplierCode", - 's.client'=>'Customer','s.fournisseur'=>'Supplier', - 's.address'=>'Address','s.zip'=>"Zip",'s.town'=>"Town",'s.phone'=>'Phone','s.email'=>"Email", + 's.rowid'=>"IdCompany", 's.nom'=>"CompanyName", 's.status'=>"Status", 's.code_client'=>"CustomerCode", 's.code_fournisseur'=>"SupplierCode", + 's.code_compta'=>"AccountancyCode", 's.code_compta_fournisseur'=>"SupplierAccountancyCode", + 's.client'=>'Customer', 's.fournisseur'=>'Supplier', + 's.address'=>'Address', 's.zip'=>"Zip", 's.town'=>"Town", 's.phone'=>'Phone', 's.email'=>"Email", 't.libelle'=>"ThirdPartyType" ); - $this->export_examplevalues_array[$r]=array('s.client'=>'0 (no customer no prospect)/1 (customer)/2 (prospect)/3 (customer and prospect)','s.fournisseur'=>'0 (not a supplier) or 1 (supplier)'); - $this->export_TypeFields_array[$r]=array( - 'c.civility'=>"List:c_civility:label:code",'c.lastname'=>'Text','c.firstname'=>'Text','c.poste'=>'Text','c.datec'=>"Date",'c.priv'=>"Boolean", - 'c.address'=>"Text",'c.zip'=>"Text",'c.town'=>"Text",'d.nom'=>'Text','co.label'=>"List:c_country:label:rowid",'co.code'=>"Text",'c.phone'=>"Text", - 'c.fax'=>"Text",'c.email'=>"Text", + $this->export_examplevalues_array[$r] = array('s.client'=>'0 (no customer no prospect)/1 (customer)/2 (prospect)/3 (customer and prospect)', 's.fournisseur'=>'0 (not a supplier) or 1 (supplier)'); + $this->export_TypeFields_array[$r] = array( + 'c.civility'=>"List:c_civility:label:code", 'c.lastname'=>'Text', 'c.firstname'=>'Text', 'c.poste'=>'Text', 'c.datec'=>"Date", 'c.priv'=>"Boolean", + 'c.address'=>"Text", 'c.zip'=>"Text", 'c.town'=>"Text", 'd.nom'=>'Text', 'co.label'=>"List:c_country:label:rowid", 'co.code'=>"Text", 'c.phone'=>"Text", + 'c.fax'=>"Text", 'c.email'=>"Text", 'c.statut'=>"Status", - 's.rowid'=>"List:societe:nom::thirdparty",'s.nom'=>"Text",'s.status'=>"Status",'s.code_client'=>"Text",'s.code_fournisseur'=>"Text", - 's.client'=>"Text",'s.fournisseur'=>"Text", - 's.address'=>"Text",'s.zip'=>"Text",'s.town'=>"Text",'s.phone'=>"Text",'s.email'=>"Text", + 's.rowid'=>"List:societe:nom::thirdparty", 's.nom'=>"Text", 's.status'=>"Status", 's.code_client'=>"Text", 's.code_fournisseur'=>"Text", + 's.code_compta'=>"Text", 's.code_compta_fournisseur'=>"Text", + 's.client'=>"Text", 's.fournisseur'=>"Text", + 's.address'=>"Text", 's.zip'=>"Text", 's.town'=>"Text", 's.phone'=>"Text", 's.email'=>"Text", 't.libelle'=>"Text" ); - $this->export_entities_array[$r]=array( - 's.rowid'=>"company",'s.nom'=>"company", 's.status'=>'company', 's.code_client'=>"company",'s.code_fournisseur'=>"company", 's.client'=>"company", - 's.fournisseur'=>"company", + $this->export_entities_array[$r] = array( + 's.rowid'=>"company", 's.nom'=>"company", 's.status'=>'company', 's.code_client'=>"company", 's.code_fournisseur'=>"company", + 's.code_compta'=>"company", 's.code_compta_fournisseur'=>"company", + 's.client'=>"company", 's.fournisseur'=>"company", 's.address'=>"company", 's.zip'=>"company", 's.town'=>"company", 's.phone'=>"company", 's.email'=>"company", 't.libelle'=>"company" - ); // We define here only fields that use another picto + ); // We define here only fields that use another picto if (empty($conf->fournisseur->enabled)) { unset($this->export_fields_array[$r]['s.code_fournisseur']); unset($this->export_entities_array[$r]['s.code_fournisseur']); } - $keyforselect='socpeople'; $keyforelement='contact'; $keyforaliasextra='extra'; + $keyforselect = 'socpeople'; $keyforelement = 'contact'; $keyforaliasextra = 'extra'; include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; - $keyforselect='societe'; $keyforelement='company'; $keyforaliasextra='extrasoc'; + $keyforselect = 'societe'; $keyforelement = 'company'; $keyforaliasextra = 'extrasoc'; include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; - $this->export_sql_start[$r]='SELECT DISTINCT '; - $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'socpeople as c'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON c.fk_soc = s.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extrasoc ON s.rowid = extrasoc.fk_object'; - if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON c.fk_departement = d.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as co ON c.fk_pays = co.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'socpeople_extrafields as extra ON extra.fk_object = c.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id'; - $this->export_sql_end[$r] .=' WHERE c.entity IN ('.getEntity('socpeople').')'; + $this->export_sql_start[$r] = 'SELECT DISTINCT '; + $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'socpeople as c'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON c.fk_soc = s.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extrasoc ON s.rowid = extrasoc.fk_object'; + if (is_object($user) && empty($user->rights->societe->client->voir)) $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON c.fk_departement = d.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as co ON c.fk_pays = co.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'socpeople_extrafields as extra ON extra.fk_object = c.rowid'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id'; + $this->export_sql_end[$r] .= ' WHERE c.entity IN ('.getEntity('socpeople').')'; if (is_object($user) && empty($user->rights->societe->client->voir)) { - $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' '; - if (! empty($conf->global->SOCIETE_EXPORT_SUBORDINATES_CHILDS)) { + $this->export_sql_end[$r] .= ' AND (sc.fk_user = '.$user->id.' '; + if (!empty($conf->global->SOCIETE_EXPORT_SUBORDINATES_CHILDS)) { $subordinatesids = $user->getAllChildIds(); - $this->export_sql_end[$r] .=count($subordinatesids)>0 ? ' OR (sc.fk_user IN ('.implode(',', $subordinatesids).')' : ''; + $this->export_sql_end[$r] .= count($subordinatesids) > 0 ? ' OR (sc.fk_user IN ('.implode(',', $subordinatesids).')' : ''; } - $this->export_sql_end[$r] .=')'; + $this->export_sql_end[$r] .= ')'; } @@ -684,7 +687,9 @@ class modSociete extends DolibarrModules 'sr.domiciliation' => "BankAccountDomiciliation", 'sr.proprio' => "BankAccountOwner", 'sr.owner_address' => "BankAccountOwnerAddress", - 'sr.default_rib' => 'Default' + 'sr.default_rib' => 'Default', + 'sr.rum' => 'RUM', + 'sr.type' => "Type ban is defaut", ); $this->import_convertvalue_array[$r] = array( @@ -711,7 +716,9 @@ class modSociete extends DolibarrModules 'sr.domiciliation' => 'bank branch address eg. "PARIS"', 'sr.proprio' => 'name on the bank account', 'sr.owner_address' => 'address of account holder', - 'sr.default_rib' => '1 (default account) / 0 (not default)' + 'sr.default_rib' => '1 (default account) / 0 (not default)', + 'sr.rum' => 'RUM code', + 'sr.type' => 'ban', ); // Import Company Sales representatives diff --git a/htdocs/core/modules/modTakePos.class.php b/htdocs/core/modules/modTakePos.class.php index 804ce8152ab..4671f40dd40 100644 --- a/htdocs/core/modules/modTakePos.class.php +++ b/htdocs/core/modules/modTakePos.class.php @@ -265,6 +265,10 @@ class modTakePos extends DolibarrModules */ public function init($options = '') { + global $conf,$db; + + dolibarr_set_const($db, "TAKEPOS_PRINT_METHOD", "browser", 'chaine', 0, '', $conf->entity); + $this->_load_tables('/takepos/sql/'); $sql = array(); diff --git a/htdocs/core/modules/modTicket.class.php b/htdocs/core/modules/modTicket.class.php index 8d7f16fcaf7..fbf560565ee 100644 --- a/htdocs/core/modules/modTicket.class.php +++ b/htdocs/core/modules/modTicket.class.php @@ -120,16 +120,16 @@ class modTicket extends DolibarrModules } $this->dictionaries = array( 'langs' => 'ticket', - 'tabname' => array(MAIN_DB_PREFIX . "c_ticket_type", MAIN_DB_PREFIX . "c_ticket_severity", MAIN_DB_PREFIX . "c_ticket_category"), - 'tablib' => array("TicketDictType", "TicketDictSeverity", "TicketDictCategory"), - 'tabsql' => array('SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticket_type as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticket_severity as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM ' . MAIN_DB_PREFIX . 'c_ticket_category as f'), - 'tabsqlsort' => array("pos ASC", "pos ASC", "pos ASC"), - 'tabfield' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"), - 'tabfieldvalue' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"), - 'tabfieldinsert' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"), - 'tabrowid' => array("rowid", "rowid", "rowid"), - 'tabcond' => array($conf->ticket->enabled, $conf->ticket->enabled, $conf->ticket->enabled), - 'tabhelp' => array(array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1"))), + 'tabname' => array(MAIN_DB_PREFIX."c_ticket_type", MAIN_DB_PREFIX."c_ticket_severity", MAIN_DB_PREFIX."c_ticket_category", MAIN_DB_PREFIX."c_ticket_resolution"), + 'tablib' => array("TicketDictType", "TicketDictSeverity", "TicketDictCategory", "TicketDictResolution"), + 'tabsql' => array('SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM '.MAIN_DB_PREFIX.'c_ticket_type as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM '.MAIN_DB_PREFIX.'c_ticket_severity as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM '.MAIN_DB_PREFIX.'c_ticket_category as f', 'SELECT f.rowid as rowid, f.code, f.pos, f.label, f.active, f.use_default FROM '.MAIN_DB_PREFIX.'c_ticket_resolution as f'), + 'tabsqlsort' => array("pos ASC", "pos ASC", "pos ASC", "pos ASC"), + 'tabfield' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"), + 'tabfieldvalue' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"), + 'tabfieldinsert' => array("pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default", "pos,code,label,use_default"), + 'tabrowid' => array("rowid", "rowid", "rowid", "rowid"), + 'tabcond' => array($conf->ticket->enabled, $conf->ticket->enabled, $conf->ticket->enabled, $conf->ticket->enabled), + 'tabhelp' => array(array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1")), array('code'=>$langs->trans("EnterAnyCode"), 'use_default'=>$langs->trans("Enter0or1"))), ); // Boxes diff --git a/htdocs/core/modules/modUser.class.php b/htdocs/core/modules/modUser.class.php index ca1a8d22209..c2ce0fec86f 100644 --- a/htdocs/core/modules/modUser.class.php +++ b/htdocs/core/modules/modUser.class.php @@ -314,7 +314,8 @@ class modUser extends DolibarrModules 'u.birth'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$' ); $this->import_examplevalues_array[$r] = array( - 'u.lastname'=>"Doe", 'u.firstname'=>'John', 'u.login'=>'jdoe', 'u.employee'=>'0 or 1', + 'u.lastname'=>"Doe", 'u.firstname'=>'John', 'u.login'=>'jdoe', 'u.employee'=>'0 or 1', 'u.job'=>'CTO', 'u.gender'=>'0 or 1', + 'u.pass_crypted'=>'Encrypted password', 'u.fk_soc'=>'0 (internal user) or company name (external user)', 'u.datec'=>dol_print_date(dol_now(), '%Y-%m-%d'), 'u.address'=>"61 jump street", 'u.zip'=>"123456", 'u.town'=>"Big town", 'u.fk_country'=>'US, FR, DE...', 'u.office_phone'=>"0101010101", 'u.office_fax'=>"0101010102", 'u.email'=>"test@mycompany.com", 'u.salary'=>"10000", 'u.note'=>"This is an example of note for record", 'u.datec'=>"2015-01-01 or 2015-01-01 12:30:00", diff --git a/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php b/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php index 398c8670a47..e276fe1f5f7 100644 --- a/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php +++ b/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php @@ -418,9 +418,11 @@ class doc_generic_mo_odt extends ModelePDFMo } if ($foundtagforlines) { + $linenumber = 0; foreach ($object->lines as $line) { - $tmparray = $this->get_substitutionarray_lines($line, $outputlangs); + $linenumber++; + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); // Call the ODTSubstitutionLine hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); diff --git a/htdocs/core/modules/oauth/github_oauthcallback.php b/htdocs/core/modules/oauth/github_oauthcallback.php index 919781baa93..4320481abb1 100644 --- a/htdocs/core/modules/oauth/github_oauthcallback.php +++ b/htdocs/core/modules/oauth/github_oauthcallback.php @@ -29,8 +29,8 @@ use OAuth\Common\Consumer\Credentials; use OAuth\OAuth2\Service\GitHub; // Define $urlwithroot -$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); -$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file +$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); +$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current @@ -70,8 +70,8 @@ $credentials = new Credentials( $currentUri->getAbsoluteUri() ); -$requestedpermissionsarray=array(); -if (GETPOST('state')) $requestedpermissionsarray=explode(',', GETPOST('state')); // Example: 'userinfo_email,userinfo_profile,cloud_print'. 'state' parameter is standard to retrieve some parameters back +$requestedpermissionsarray = array(); +if (GETPOST('state')) $requestedpermissionsarray = explode(',', GETPOST('state')); // Example: 'user'. 'state' parameter is standard to retrieve some parameters back if ($action != 'delete' && empty($requestedpermissionsarray)) { print 'Error, parameter state is not defined'; @@ -93,18 +93,17 @@ $langs->load("oauth"); * Actions */ - if ($action == 'delete') { $storage->clearToken('GitHub'); setEventMessages($langs->trans('TokenDeleted'), null, 'mesgs'); - header('Location: ' . $backtourl); + header('Location: '.$backtourl); exit(); } -if (! empty($_GET['code'])) // We are coming from oauth provider page +if (!empty($_GET['code'])) // We are coming from oauth provider page { // We should have //$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16)) @@ -133,12 +132,12 @@ if (! empty($_GET['code'])) // We are coming from oauth provider page // parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri) // has not the ending parameter to true like the Google class constructor. - setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token + setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token $backtourl = $_SESSION["backtourlsavedbeforeoauthjump"]; unset($_SESSION["backtourlsavedbeforeoauthjump"]); - header('Location: ' . $backtourl); + header('Location: '.$backtourl); exit(); } catch (Exception $e) { print $e->getMessage(); @@ -146,7 +145,7 @@ if (! empty($_GET['code'])) // We are coming from oauth provider page } else // If entry on page with no parameter, we arrive here { - $_SESSION["backtourlsavedbeforeoauthjump"]=$backtourl; + $_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl; // This may create record into oauth_state before the header redirect. // Creation of record with state in this tables depend on the Provider used (see its constructor). @@ -156,11 +155,11 @@ else // If entry on page with no parameter, we arrive here } else { - $url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated + $url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated } // we go on oauth provider authorization page - header('Location: ' . $url); + header('Location: '.$url); exit(); } diff --git a/htdocs/core/modules/oauth/google_oauthcallback.php b/htdocs/core/modules/oauth/google_oauthcallback.php index c9fd9869caf..68aba389f31 100644 --- a/htdocs/core/modules/oauth/google_oauthcallback.php +++ b/htdocs/core/modules/oauth/google_oauthcallback.php @@ -29,8 +29,8 @@ use OAuth\Common\Consumer\Credentials; use OAuth\OAuth2\Service\Google; // Define $urlwithroot -$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); -$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file +$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); +$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current @@ -70,8 +70,8 @@ $credentials = new Credentials( $currentUri->getAbsoluteUri() ); -$requestedpermissionsarray=array(); -if (GETPOST('state')) $requestedpermissionsarray=explode(',', GETPOST('state')); // Example: 'userinfo_email,userinfo_profile,cloud_print'. 'state' parameter is standard to retrieve some parameters back +$requestedpermissionsarray = array(); +if (GETPOST('state')) $requestedpermissionsarray = explode(',', GETPOST('state')); // Example: 'userinfo_email,userinfo_profile,cloud_print'. 'state' parameter is standard to store a hash value and can be used to retrieve some parameters back if ($action != 'delete' && empty($requestedpermissionsarray)) { print 'Error, parameter state is not defined'; @@ -105,11 +105,11 @@ if ($action == 'delete') setEventMessages($langs->trans('TokenDeleted'), null, 'mesgs'); - header('Location: ' . $backtourl); + header('Location: '.$backtourl); exit(); } -if (! empty($_GET['code'])) // We are coming from oauth provider page +if (!empty($_GET['code'])) // We are coming from oauth provider page { dol_syslog("We are coming from the oauth provider page"); //llxHeader('',$langs->trans("OAuthSetup")); @@ -130,12 +130,12 @@ if (! empty($_GET['code'])) // We are coming from oauth provider page $token = $apiService->requestAccessToken($_GET['code'], $state); - setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token + setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token $backtourl = $_SESSION["backtourlsavedbeforeoauthjump"]; unset($_SESSION["backtourlsavedbeforeoauthjump"]); - header('Location: ' . $backtourl); + header('Location: '.$backtourl); exit(); } catch (Exception $e) { print $e->getMessage(); @@ -143,7 +143,7 @@ if (! empty($_GET['code'])) // We are coming from oauth provider page } else // If entry on page with no parameter, we arrive here { - $_SESSION["backtourlsavedbeforeoauthjump"]=$backtourl; + $_SESSION["backtourlsavedbeforeoauthjump"] = $backtourl; // This may create record into oauth_state before the header redirect. // Creation of record with state in this tables depend on the Provider used (see its constructor). @@ -153,11 +153,11 @@ else // If entry on page with no parameter, we arrive here } else { - $url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated + $url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated } // we go on oauth provider authorization page - header('Location: ' . $url); + header('Location: '.$url); exit(); } diff --git a/htdocs/core/modules/payment/mod_payment_ant.php b/htdocs/core/modules/payment/mod_payment_ant.php index 612a411daed..a42b68b37e4 100644 --- a/htdocs/core/modules/payment/mod_payment_ant.php +++ b/htdocs/core/modules/payment/mod_payment_ant.php @@ -44,7 +44,7 @@ class mod_payment_ant extends ModeleNumRefPayments /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom='Ant'; diff --git a/htdocs/core/modules/payment/mod_payment_cicada.php b/htdocs/core/modules/payment/mod_payment_cicada.php index cd796fbcd19..9c40a575f47 100644 --- a/htdocs/core/modules/payment/mod_payment_cicada.php +++ b/htdocs/core/modules/payment/mod_payment_cicada.php @@ -45,7 +45,7 @@ class mod_payment_cicada extends ModeleNumRefPayments /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom='Cicada'; diff --git a/htdocs/core/modules/project/doc/pdf_baleine.modules.php b/htdocs/core/modules/project/doc/pdf_baleine.modules.php index 910ef3ec1cf..79941dba8d6 100644 --- a/htdocs/core/modules/project/doc/pdf_baleine.modules.php +++ b/htdocs/core/modules/project/doc/pdf_baleine.modules.php @@ -362,7 +362,13 @@ class pdf_baleine extends ModelePDFProjects else { // We found a page break - $showpricebeforepagebreak=0; + + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; + $forcedesconsamepage=1; if ($forcedesconsamepage) { diff --git a/htdocs/core/modules/project/doc/pdf_beluga.modules.php b/htdocs/core/modules/project/doc/pdf_beluga.modules.php index b26b46604ff..4072f22bf58 100644 --- a/htdocs/core/modules/project/doc/pdf_beluga.modules.php +++ b/htdocs/core/modules/project/doc/pdf_beluga.modules.php @@ -512,7 +512,13 @@ class pdf_beluga extends ModelePDFProjects else { // We found a page break - $showpricebeforepagebreak=0; + + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; + $forcedesconsamepage=1; if ($forcedesconsamepage) { diff --git a/htdocs/core/modules/project/doc/pdf_timespent.modules.php b/htdocs/core/modules/project/doc/pdf_timespent.modules.php index 27822545fa2..0c1eba3c9ac 100644 --- a/htdocs/core/modules/project/doc/pdf_timespent.modules.php +++ b/htdocs/core/modules/project/doc/pdf_timespent.modules.php @@ -293,7 +293,13 @@ class pdf_timespent extends ModelePDFProjects else { // We found a page break - $showpricebeforepagebreak=0; + + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; + $forcedesconsamepage=1; if ($forcedesconsamepage) { diff --git a/htdocs/core/modules/project/mod_project_simple.php b/htdocs/core/modules/project/mod_project_simple.php index d73ee22fbae..92f86a433c8 100644 --- a/htdocs/core/modules/project/mod_project_simple.php +++ b/htdocs/core/modules/project/mod_project_simple.php @@ -47,7 +47,7 @@ class mod_project_simple extends ModeleNumRefProjects /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom='Simple'; diff --git a/htdocs/core/modules/project/mod_project_universal.php b/htdocs/core/modules/project/mod_project_universal.php index 9bf0d313ae8..f833ec280d2 100644 --- a/htdocs/core/modules/project/mod_project_universal.php +++ b/htdocs/core/modules/project/mod_project_universal.php @@ -44,7 +44,7 @@ class mod_project_universal extends ModeleNumRefProjects /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom = 'Universal'; diff --git a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php index 386de7bfdd7..8a38450697f 100644 --- a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php +++ b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php @@ -57,7 +57,7 @@ class doc_generic_task_odt extends ModelePDFTask { /** * Issuer - * @var Company object that emits + * @var Societe Object that emits */ public $emetteur; diff --git a/htdocs/core/modules/project/task/mod_task_simple.php b/htdocs/core/modules/project/task/mod_task_simple.php index 65c7deb8edf..3f9debf9941 100644 --- a/htdocs/core/modules/project/task/mod_task_simple.php +++ b/htdocs/core/modules/project/task/mod_task_simple.php @@ -47,7 +47,7 @@ class mod_task_simple extends ModeleNumRefTask /** * @var string * @deprecated - * @see name + * @see $name */ public $nom='Simple'; diff --git a/htdocs/core/modules/project/task/mod_task_universal.php b/htdocs/core/modules/project/task/mod_task_universal.php index 1eecf94734b..b1c4f576a74 100644 --- a/htdocs/core/modules/project/task/mod_task_universal.php +++ b/htdocs/core/modules/project/task/mod_task_universal.php @@ -44,7 +44,7 @@ class mod_task_universal extends ModeleNumRefTask /** * @var string * @deprecated - * @see name + * @see $name */ public $nom = 'Universal'; diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php index fde5f08d318..33850c5d882 100644 --- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php +++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php @@ -456,9 +456,11 @@ class doc_generic_proposal_odt extends ModelePDFPropales } if ($foundtagforlines) { + $linenumber = 0; foreach ($object->lines as $line) { - $tmparray = $this->get_substitutionarray_lines($line, $outputlangs); + $linenumber++; + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); // Call the ODTSubstitutionLine hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php index fada0b8a142..0167d900b3f 100644 --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php @@ -500,7 +500,12 @@ class pdf_azur extends ModelePDFPropales $pdf->setPage($pageposbefore + 1); $curY = $tab_top_newpage; - $showpricebeforepagebreak = 0; + + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } if (isset($imglinesize['width']) && isset($imglinesize['height'])) @@ -541,7 +546,12 @@ class pdf_azur extends ModelePDFPropales else { // We found a page break - $showpricebeforepagebreak = 0; + + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak @@ -1091,28 +1101,28 @@ class pdf_azur extends ModelePDFPropales //Local tax 1 before VAT //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on') //{ - foreach($this->localtax1 as $localtax_type => $localtax_rate) + foreach ($this->localtax1 as $localtax_type => $localtax_rate) { - if (in_array((string) $localtax_type, array('1','3','5'))) continue; + if (in_array((string) $localtax_type, array('1', '3', '5'))) continue; - foreach($localtax_rate as $tvakey => $tvaval) + foreach ($localtax_rate as $tvakey => $tvaval) { - if ($tvakey!=0) // On affiche pas taux 0 + if ($tvakey != 0) // On affiche pas taux 0 { //$this->atleastoneratenotnull++; $index++; $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); - $tvacompl=''; + $tvacompl = ''; if (preg_match('/\*/', $tvakey)) { - $tvakey=str_replace('*', '', $tvakey); + $tvakey = str_replace('*', '', $tvakey); $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; } $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' '; - $totalvat.=vatrate(abs($tvakey), 1).$tvacompl; - $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + $totalvat .= vatrate(abs($tvakey), 1).$tvacompl; + $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1); $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); @@ -1123,13 +1133,13 @@ class pdf_azur extends ModelePDFPropales //Local tax 2 before VAT //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on') //{ - foreach($this->localtax2 as $localtax_type => $localtax_rate) + foreach ($this->localtax2 as $localtax_type => $localtax_rate) { - if (in_array((string) $localtax_type, array('1','3','5'))) continue; + if (in_array((string) $localtax_type, array('1', '3', '5'))) continue; - foreach($localtax_rate as $tvakey => $tvaval) + foreach ($localtax_rate as $tvakey => $tvaval) { - if ($tvakey!=0) // On affiche pas taux 0 + if ($tvakey != 0) // On affiche pas taux 0 { //$this->atleastoneratenotnull++; @@ -1138,15 +1148,15 @@ class pdf_azur extends ModelePDFPropales $index++; $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); - $tvacompl=''; + $tvacompl = ''; if (preg_match('/\*/', $tvakey)) { - $tvakey=str_replace('*', '', $tvakey); + $tvakey = str_replace('*', '', $tvakey); $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; } $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' '; - $totalvat.=vatrate(abs($tvakey), 1).$tvacompl; - $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + $totalvat .= vatrate(abs($tvakey), 1).$tvacompl; + $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1); $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); @@ -1182,11 +1192,11 @@ class pdf_azur extends ModelePDFPropales //Local tax 1 after VAT //if (! empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on') //{ - foreach($this->localtax1 as $localtax_type => $localtax_rate) + foreach ($this->localtax1 as $localtax_type => $localtax_rate) { - if (in_array((string) $localtax_type, array('2','4','6'))) continue; + if (in_array((string) $localtax_type, array('2', '4', '6'))) continue; - foreach($localtax_rate as $tvakey => $tvaval) + foreach ($localtax_rate as $tvakey => $tvaval) { if ($tvakey != 0) // On affiche pas taux 0 { @@ -1195,16 +1205,16 @@ class pdf_azur extends ModelePDFPropales $index++; $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); - $tvacompl=''; + $tvacompl = ''; if (preg_match('/\*/', $tvakey)) { - $tvakey=str_replace('*', '', $tvakey); + $tvakey = str_replace('*', '', $tvakey); $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; } $totalvat = $outputlangs->transcountrynoentities("TotalLT1", $mysoc->country_code).' '; - $totalvat.=vatrate(abs($tvakey), 1).$tvacompl; - $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + $totalvat .= vatrate(abs($tvakey), 1).$tvacompl; + $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1); $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); } @@ -1214,11 +1224,11 @@ class pdf_azur extends ModelePDFPropales //Local tax 2 after VAT //if (! empty($conf->global->FACTURE_LOCAL_TAX2_OPTION) && $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on') //{ - foreach($this->localtax2 as $localtax_type => $localtax_rate) + foreach ($this->localtax2 as $localtax_type => $localtax_rate) { - if (in_array((string) $localtax_type, array('2','4','6'))) continue; + if (in_array((string) $localtax_type, array('2', '4', '6'))) continue; - foreach($localtax_rate as $tvakey => $tvaval) + foreach ($localtax_rate as $tvakey => $tvaval) { // retrieve global local tax if ($tvakey != 0) // On affiche pas taux 0 @@ -1228,16 +1238,16 @@ class pdf_azur extends ModelePDFPropales $index++; $pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index); - $tvacompl=''; + $tvacompl = ''; if (preg_match('/\*/', $tvakey)) { - $tvakey=str_replace('*', '', $tvakey); + $tvakey = str_replace('*', '', $tvakey); $tvacompl = " (".$outputlangs->transnoentities("NonPercuRecuperable").")"; } $totalvat = $outputlangs->transcountrynoentities("TotalLT2", $mysoc->country_code).' '; - $totalvat.=vatrate(abs($tvakey), 1).$tvacompl; - $pdf->MultiCell($col2x-$col1x, $tab2_hl, $totalvat, 0, 'L', 1); + $totalvat .= vatrate(abs($tvakey), 1).$tvacompl; + $pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1); $pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index); $pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1); @@ -1466,7 +1476,7 @@ class pdf_azur extends ModelePDFPropales if ($this->emetteur->logo) { $logodir = $conf->mycompany->dir_output; - if (! empty($conf->mycompany->multidir_output[$object->entity])) $logodir = $conf->mycompany->multidir_output[$object->entity]; + if (!empty($conf->mycompany->multidir_output[$object->entity])) $logodir = $conf->mycompany->multidir_output[$object->entity]; if (empty($conf->global->MAIN_PDF_USE_LARGE_LOGO)) { $logo = $logodir.'/logos/thumbs/'.$this->emetteur->logo_small; @@ -1518,6 +1528,30 @@ class pdf_azur extends ModelePDFPropales $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R'); } + if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) + { + $object->fetch_projet(); + if (!empty($object->project->ref)) + { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R'); + } + } + + if (!empty($conf->global->PDF_SHOW_PROJECT)) + { + $object->fetch_projet(); + if (!empty($object->project->ref)) + { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->projet->ref), '', 'R'); + } + } + $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php index a14c087dbf7..c45db2f8380 100644 --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php @@ -418,6 +418,14 @@ class pdf_cyan extends ModelePDFPropales if (!empty($salerepobj->signature)) $notetoshow = dol_concatdesc($notetoshow, $salerepobj->signature); } } + + // Extrafields in note + $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); + if (!empty($extranote)) + { + $notetoshow = dol_concatdesc($notetoshow, $extranote); + } + if (!empty($conf->global->MAIN_ADD_CREATOR_IN_NOTE) && $object->user_author_id > 0) { $tmpuser = new User($this->db); @@ -556,9 +564,7 @@ class pdf_cyan extends ModelePDFPropales $this->pdfTabTitles($pdf, $tab_top, $tab_height, $outputlangs, $hidetop); $pdf->rollbackTransaction(true); - $iniY = $tab_top + $this->tabTitleHeight + 2; - $curY = $tab_top + $this->tabTitleHeight + 2; - $nexY = $tab_top + $this->tabTitleHeight + 2; + $nexY = $tab_top + $this->tabTitleHeight; // Loop on each lines $pageposbeforeprintlines = $pdf->getPage(); @@ -592,7 +598,12 @@ class pdf_cyan extends ModelePDFPropales $pdf->setPage($pageposbefore + 1); $curY = $tab_top_newpage; - $showpricebeforepagebreak = 0; + + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } @@ -608,15 +619,17 @@ class pdf_cyan extends ModelePDFPropales if ($this->getColumnStatus('desc')) { $pdf->startTransaction(); - pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc); + + $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); + if ($pageposafter > $pageposbefore) // There is a pagebreak { $pdf->rollbackTransaction(true); - $pageposafter = $pageposbefore; - //print $pageposafter.'-'.$pageposbefore;exit; + $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. - pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc); + + $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc); $pageposafter = $pdf->getPage(); $posyafter = $pdf->GetY(); @@ -634,7 +647,11 @@ class pdf_cyan extends ModelePDFPropales else { // We found a page break - $showpricebeforepagebreak = 0; + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak @@ -708,6 +725,17 @@ class pdf_cyan extends ModelePDFPropales $nexY = max($pdf->GetY(), $nexY); } + // Extrafields + if(!empty($object->lines[$i]->array_options)){ + foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue){ + if ($this->getColumnStatus($extrafieldColKey)) + { + $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey); + $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); + $nexY = max($pdf->GetY(), $nexY); + } + } + } $parameters = array( 'object' => $object, @@ -766,11 +794,11 @@ class pdf_cyan extends ModelePDFPropales $pdf->setPage($pageposafter); $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80))); //$pdf->SetDrawColor(190,190,200); - $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1); + $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY); $pdf->SetLineStyle(array('dash'=>0)); } - $nexY += 2; // Add space between lines + // Detect if some page were added automatically and output _tableau for past pages while ($pagenb < $pageposafter) @@ -1579,6 +1607,30 @@ class pdf_cyan extends ModelePDFPropales $pdf->MultiCell(100, 3, $outputlangs->transnoentities("RefCustomer")." : ".$outputlangs->convToOutputCharset($object->ref_client), '', 'R'); } + if (!empty($conf->global->PDF_SHOW_PROJECT_TITLE)) + { + $object->fetch_projet(); + if (!empty($object->project->ref)) + { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("Project")." : ".(empty($object->project->title) ? '' : $object->projet->title), '', 'R'); + } + } + + if (!empty($conf->global->PDF_SHOW_PROJECT)) + { + $object->fetch_projet(); + if (!empty($object->project->ref)) + { + $posy += 3; + $pdf->SetXY($posx, $posy); + $pdf->SetTextColor(0, 0, 60); + $pdf->MultiCell($w, 3, $outputlangs->transnoentities("RefProject")." : ".(empty($object->project->ref) ? '' : $object->projet->ref), '', 'R'); + } + } + $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); @@ -1788,7 +1840,7 @@ class pdf_cyan extends ModelePDFPropales // Default field style for content $this->defaultContentsFieldsStyle = array( 'align' => 'R', // R,C,L - 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left ); // Default field style for content @@ -1825,10 +1877,11 @@ class pdf_cyan extends ModelePDFPropales 'align' => 'L', // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label // 'label' => ' ', // the final label - 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + 'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left ), 'content' => array( 'align' => 'L', + 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left ), ); @@ -1919,7 +1972,7 @@ class pdf_cyan extends ModelePDFPropales $this->cols['discount']['status'] = true; } - $rank = $rank + 10; + $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100 $this->cols['totalexcltax'] = array( 'rank' => $rank, 'width' => 26, // in mm @@ -1930,6 +1983,11 @@ class pdf_cyan extends ModelePDFPropales 'border-left' => true, // add left line separator ); + // Add extrafields cols + if(!empty($object->lines)) { + $line = reset($object->lines); + $this->defineColumnExtrafield($line, $outputlangs, $hidedetails); + } $parameters = array( 'object' => $object, diff --git a/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php b/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php index 51438ed6bf8..89a532c2556 100644 --- a/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php +++ b/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php @@ -37,7 +37,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php'; class doc_generic_reception_odt extends ModelePdfReception { /** - * @var Company Issuer object that emits + * @var Societe Issuer object that emits */ public $emetteur; // Objet societe qui emet diff --git a/htdocs/core/modules/reception/doc/pdf_squille.modules.php b/htdocs/core/modules/reception/doc/pdf_squille.modules.php index 125c56960ca..f1c2eba89e4 100644 --- a/htdocs/core/modules/reception/doc/pdf_squille.modules.php +++ b/htdocs/core/modules/reception/doc/pdf_squille.modules.php @@ -374,7 +374,12 @@ class pdf_squille extends ModelePdfReception $pdf->setPage($pageposbefore + 1); $curY = $tab_top_newpage; - $showpricebeforepagebreak = 0; + + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } if (isset($imglinesize['width']) && isset($imglinesize['height'])) @@ -417,7 +422,12 @@ class pdf_squille extends ModelePdfReception else { // We found a page break - $showpricebeforepagebreak = 0; + + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak diff --git a/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php b/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php index 23609ad4384..d5ccf5dbd89 100644 --- a/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php +++ b/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php @@ -209,7 +209,7 @@ class doc_generic_stock_odt extends ModelePDFStock /** * Function to build a document on disk using the generic odt module. * - * @param Stock $object Object source to build document + * @param Entrepot $object Object source to build document * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file * @param int $hidedetails Do not show line details @@ -250,7 +250,7 @@ class doc_generic_stock_odt extends ModelePDFStock if (!is_object($object)) { $id = $object; - $object = new Stock($this->db); + $object = new Entrepot($this->db); $result = $object->fetch($id); if ($result < 0) { @@ -258,7 +258,8 @@ class doc_generic_stock_odt extends ModelePDFStock return -1; } } - $stockFournisseur = new StockFournisseur($this->db); + + $stockFournisseur = new ProductFournisseur($this->db); $supplierprices = $stockFournisseur->list_stock_fournisseur_price($object->id); $object->supplierprices = $supplierprices; diff --git a/htdocs/core/modules/stock/doc/pdf_standard.modules.php b/htdocs/core/modules/stock/doc/pdf_standard.modules.php index 97c0744c121..17071641817 100644 --- a/htdocs/core/modules/stock/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/stock/doc/pdf_standard.modules.php @@ -181,7 +181,7 @@ class pdf_standard extends ModelePDFStock /** * Function to build a document on disk using the generic odt module. * - * @param Stock $object Object source to build document + * @param Entrepot $object Object source to build document * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file * @param int $hidedetails Do not show line details @@ -383,7 +383,12 @@ class pdf_standard extends ModelePDFStock else { // We found a page break - $showpricebeforepagebreak=0; + + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak diff --git a/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php b/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php index 4f59c2510b4..362f17c7e9c 100644 --- a/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php +++ b/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php @@ -543,7 +543,12 @@ class pdf_stdmovement extends ModelePDFMovement else { // We found a page break - $showpricebeforepagebreak=0; + + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak diff --git a/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php b/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php index f318237a43e..a484343b1c0 100644 --- a/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php +++ b/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php @@ -428,7 +428,11 @@ class pdf_canelle extends ModelePDFSuppliersInvoices else { // We found a page break - $showpricebeforepagebreak=0; + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak diff --git a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php index 8708a2c01a2..7d2aafb4882 100644 --- a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php +++ b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_cactus.php @@ -47,7 +47,7 @@ class mod_facture_fournisseur_cactus extends ModeleNumRefSuppliersInvoices /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom='Cactus'; diff --git a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php index 85eb6673124..39360550d8c 100644 --- a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php +++ b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php @@ -50,7 +50,7 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom='Tulip'; diff --git a/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php b/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php index c71fe8f59ec..d7f48915308 100644 --- a/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php +++ b/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php @@ -421,9 +421,11 @@ class doc_generic_supplier_order_odt extends ModelePDFSuppliersOrders } if ($foundtagforlines) { + $linenumber = 0; foreach ($object->lines as $line) { - $tmparray = $this->get_substitutionarray_lines($line, $outputlangs); + $linenumber++; + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); // Call the ODTSubstitutionLine hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); diff --git a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php index 2a2916cf253..2d3c766a7c2 100644 --- a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php +++ b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php @@ -369,6 +369,13 @@ class pdf_cornas extends ModelePDFSuppliersOrders // Affiche notes $notetoshow = empty($object->note_public) ? '' : $object->note_public; + // Extrafields in note + $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); + if (!empty($extranote)) + { + $notetoshow = dol_concatdesc($notetoshow, $extranote); + } + $pagenb = $pdf->getPage(); if ($notetoshow) { @@ -489,9 +496,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders $height_note = 0; } - $iniY = $tab_top + 7; - $curY = $tab_top + 7; - $nexY = $tab_top + 7; + $nexY = $tab_top + 5; // Use new auto collum system $this->prepareArrayColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref); @@ -526,7 +531,12 @@ class pdf_cornas extends ModelePDFSuppliersOrders $pdf->setPage($pageposbefore + 1); $curY = $tab_top_newpage; - $showpricebeforepagebreak = 0; + + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } if (!empty($imglinesize['width']) && !empty($imglinesize['height'])) @@ -543,15 +553,15 @@ class pdf_cornas extends ModelePDFSuppliersOrders if ($this->getColumnStatus('desc')) { $pdf->startTransaction(); - pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc); + $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc, 1); + $pageposafter = $pdf->getPage(); if ($pageposafter > $pageposbefore) // There is a pagebreak { $pdf->rollbackTransaction(true); - $pageposafter = $pageposbefore; - //print $pageposafter.'-'.$pageposbefore;exit; - $pdf->setPageOrientation('', 1, $heightforfooter); // The only function to edit the bottom margin of current page to set it. - pdf_writelinedesc($pdf, $object, $i, $outputlangs, $this->getColumnContentWidth('desc'), 3, $this->getColumnContentXStart('desc'), $curY, $hideref, $hidedesc); + + $this->printColDescContent($pdf, $curY, 'desc', $object, $i, $outputlangs, $hideref, $hidedesc, 1); + $pageposafter = $pdf->getPage(); $posyafter = $pdf->GetY(); if ($posyafter > ($this->page_hauteur - ($heightforfooter + $heightforfreetext + $heightforinfotot))) // There is no space left for total+free text @@ -567,7 +577,11 @@ class pdf_cornas extends ModelePDFSuppliersOrders else { // We found a page break - $showpricebeforepagebreak = 0; + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak @@ -640,6 +654,17 @@ class pdf_cornas extends ModelePDFSuppliersOrders $nexY = max($pdf->GetY(), $nexY); } + // Extrafields + if(!empty($object->lines[$i]->array_options)){ + foreach ($object->lines[$i]->array_options as $extrafieldColKey => $extrafieldValue){ + if ($this->getColumnStatus($extrafieldColKey)) + { + $extrafieldValue = $this->getExtrafieldContent($object->lines[$i], $extrafieldColKey); + $this->printStdColumnContent($pdf, $curY, $extrafieldColKey, $extrafieldValue); + $nexY = max($pdf->GetY(), $nexY); + } + } + } $parameters = array( 'object' => $object, @@ -697,12 +722,10 @@ class pdf_cornas extends ModelePDFSuppliersOrders $pdf->setPage($pageposafter); $pdf->SetLineStyle(array('dash'=>'1,1', 'color'=>array(80, 80, 80))); //$pdf->SetDrawColor(190,190,200); - $pdf->line($this->marge_gauche, $nexY + 1, $this->page_largeur - $this->marge_droite, $nexY + 1); + $pdf->line($this->marge_gauche, $nexY, $this->page_largeur - $this->marge_droite, $nexY); $pdf->SetLineStyle(array('dash'=>0)); } - $nexY += 2; // Add space between lines - // Detect if some page were added automatically and output _tableau for past pages while ($pagenb < $pageposafter) { @@ -1456,7 +1479,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders // Default field style for content $this->defaultContentsFieldsStyle = array( 'align' => 'R', // R,C,L - 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + 'padding' => array(1, 0.5, 1, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left ); // Default field style for content @@ -1493,10 +1516,11 @@ class pdf_cornas extends ModelePDFSuppliersOrders 'align' => 'L', // 'textkey' => 'yourLangKey', // if there is no label, yourLangKey will be translated to replace label // 'label' => ' ', // the final label - 'padding' => array(0.5, 0.5, 0.5, 0.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left + 'padding' => array(0.5, 1, 0.5, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left ), 'content' => array( 'align' => 'L', + 'padding' => array(1, 0.5, 1, 1.5), // Like css 0 => top , 1 => right, 2 => bottom, 3 => left ), ); @@ -1587,7 +1611,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders $this->cols['discount']['status'] = true; } - $rank = $rank + 10; + $rank = $rank + 1000; // add a big offset to be sure is the last col because default extrafield rank is 100 $this->cols['totalexcltax'] = array( 'rank' => $rank, 'width' => 26, // in mm @@ -1598,6 +1622,11 @@ class pdf_cornas extends ModelePDFSuppliersOrders 'border-left' => true, // add left line separator ); + // Add extrafields cols + if(!empty($object->lines)) { + $line = reset($object->lines); + $this->defineColumnExtrafield($line, $outputlangs, $hidedetails); + } $parameters = array( 'object' => $object, @@ -1621,230 +1650,4 @@ class pdf_cornas extends ModelePDFSuppliersOrders $this->cols = $hookmanager->resArray; } } - - /* - * - * DEBUT PARTIE NORMALEMENT DANS LA CLASSE CommonDocGenerator - * - * - */ - - /** - * uasort callback function to Sort columns fields - * - * @param array $a PDF lines array fields configs - * @param array $b PDF lines array fields configs - * @return int Return compare result - */ - public function columnSort($a, $b) - { - if (empty($a['rank'])) { $a['rank'] = 0; } - if (empty($b['rank'])) { $b['rank'] = 0; } - if ($a['rank'] == $b['rank']) { - return 0; - } - return ($a['rank'] > $b['rank']) ? -1 : 1; - } - - /** - * Prepare Array Column Field - * - * @param object $object common object - * @param Translate $outputlangs langs - * @param int $hidedetails Do not show line details - * @param int $hidedesc Do not show desc - * @param int $hideref Do not show ref - * @return null - */ - public function prepareArrayColumnField($object, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0) - { - global $conf; - - $this->defineColumnField($object, $outputlangs, $hidedetails, $hidedesc, $hideref); - - // Sorting - uasort($this->cols, array($this, 'columnSort')); - - // Positionning - $curX = $this->page_largeur - $this->marge_droite; // start from right - - // Array width - $arrayWidth = $this->page_largeur - $this->marge_droite - $this->marge_gauche; - - // Count flexible column - $totalDefinedColWidth = 0; - $countFlexCol = 0; - foreach ($this->cols as $colKey => &$colDef) - { - if (!$this->getColumnStatus($colKey)) continue; // continue if disabled - - if (!empty($colDef['scale'])) { - // In case of column widht is defined by percentage - $colDef['width'] = abs($arrayWidth * $colDef['scale'] / 100); - } - - if (empty($colDef['width'])) { - $countFlexCol++; - } - else { - $totalDefinedColWidth += $colDef['width']; - } - } - - foreach ($this->cols as $colKey => &$colDef) - { - // setting empty conf with default - if (!empty($colDef['title'])) { - $colDef['title'] = array_replace($this->defaultTitlesFieldsStyle, $colDef['title']); - } - else { - $colDef['title'] = $this->defaultTitlesFieldsStyle; - } - - // setting empty conf with default - if (!empty($colDef['content'])) { - $colDef['content'] = array_replace($this->defaultContentsFieldsStyle, $colDef['content']); - } - else { - $colDef['content'] = $this->defaultContentsFieldsStyle; - } - - if ($this->getColumnStatus($colKey)) - { - // In case of flexible column - if (empty($colDef['width'])) { - $colDef['width'] = abs(($arrayWidth - $totalDefinedColWidth)) / $countFlexCol; - } - - // Set positions - $lastX = $curX; - $curX = $lastX - $colDef['width']; - $colDef['xStartPos'] = $curX; - $colDef['xEndPos'] = $lastX; - } - } - } - - /** - * get column content width from column key - * - * @param string $colKey the column key - * @return float width in mm - */ - public function getColumnContentWidth($colKey) - { - $colDef = $this->cols[$colKey]; - return $colDef['width'] - $colDef['content']['padding'][3] - $colDef['content']['padding'][1]; - } - - - /** - * get column content X (abscissa) left position from column key - * - * @param string $colKey the column key - * @return float X position in mm - */ - public function getColumnContentXStart($colKey) - { - $colDef = $this->cols[$colKey]; - return $colDef['xStartPos'] + $colDef['content']['padding'][3]; - } - - /** - * get column position rank from column key - * - * @param string $colKey the column key - * @return int rank on success and -1 on error - */ - public function getColumnRank($colKey) - { - if (!isset($this->cols[$colKey]['rank'])) return -1; - return $this->cols[$colKey]['rank']; - } - - /** - * get column position rank from column key - * - * @param string $newColKey the new column key - * @param array $defArray a single column definition array - * @param string $targetCol target column used to place the new column beside - * @param bool $insertAfterTarget insert before or after target column ? - * @return int new rank on success and -1 on error - */ - public function insertNewColumnDef($newColKey, $defArray, $targetCol = false, $insertAfterTarget = false) - { - // prepare wanted rank - $rank = -1; - - // try to get rank from target column - if (!empty($targetCol)) { - $rank = $this->getColumnRank($targetCol); - if ($rank >= 0 && $insertAfterTarget) { $rank++; } - } - - // get rank from new column definition - if ($rank < 0 && !empty($defArray['rank'])) { - $rank = $defArray['rank']; - } - - // error: no rank - if ($rank < 0) { return -1; } - - foreach ($this->cols as $colKey =>& $colDef) - { - if ($rank <= $colDef['rank']) - { - $colDef['rank'] = $colDef['rank'] + 1; - } - } - - $defArray['rank'] = $rank; - $this->cols[$newColKey] = $defArray; // array_replace is used to preserve keys - - return $rank; - } - - - /** - * print standard column content - * - * @param PDF $pdf pdf object - * @param float $curY curent Y position - * @param string $colKey the column key - * @param string $columnText column text - * @return int new rank on success and -1 on error - */ - public function printStdColumnContent($pdf, &$curY, $colKey, $columnText = '') - { - global $hookmanager; - - $parameters = array( - 'curY' =>& $curY, - 'columnText' => $columnText, - 'colKey' => $colKey - ); - $reshook = $hookmanager->executeHooks('printStdColumnContent', $parameters, $this); // Note that $action and $object may have been modified by hook - if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - if (!$reshook) - { - if (empty($columnText)) return; - $pdf->SetXY($this->getColumnContentXStart($colKey), $curY); // Set curent position - $colDef = $this->cols[$colKey]; - $pdf->MultiCell($this->getColumnContentWidth($colKey), 2, $columnText, '', $colDef['content']['align']); - } - } - - /** - * get column status from column key - * - * @param string $colKey the column key - * @return float width in mm - */ - public function getColumnStatus($colKey) - { - if (!empty($this->cols[$colKey]['status'])) { - return true; - } - else return false; - } } diff --git a/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php index 395e461e807..e4cb8f53e66 100644 --- a/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php +++ b/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php @@ -443,7 +443,12 @@ class pdf_muscadet extends ModelePDFSuppliersOrders $pdf->setPage($pageposbefore + 1); $curY = $tab_top_newpage; - $showpricebeforepagebreak = 0; + + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } if (!empty($imglinesize['width']) && !empty($imglinesize['height'])) @@ -490,7 +495,11 @@ class pdf_muscadet extends ModelePDFSuppliersOrders else { // We found a page break - $showpricebeforepagebreak = 0; + // Allows data in the first page if description is long enough to break in multiples pages + if(!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak diff --git a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php index ece2d8e5a7e..25fdd77991b 100644 --- a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php +++ b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_muguet.php @@ -45,7 +45,7 @@ class mod_commande_fournisseur_muguet extends ModeleNumRefSuppliersOrders /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom='Muguet'; diff --git a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php index 565e8cbd41d..72ba5f28186 100644 --- a/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php +++ b/htdocs/core/modules/supplier_order/mod_commande_fournisseur_orchidee.php @@ -46,7 +46,7 @@ class mod_commande_fournisseur_orchidee extends ModeleNumRefSuppliersOrders /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom='Orchidee'; diff --git a/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php b/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php index 2a6112db9e2..0ad8b391faf 100644 --- a/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php @@ -363,7 +363,11 @@ class pdf_standard extends ModelePDFSuppliersPayments else { // We found a page break - $showpricebeforepagebreak = 0; + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak diff --git a/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php b/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php index 92a2862143f..60d25792988 100644 --- a/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php +++ b/htdocs/core/modules/supplier_payment/mod_supplier_payment_brodator.php @@ -44,7 +44,7 @@ class mod_supplier_payment_brodator extends ModeleNumRefSupplierPayments /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom='Brodator'; diff --git a/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php b/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php index 1bc34d41bce..8a16475b383 100644 --- a/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php +++ b/htdocs/core/modules/supplier_payment/mod_supplier_payment_bronan.php @@ -45,7 +45,7 @@ class mod_supplier_payment_bronan extends ModeleNumRefSupplierPayments /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom='Bronan'; diff --git a/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php b/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php index 9c7305d1c07..3b4a39288ea 100644 --- a/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php +++ b/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php @@ -225,7 +225,7 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal /** * Function to build a document on disk using the generic odt module. * - * @param Propale $object Object source to build document + * @param Propal $object Object source to build document * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file * @param int $hidedetails Do not show line details @@ -445,9 +445,11 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal } if ($foundtagforlines) { + $linenumber = 0; foreach ($object->lines as $line) { - $tmparray = $this->get_substitutionarray_lines($line, $outputlangs); + $linenumber++; + $tmparray = $this->get_substitutionarray_lines($line, $outputlangs, $linenumber); complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); // Call the ODTSubstitutionLine hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); diff --git a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php index db5c5501d53..afaf4987e04 100644 --- a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php +++ b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php @@ -428,7 +428,12 @@ class pdf_aurore extends ModelePDFSupplierProposal $pdf->setPage($pageposbefore + 1); $curY = $tab_top_newpage; - $showpricebeforepagebreak = 0; + + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } if (!empty($imglinesize['width']) && !empty($imglinesize['height'])) @@ -478,7 +483,11 @@ class pdf_aurore extends ModelePDFSupplierProposal else { // We found a page break - $showpricebeforepagebreak = 0; + // Allows data in the first page if description is long enough to break in multiples pages + if (!empty($conf->global->MAIN_PDF_DATA_ON_FIRST_PAGE)) + $showpricebeforepagebreak = 1; + else + $showpricebeforepagebreak = 0; } } else // No pagebreak diff --git a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php index 8fa71cc1a3b..7bd15599e24 100644 --- a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php +++ b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_marbre.php @@ -47,7 +47,7 @@ class mod_supplier_proposal_marbre extends ModeleNumRefSupplierProposal /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom='Marbre'; diff --git a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php index bfaaa6b15fb..7cf4d295239 100644 --- a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php +++ b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php @@ -47,7 +47,7 @@ class mod_supplier_proposal_saphir extends ModeleNumRefSupplierProposal /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom='Saphir'; diff --git a/htdocs/core/modules/ticket/mod_ticket_simple.php b/htdocs/core/modules/ticket/mod_ticket_simple.php index dbec61b67bf..3245f7b8e84 100644 --- a/htdocs/core/modules/ticket/mod_ticket_simple.php +++ b/htdocs/core/modules/ticket/mod_ticket_simple.php @@ -46,7 +46,7 @@ class mod_ticket_simple extends ModeleNumRefTicket /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom='Simple'; diff --git a/htdocs/core/modules/ticket/mod_ticket_universal.php b/htdocs/core/modules/ticket/mod_ticket_universal.php index 5b5f5a55953..e6749bbb1f6 100644 --- a/htdocs/core/modules/ticket/mod_ticket_universal.php +++ b/htdocs/core/modules/ticket/mod_ticket_universal.php @@ -43,7 +43,7 @@ class mod_ticket_universal extends ModeleNumRefTicket /** * @var string Nom du modele * @deprecated - * @see name + * @see $name */ public $nom='Universal'; diff --git a/htdocs/core/photos_resize.php b/htdocs/core/photos_resize.php index 17c7cb9e974..dd59b20c964 100644 --- a/htdocs/core/photos_resize.php +++ b/htdocs/core/photos_resize.php @@ -38,6 +38,10 @@ $original_file = GETPOST("file"); $backtourl = GETPOST('backtourl'); $cancel = GETPOST('cancel', 'alpha'); +$file = GETPOST('file', 'alpha'); +$num = GETPOST('num', 'alpha'); // Used for document on bank statement + + // Security check if (empty($modulepart)) accessforbidden('Bad value for modulepart'); $accessallowed = 0; @@ -249,19 +253,25 @@ else { if (empty($backtourl)) { - if (in_array($modulepart, array('product', 'produit', 'service', 'produit|service'))) $backtourl = DOL_URL_ROOT."/product/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('expensereport'))) $backtourl = DOL_URL_ROOT."/expensereport/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('holiday'))) $backtourl = DOL_URL_ROOT."/holiday/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('member'))) $backtourl = DOL_URL_ROOT."/adherents/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('project'))) $backtourl = DOL_URL_ROOT."/projet/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('propal'))) $backtourl = DOL_URL_ROOT."/comm/propal/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('societe'))) $backtourl = DOL_URL_ROOT."/societe/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('tax'))) $backtourl = DOL_URL_ROOT."/compta/sociales/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('ticket'))) $backtourl = DOL_URL_ROOT."/ticket/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('user'))) $backtourl = DOL_URL_ROOT."/user/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('bank'))) $backtourl = DOL_URL_ROOT."/compta/bank/document.php?id=".$id.'&file='.urldecode($_POST["file"]); - elseif (in_array($modulepart, array('mrp'))) $backtourl = DOL_URL_ROOT."/mrp/mo_document.php?id=".$id.'&file='.urldecode($_POST["file"]); - else $backtourl = DOL_URL_ROOT."/".$modulepart."/".$modulepart."_document.php?id=".$id.'&file='.urldecode($_POST["file"]); + $regs = array(); + + if (in_array($modulepart, array('product', 'produit', 'service', 'produit|service'))) $backtourl = DOL_URL_ROOT."/product/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('expensereport'))) $backtourl = DOL_URL_ROOT."/expensereport/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('holiday'))) $backtourl = DOL_URL_ROOT."/holiday/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('member'))) $backtourl = DOL_URL_ROOT."/adherents/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('project'))) $backtourl = DOL_URL_ROOT."/projet/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('propal'))) $backtourl = DOL_URL_ROOT."/comm/propal/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('societe'))) $backtourl = DOL_URL_ROOT."/societe/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('tax'))) $backtourl = DOL_URL_ROOT."/compta/sociales/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('ticket'))) $backtourl = DOL_URL_ROOT."/ticket/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('user'))) $backtourl = DOL_URL_ROOT."/user/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('bank')) && preg_match('/\/statement\/([^\/]+)\//', $file, $regs)) { + $num = $regs[1]; + $backtourl = DOL_URL_ROOT."/compta/bank/account_statement_document.php?id=".$id.'&num='.urlencode($num).'&file='.urldecode($file); + } + elseif (in_array($modulepart, array('bank'))) $backtourl = DOL_URL_ROOT."/compta/bank/document.php?id=".$id.'&file='.urldecode($file); + elseif (in_array($modulepart, array('mrp'))) $backtourl = DOL_URL_ROOT."/mrp/mo_document.php?id=".$id.'&file='.urldecode($file); + else $backtourl = DOL_URL_ROOT."/".$modulepart."/".$modulepart."_document.php?id=".$id.'&file='.urldecode($file); } @@ -283,11 +293,11 @@ if ($cancel) } } -if ($action == 'confirm_resize' && (isset($_POST["file"]) != "") && (isset($_POST["sizex"]) != "") && (isset($_POST["sizey"]) != "")) +if ($action == 'confirm_resize' && GETPOSTISSET("file") && GETPOSTISSET("sizex") && GETPOSTISSET("sizey")) { $fullpath = $dir."/".$original_file; - $result = dol_imageResizeOrCrop($fullpath, 0, $_POST['sizex'], $_POST['sizey']); + $result = dol_imageResizeOrCrop($fullpath, 0, GETPOST('sizex', 'int'), GETPOST('sizey', 'int')); if ($result == $fullpath) { @@ -357,7 +367,7 @@ if ($action == 'confirm_crop') $fullpath = $dir."/".$original_file; //var_dump($_POST['w'].'x'.$_POST['h'].'-'.$_POST['x'].'x'.$_POST['y']);exit; - $result = dol_imageResizeOrCrop($fullpath, 1, $_POST['w'], $_POST['h'], $_POST['x'], $_POST['y']); + $result = dol_imageResizeOrCrop($fullpath, 1, GETPOST('w', 'int'), GETPOST('h', 'int'), GETPOST('x', 'int'), GETPOST('y', 'int')); if ($result == $fullpath) { @@ -445,7 +455,7 @@ print '
'."\n"; */ print ''."\n"; -print '
'; +print ''; print ''; print '
'; @@ -454,7 +464,7 @@ print $langs->trans("ResizeDesc").'
'; print $langs->trans("NewLength").': px   '.$langs->trans("or").'   '; print $langs->trans("NewHeight").': px  
'; -print ''; +print ''; print ''; print ''; print ''; @@ -497,7 +507,8 @@ if (!empty($conf->use_javascript_ajax)) print ''; print ''; print '
'; - print ''; + + print ''; print ''; print '
diff --git a/htdocs/core/tpl/admin_extrafields_add.tpl.php b/htdocs/core/tpl/admin_extrafields_add.tpl.php index 37ca5e1ec10..8859ce4ba9d 100644 --- a/htdocs/core/tpl/admin_extrafields_add.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_add.tpl.php @@ -148,7 +148,7 @@ $langs->load("modulebuilder");
- + + + diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php index 4063111a6fb..4dc47bbf031 100644 --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php @@ -165,6 +165,7 @@ $list=$extrafields->attributes[$elementtype]['list'][$attrname]; $totalizable = $extrafields->attributes[$elementtype]['totalizable'][$attrname]; $help=$extrafields->attributes[$elementtype]['help'][$attrname]; $entitycurrentorall=$extrafields->attributes[$elementtype]['entityid'][$attrname]; +$printable=$extrafields->attributes[$elementtype]['printable'][$attrname]; if((($type == 'select') || ($type == 'checkbox') || ($type == 'radio')) && is_array($param)) { @@ -261,8 +262,12 @@ else + + + @@ -270,7 +275,6 @@ else -
diff --git a/htdocs/core/modules/dons/html_cerfafr.modules.php b/htdocs/core/modules/dons/html_cerfafr.modules.php index bcda35459f6..4c025750f04 100644 --- a/htdocs/core/modules/dons/html_cerfafr.modules.php +++ b/htdocs/core/modules/dons/html_cerfafr.modules.php @@ -3,7 +3,7 @@ * Copyright (C) 2005-2006 Laurent Destailleur * Copyright (C) 2012 Regis Houssin * Copyright (C) 2012 Marcos García - * Copyright (C) 2014-2015 Alexandre Spangaro + * Copyright (C) 2014-2020 Alexandre Spangaro * Copyright (C) 2015 Benoit Bruchard * * This program is free software; you can redistribute it and/or modify @@ -42,11 +42,11 @@ class html_cerfafr extends ModeleDon */ public function __construct($db) { - global $conf,$langs; + global $conf, $langs; $this->db = $db; $this->name = "cerfafr"; - $this->description = $langs->trans('DonationsReceiptModel').' - fr_FR - Cerfa 11580*03'; + $this->description = $langs->trans('DonationsReceiptModel').' - fr_FR - Cerfa 11580*04'; // Dimension page for size A4 $this->type = 'html'; @@ -76,46 +76,46 @@ class html_cerfafr extends ModeleDon public function write_file($don, $outputlangs, $currency = '') { // phpcs:enable - global $user,$conf,$langs,$mysoc; + global $user, $conf, $langs, $mysoc; - $now=dol_now(); - $id = (! is_object($don)?$don:''); + $now = dol_now(); + $id = (!is_object($don) ? $don : ''); - if (! is_object($outputlangs)) $outputlangs=$langs; + if (!is_object($outputlangs)) $outputlangs = $langs; // Load traductions files required by page $outputlangs->loadLangs(array("main", "dict", "companies", "bills", "products", "donations")); $currency = !empty($currency) ? $currency : $conf->currency; - if (! empty($conf->don->dir_output)) + if (!empty($conf->don->dir_output)) { // Definition of the object don (for upward compatibility) - if (! is_object($don)) + if (!is_object($don)) { $don = new Don($this->db); - $ret=$don->fetch($id); - $id=$don->id; + $ret = $don->fetch($id); + $id = $don->id; } // Definition of $dir and $file - if (! empty($don->specimen)) + if (!empty($don->specimen)) { $dir = $conf->don->dir_output; - $file = $dir . "/SPECIMEN.html"; + $file = $dir."/SPECIMEN.html"; } else { $donref = dol_sanitizeFileName($don->ref); - $dir = $conf->don->dir_output . "/" . $donref; - $file = $dir . "/" . $donref . ".html"; + $dir = $conf->don->dir_output."/".$donref; + $file = $dir."/".$donref.".html"; } - if (! file_exists($dir)) + if (!file_exists($dir)) { if (dol_mkdir($dir) < 0) { - $this->error=$langs->trans("ErrorCanNotCreateDir", $dir); + $this->error = $langs->trans("ErrorCanNotCreateDir", $dir); return -1; } } @@ -133,13 +133,13 @@ class html_cerfafr extends ModeleDon } else $paymentmode = ''; - if ($don->modepaymentcode=='CHQ'){ + if ($don->modepaymentcode == 'CHQ') { $ModePaiement = ' Remise d\'espèces Chèque Virement, prélèvement, carte bancaire Remise d\'espèces Chèque Virement, prélèvement, carte bancaire Remise d\'espèces Chèque Virement, prélèvement, carte bancaire 200 du CGI 238 bis du CGI 885-0 V bis A du CGI 200 du CGI 238 bis du CGI 978 du CGI 200 du CGI 238 bis du CGI 885-0 V bis A du CGI 200 du CGI 238 bis du CGI 978 du CGI
trans("LabelOrTranslationKey"); ?>
trans("AttributeCode"); ?> (trans("AlphaNumOnlyLowerCharsAndNoSpace"); ?>)
trans("AttributeCode"); ?> (trans("AlphaNumOnlyLowerCharsAndNoSpace"); ?>)
trans("Type"); ?> selectarray('type', $type2label, GETPOST('type', 'alpha')); ?> @@ -196,6 +196,9 @@ $langs->load("modulebuilder");
textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc")); ?>
textwithpicto($langs->trans("DisplayOnPdf"), $langs->trans("DisplayOnPdfDesc")); ?> +
trans("Totalizable"); ?>>
trans("Required"); ?>>
trans("AlwaysEditable"); ?>>
textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc")); ?>
textwithpicto($langs->trans("DisplayOnPdf"), $langs->trans("DisplayOnPdfDesc")); ?> +
textwithpicto($langs->trans("Totalizable"), $langs->trans("TotalizableDesc")); ?>>
textwithpicto($langs->trans("HelpOnTooltip"), $langs->trans("HelpOnTooltipDesc")); ?>
trans("AllEntities"); ?>>
diff --git a/htdocs/core/tpl/admin_extrafields_view.tpl.php b/htdocs/core/tpl/admin_extrafields_view.tpl.php index 0ddd3f5a8fa..a59350d8678 100644 --- a/htdocs/core/tpl/admin_extrafields_view.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_view.tpl.php @@ -64,8 +64,9 @@ print '
'.$langs->trans("Unique").''.$langs->trans("Required").''.$langs->trans("AlwaysEditable").''.$form->textwithpicto($langs->trans("Visible"), $langs->trans("VisibleDesc")).''.$form->textwithpicto($langs->trans("DisplayOnPdf"), $langs->trans("DisplayOnPdfDesc")).''.$form->textwithpicto($langs->trans("Totalizable"), $langs->trans("TotalizableDesc")).''.$langs->trans("Entities").' '.yn($extrafields->attributes[$elementtype]['required'][$key])."'.yn($extrafields->attributes[$elementtype]['alwayseditable'][$key])."'.$extrafields->attributes[$elementtype]['list'][$key]."'.$extrafields->attributes[$elementtype]['printable'][$key]."'.yn($extrafields->attributes[$elementtype]['totalizable'][$key])."'; diff --git a/htdocs/core/tpl/advtarget.tpl.php b/htdocs/core/tpl/advtarget.tpl.php index 478c2dfa4b8..b3b6b5d1bf1 100644 --- a/htdocs/core/tpl/advtarget.tpl.php +++ b/htdocs/core/tpl/advtarget.tpl.php @@ -58,24 +58,27 @@ print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; -print '' . "\n"; + +print ''."\n"; diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php index 1a9a046bf81..795483b08ba 100644 --- a/htdocs/core/tpl/card_presend.tpl.php +++ b/htdocs/core/tpl/card_presend.tpl.php @@ -188,7 +188,8 @@ if ($action == 'presend') } } - $formmail->withto = GETPOST('sendto') ? GETPOST('sendto') : $liste; + $formmail->withto = $liste; + $formmail->withtofree = (GETPOSTISSET('sendto') ? (GETPOST('sendto') ? GETPOST('sendto') : '1') : '1'); $formmail->withtocc = $liste; $formmail->withtoccc = $conf->global->MAIN_EMAIL_USECCC; $formmail->withtopic = $topicmail; diff --git a/htdocs/core/tpl/contacts.tpl.php b/htdocs/core/tpl/contacts.tpl.php index d14503a9039..e6de4520ba4 100644 --- a/htdocs/core/tpl/contacts.tpl.php +++ b/htdocs/core/tpl/contacts.tpl.php @@ -28,7 +28,6 @@ if (empty($object) || !is_object($object)) exit; } - require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; @@ -66,8 +65,9 @@ $userstatic = new User($db);
+if ($permission) +{ + ?>
trans("NatureOfContact"); ?>
trans("ThirdParty"); ?>
@@ -153,94 +153,164 @@ if ($permission) { - -
trans("NatureOfContact"); ?>
-
trans("ThirdParty"); ?>
-
trans("Users").'/'.$langs->trans("Contacts"); ?>
-
trans("ContactType"); ?>
-
trans("Status"); ?>
-
 
- +print "
"; -element == 'shipping'|| $object->element == 'reception') && is_object($objectsrc)) $tmpobject=$objectsrc; +/** +* Prepare list +*/ + +// TODO: replace this with direct SQL string to use $db->sort($sortfield, $sortorder) +$list = array(); +foreach(array('internal', 'external') as $source) +{ + $tmpobject = $object; + + if (($object->element == 'shipping'|| $object->element == 'reception') && is_object($objectsrc)) + { + $tmpobject = $objectsrc; + } $tab = $tmpobject->liste_contact(-1, $source); - $num=count($tab); + $num = count($tab); $i = 0; - while ($i < $num) { - ?> + while ($i < $num) + { + $entry = new stdClass(); + + $entry->id = $tab[$i]['rowid']; + $entry->type = $tab[$i]['libelle']; + + if ($tab[$i]['source'] == 'internal') + { + $entry->nature = $langs->trans("User"); + } + elseif ($tab[$i]['source'] == 'external') + { + $entry->nature = $langs->trans("ThirdPartyContact"); + } - -
- trans("User"); ?> - trans("ThirdPartyContact"); ?> -
-
- 0) { $companystatic->fetch($tab[$i]['socid']); - echo $companystatic->getNomUrl(1); + $entry->thirdparty = $companystatic->getNomUrl(1); } - if ($tab[$i]['socid'] < 0) + elseif ($tab[$i]['socid'] < 0) { - echo $conf->global->MAIN_INFO_SOCIETE_NOM; + $entry->thirdparty = $conf->global->MAIN_INFO_SOCIETE_NOM; } - if (! $tab[$i]['socid']) + elseif (! $tab[$i]['socid']) { - echo ' '; + $entry->thirdparty = ""; } - ?> -
-
- fetch($tab[$i]['id']); - echo $userstatic->getNomUrl(-1, '', 0, 0, 0, 0, '', 'valignmiddle'); + $entry->contact = $userstatic->getNomUrl(-1, '', 0, 0, 0, 0, '', 'valignmiddle'); } - if ($tab[$i]['source']=='external') + elseif ($tab[$i]['source']=='external') { $contactstatic->fetch($tab[$i]['id']); - echo $contactstatic->getNomUrl(1, '', 0, '', 0, 0); + $entry->contact =$contactstatic->getNomUrl(1, '', 0, '', 0, 0); } - ?> -
-
- - - - \n"; -print "\n"; + +$sortfield = GETPOST("sortfield", "alpha"); +$sortorder = GETPOST("sortorder", 'alpha'); + +if (!$sortfield) $sortfield = "nature"; +if (!$sortorder) $sortorder = "asc"; + +// Re-sort list +$list = dol_sort_array($list, $sortfield, $sortorder, 1, 0, 1); + +$arrayfields = array( + 'rowid' => array('label'=>$langs->trans("Id"), 'checked'=>1), + 'nature' => array('label'=>$langs->trans("NatureOfContact"), 'checked'=>1), + 'thirdparty' => array('label'=>$langs->trans("ThirdParty"), 'checked'=>1), + 'contact' => array('label'=>$langs->trans("Users").'/'.$langs->trans("Contacts"), 'checked'=>1), + 'type' => array('label'=>$langs->trans("ContactType"), 'checked'=>1), + 'status' => array('label'=>$langs->trans("Status"), 'checked'=>1), + 'link' => array('label'=>$langs->trans("Link"), 'checked'=>1), +); + +$param = 'id='.$object->id.'&mainmenu=home'; + +/** + * Show list + */ + +print '
'; + +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +print '
'."\n"; -print ''."\n"; +print ''."\n"; print '
'.$langs->trans('AdvTgtNameTemplate').''; +print '
'.$langs->trans('AdvTgtNameTemplate').''; if (!empty($template_id)) { $default_template = $template_id; } else { $default_template = $advTarget->id; } -print $formadvtargetemaling->selectAdvtargetemailingTemplate('template_id', $default_template, 0, $advTarget->type_element); -print ''; -print ''; -print ''; -print $langs->trans('AdvTgtOrCreateNewFilter'); +print $formadvtargetemaling->selectAdvtargetemailingTemplate('template_id', $default_template, 0, $advTarget->type_element, 'valignmiddle'); +print ''; +print ''; +print ''; +print '' . "\n"; +print '
' . $langs->trans('AdvTgtOrCreateNewFilter') . ''; print ''; -print ''; +print ''; print ''."\n"; print '
'; + +print ''; +print ''; + +print ''; +print_liste_field_titre($arrayfields['nature']['label'], $_SERVER["PHP_SELF"], "nature", "", $param, "", $sortfield, $sortorder); +print_liste_field_titre($arrayfields['thirdparty']['label'], $_SERVER["PHP_SELF"], "thirdparty", "", $param, "", $sortfield, $sortorder); +print_liste_field_titre($arrayfields['contact']['label'], $_SERVER["PHP_SELF"], "contact", "", $param, "", $sortfield, $sortorder); +print_liste_field_titre($arrayfields['type']['label'], $_SERVER["PHP_SELF"], "type", "", $param, "", $sortfield, $sortorder); +print_liste_field_titre($arrayfields['status']['label'], $_SERVER["PHP_SELF"], "statut", "", $param, "", $sortfield, $sortorder, 'center '); +print_liste_field_titre($arrayfields['link']['label'], $_SERVER["PHP_SELF"], "", "", "", "", $sortfield, $sortorder, 'center maxwidthsearch '); +print ""; + +foreach($list as $entry) +{ + print ''; + + print ''; + print ''; + print ''; + print ''; + print ''; + + if ($permission) + { + $href = $_SERVER["PHP_SELF"]; + $href .= "?id=".$object->id; + $href .= "&action=deletecontact"; + $href .= "&lineid=".$entry->id; + + print ""; + } + + print ""; +} + +print "
'.$entry->nature.''.$entry->thirdparty.''.$entry->contact.''.$entry->type.''.$entry->status.'"; + print ""; + print img_picto($langs->trans("Unlink"), "unlink"); + print ""; + print "
"; +print ""; +print ""; +print ""; + print "\n"; if (is_object($hookmanager)) { $hookmanager->initHooks(array('contacttpl')); @@ -248,3 +318,4 @@ if (is_object($hookmanager)) { $reshook=$hookmanager->executeHooks('formContactTpl', $parameters, $object, $action); } print "\n"; + diff --git a/htdocs/core/tpl/document_actions_post_headers.tpl.php b/htdocs/core/tpl/document_actions_post_headers.tpl.php index a3de72723a4..1b5cb242391 100644 --- a/htdocs/core/tpl/document_actions_post_headers.tpl.php +++ b/htdocs/core/tpl/document_actions_post_headers.tpl.php @@ -23,6 +23,7 @@ // $permissiontoadd = permission or not to add a file (can use also $permission) and permission or not to edit file name or crop file (can use also $permtoedit) // $modulepart = for download // $param = param to add to download links +// $moreparam = param to add to download link for the form_attach_new_file function // $upload_dir // $object // $filearray @@ -71,6 +72,7 @@ if ($action == 'delete') $formfile=new FormFile($db); + // We define var to enable the feature to add prefix of uploaded files. // Caller of this include can make // $savingdocmask=dol_sanitizeFileName($object->ref).'-__file__'; @@ -92,6 +94,7 @@ if (!isset($savingdocmask) || !empty($conf->global->MAIN_DISABLE_SUGGEST_REF_AS_ 'project_task', 'expensereport', 'tax', + 'tax-vat', 'produit', 'product_batch', 'bom', @@ -109,7 +112,7 @@ if (!isset($savingdocmask) || !empty($conf->global->MAIN_DISABLE_SUGGEST_REF_AS_ // Show upload form (document and links) $formfile->form_attach_new_file( - $_SERVER["PHP_SELF"].'?id='.$object->id.(empty($withproject)?'':'&withproject=1'), + $_SERVER["PHP_SELF"].'?id='.$object->id.(empty($withproject)?'':'&withproject=1').(empty($moreparam)?'':$moreparam), '', 0, 0, diff --git a/htdocs/core/tpl/extrafields_add.tpl.php b/htdocs/core/tpl/extrafields_add.tpl.php index 0579c464d30..2ef606afa0b 100644 --- a/htdocs/core/tpl/extrafields_add.tpl.php +++ b/htdocs/core/tpl/extrafields_add.tpl.php @@ -37,11 +37,14 @@ if (empty($conf) || !is_object($conf)) executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; if (empty($reshook)) { - $params = isset($tpl_context) ? array('tpl_context' => $tpl_context) : array(); // BUG #11554 : Add tpl_context in params + $params = array(); + if (isset($tpl_context)) $params['tpl_context'] = $tpl_context; + $params['cols']=$parameters['colspanvalue']; print $object->showOptionals($extrafields, 'edit', $params); // BUG #11554 : Add context in params } diff --git a/htdocs/core/tpl/extrafields_edit.tpl.php b/htdocs/core/tpl/extrafields_edit.tpl.php index adca8b50fab..8a04aa32dea 100644 --- a/htdocs/core/tpl/extrafields_edit.tpl.php +++ b/htdocs/core/tpl/extrafields_edit.tpl.php @@ -37,11 +37,13 @@ if (empty($conf) || ! is_object($conf)) executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; if (empty($reshook)) { - print $object->showOptionals($extrafields, 'edit'); + $params=array(); + $params['cols']=$parameters['colspanvalue']; + print $object->showOptionals($extrafields, 'edit', $params); } ?> diff --git a/htdocs/core/tpl/extrafields_list_search_param.tpl.php b/htdocs/core/tpl/extrafields_list_search_param.tpl.php index ca72293365a..6e6d6305106 100644 --- a/htdocs/core/tpl/extrafields_list_search_param.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_param.tpl.php @@ -8,7 +8,7 @@ if (empty($conf) || !is_object($conf)) } // Loop to complete $param for extrafields -if (!empty($search_array_options)) // $extrafieldsobject is the $object->table_element like 'societe', 'socpeople', ... +if (!empty($search_array_options) && is_array($search_array_options)) // $extrafieldsobject is the $object->table_element like 'societe', 'socpeople', ... { if (empty($search_options_pattern)) $search_options_pattern = 'search_options_'; diff --git a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php index 29c67094975..3a0bcf6375c 100644 --- a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php @@ -40,7 +40,10 @@ if (! empty($extrafieldsobjectkey) && ! empty($search_array_options) && is_array if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int if (in_array($typ, array('chkbxlst','checkbox'))) $mode_search=4; // Search on a multiselect field with sql type = text if (is_array($crit)) $crit = implode(' ', $crit); // natural_search() expects a string - + elseif ($typ === 'select' and is_string($crit) and strpos($crit, ' ') === false) { + $sql .= ' AND (' . $extrafieldsobjectprefix.$tmpkey . ' = "' . $db->escape($crit) . '")'; + continue; + } $sql .= natural_search($extrafieldsobjectprefix.$tmpkey, $crit, $mode_search); } } diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index f8767a82163..1ef3ef07255 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -73,7 +73,7 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element] //print $key.'-'.$enabled.'-'.$perms.'-'.$label.$_POST["options_" . $key].'
'."\n"; if (empty($enabled)) continue; // 0 = Never visible field - if (abs($enabled) != 1 && abs($enabled) != 3) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list + if (abs($enabled) != 1 && abs($enabled) != 3 && abs($enabled) != 5) continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list if (empty($perms)) continue; // 0 = Not visible // Load language if required @@ -135,7 +135,7 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element] if ($object->element == 'productlot') $permok = $user->rights->stock->creer; if ($object->element == 'facturerec') $permok = $user->rights->facture->creer; if (($object->statut == 0 || !empty($extrafields->attributes[$object->table_element]['alwayseditable'][$key])) - && $permok && ($action != 'edit_extras' || GETPOST('attribute') != $key) + && $permok && $enabled != 5 && ($action != 'edit_extras' || GETPOST('attribute') != $key) && empty($extrafields->attributes[$object->table_element]['computed'][$key])) { $fieldid = 'id'; diff --git a/htdocs/core/tpl/notes.tpl.php b/htdocs/core/tpl/notes.tpl.php index 7663af1c48e..28eb78fa61b 100644 --- a/htdocs/core/tpl/notes.tpl.php +++ b/htdocs/core/tpl/notes.tpl.php @@ -1,7 +1,7 @@ * Copyright (C) 2013 Florian Henry - * Copyright (C) 2014-2017 Laurent Destailleur + * Copyright (C) 2014-2020 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 @@ -29,69 +29,70 @@ $module = $object->element; $note_public = 'note_public'; $note_private = 'note_private'; -$colwidth=(isset($colwidth)?$colwidth:(empty($cssclass)?'25':'')); +$colwidth = (isset($colwidth) ? $colwidth : (empty($cssclass) ? '25' : '')); // Set $permission from the $permissionnote var defined on calling page -$permission=(isset($permissionnote)?$permissionnote:(isset($permission)?$permission:(isset($user->rights->$module->create)?$user->rights->$module->create:(isset($user->rights->$module->creer)?$user->rights->$module->creer:0)))); -$moreparam=(isset($moreparam)?$moreparam:''); -$value_public=$object->note_public; -$value_private=$object->note_private; -if (! empty($conf->global->MAIN_AUTO_TIMESTAMP_IN_PUBLIC_NOTES)) +$permission = (isset($permissionnote) ? $permissionnote : (isset($permission) ? $permission : (isset($user->rights->$module->create) ? $user->rights->$module->create : (isset($user->rights->$module->creer) ? $user->rights->$module->creer : 0)))); +$moreparam = (isset($moreparam) ? $moreparam : ''); +$value_public = $object->note_public; +$value_private = $object->note_private; +if (!empty($conf->global->MAIN_AUTO_TIMESTAMP_IN_PUBLIC_NOTES)) { - $stringtoadd=dol_print_date(dol_now(), 'dayhour').' '.$user->getFullName($langs).' --'; + $stringtoadd = dol_print_date(dol_now(), 'dayhour').' '.$user->getFullName($langs).' --'; if (GETPOST('action', 'aZ09') == 'edit'.$note_public) { - $value_public=dol_concatdesc($value_public, ($value_public?"\n":"")."-- ".$stringtoadd); - if (dol_textishtml($value_public)) $value_public.="
\n"; - else $value_public.="\n"; + $value_public = dol_concatdesc($value_public, ($value_public ? "\n" : "")."-- ".$stringtoadd); + if (dol_textishtml($value_public)) $value_public .= "
\n"; + else $value_public .= "\n"; } } -if (! empty($conf->global->MAIN_AUTO_TIMESTAMP_IN_PRIVATE_NOTES)) +if (!empty($conf->global->MAIN_AUTO_TIMESTAMP_IN_PRIVATE_NOTES)) { - $stringtoadd=dol_print_date(dol_now(), 'dayhour').' '.$user->getFullName($langs).' --'; + $stringtoadd = dol_print_date(dol_now(), 'dayhour').' '.$user->getFullName($langs).' --'; if (GETPOST('action', 'aZ09') == 'edit'.$note_private) { - $value_private=dol_concatdesc($value_private, ($value_private?"\n":"")."-- ".$stringtoadd); - if (dol_textishtml($value_private)) $value_private.="
\n"; - else $value_private.="\n"; + $value_private = dol_concatdesc($value_private, ($value_private ? "\n" : "")."-- ".$stringtoadd); + if (dol_textishtml($value_private)) $value_private .= "
\n"; + else $value_private .= "\n"; } } // Special cases -if ($module == 'propal') { $permission=$user->rights->propale->creer;} -elseif ($module == 'supplier_proposal') { $permission=$user->rights->supplier_proposal->creer;} -elseif ($module == 'fichinter') { $permission=$user->rights->ficheinter->creer;} -elseif ($module == 'project') { $permission=$user->rights->projet->creer;} -elseif ($module == 'project_task') { $permission=$user->rights->projet->creer;} -elseif ($module == 'invoice_supplier') { $permission=$user->rights->fournisseur->facture->creer;} -elseif ($module == 'order_supplier') { $permission=$user->rights->fournisseur->commande->creer;} -elseif ($module == 'societe') { $permission=$user->rights->societe->creer;} -elseif ($module == 'contact') { $permission=$user->rights->societe->creer;} -elseif ($module == 'shipping') { $permission=$user->rights->expedition->creer;} -elseif ($module == 'product') { $permission=$user->rights->produit->creer;} +if ($module == 'propal') { $permission = $user->rights->propale->creer; } +elseif ($module == 'supplier_proposal') { $permission = $user->rights->supplier_proposal->creer; } +elseif ($module == 'fichinter') { $permission = $user->rights->ficheinter->creer; } +elseif ($module == 'project') { $permission = $user->rights->projet->creer; } +elseif ($module == 'project_task') { $permission = $user->rights->projet->creer; } +elseif ($module == 'invoice_supplier') { $permission = $user->rights->fournisseur->facture->creer; } +elseif ($module == 'order_supplier') { $permission = $user->rights->fournisseur->commande->creer; } +elseif ($module == 'societe') { $permission = $user->rights->societe->creer; } +elseif ($module == 'contact') { $permission = $user->rights->societe->creer; } +elseif ($module == 'shipping') { $permission = $user->rights->expedition->creer; } +elseif ($module == 'product') { $permission = $user->rights->produit->creer; } //else dol_print_error('','Bad value '.$module.' for param module'); -if (! empty($conf->fckeditor->enabled) && ! empty($conf->global->FCKEDITOR_ENABLE_SOCIETE)) $typeofdata='ckeditor:dolibarr_notes:100%:200::1:12:95%:0'; // Rem: This var is for all notes, not only thirdparties note. -else $typeofdata='textarea:12:95%'; +if (!empty($conf->fckeditor->enabled) && !empty($conf->global->FCKEDITOR_ENABLE_SOCIETE)) $typeofdata = 'ckeditor:dolibarr_notes:100%:200::1:12:95%:0'; // Rem: This var is for all notes, not only thirdparties note. +else $typeofdata = 'textarea:12:95%'; print ''."\n"; print '
'."\n"; if ($module != 'product') { // No public note yet on products print '
'."\n"; - print '
'."\n"; + print '
'."\n"; print $form->editfieldkey("NotePublic", $note_public, $value_public, $object, $permission, $typeofdata, $moreparam, '', 0); print '
'."\n"; - print '
'."\n"; + print '
'."\n"; print $form->editfieldval("NotePublic", $note_public, $value_public, $object, $permission, $typeofdata, '', null, null, $moreparam, 1)."\n"; print '
'."\n"; print '
'."\n"; } if (empty($user->socid)) { + // Private notes (always hidden to external users) print '
'."\n"; - print '
'."\n"; + print '
'."\n"; print $form->editfieldkey("NotePrivate", $note_private, $value_private, $object, $permission, $typeofdata, $moreparam, '', 0); print '
'."\n"; - print '
'."\n"; + print '
'."\n"; print $form->editfieldval("NotePrivate", $note_private, $value_private, $object, $permission, $typeofdata, '', null, null, $moreparam, 1); print '
'."\n"; print '
'."\n"; diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index b60c48da09c..4e636f3d9cf 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -261,7 +261,7 @@ if ($nolinesbefore) { if ($senderissupplier != 2) { $ajaxoptions = array( - 'update' => array('qty'=>'qty', 'remise_percent' => 'discount', 'idprod' => 'idprod'), // html id tags that will be edited with which ajax json response key + 'update' => array('qty'=>'qty', 'remise_percent' => 'discount', 'idprod' => 'idprod'), // html id tags that will be edited with each ajax json response key 'option_disabled' => 'idthatdoesnotexists', // html id to disable once select is done 'warning' => $langs->trans("NoPriceDefinedForThisSupplier") // translation of an error saved into var 'warning' (for example shown we select a disabled option into combo) ); @@ -432,7 +432,7 @@ if ($nolinesbefore) { showOptionals($extrafields, 'edit', array('colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD) ? 0 : 1); + print $objectline->showOptionals($extrafields, 'edit', array('colspan'=>$coldisplay), '', '', 1); } if ((!empty($conf->service->enabled) || ($object->element == 'contrat')) && $dateSelector && GETPOST('type') != '0') // We show date field if required @@ -541,6 +541,7 @@ if (!empty($usemargins) && $user->rights->margins->creer) else if (npRate == "np_markRate") price = ((bpjs / (1 - ratejs / 100)) / (1 - remisejs / 100)); } + $("input[name='price_ht']:first").val(price); // TODO Must use a function like php price to have here a formated value return true; @@ -552,26 +553,26 @@ if (!empty($usemargins) && $user->rights->margins->creer) /* JQuery for product free or predefined select */ jQuery(document).ready(function() { - jQuery("#price_ht").keyup(function(event) { - // console.log(event.which); // discard event tag and arrows - if (event.which != 9 && (event.which < 37 ||event.which > 40) && jQuery("#price_ht").val() != '') { - jQuery("#price_ttc").val(''); - jQuery("#multicurrency_subprice").val(''); - } + jQuery("#price_ht").keyup(function(event) { + // console.log(event.which); // discard event tag and arrows + if (event.which != 9 && (event.which < 37 ||event.which > 40) && jQuery("#price_ht").val() != '') { + jQuery("#price_ttc").val(''); + jQuery("#multicurrency_subprice").val(''); + } }); jQuery("#price_ttc").keyup(function(event) { - // console.log(event.which); // discard event tag and arrows - if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#price_ttc").val() != '') { - jQuery("#price_ht").val(''); - jQuery("#multicurrency_subprice").val(''); - } + // console.log(event.which); // discard event tag and arrows + if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#price_ttc").val() != '') { + jQuery("#price_ht").val(''); + jQuery("#multicurrency_subprice").val(''); + } }); jQuery("#multicurrency_subprice").keyup(function(event) { - // console.log(event.which); // discard event tag and arrows - if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#price_ttc").val() != '') { - jQuery("#price_ht").val(''); - jQuery("#price_ttc").val(''); - } + // console.log(event.which); // discard event tag and arrows + if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#price_ttc").val() != '') { + jQuery("#price_ht").val(''); + jQuery("#price_ttc").val(''); + } }); $("#prod_entry_mode_free").on( "click", function() { @@ -630,15 +631,28 @@ if (!empty($usemargins) && $user->rights->margins->creer) if (empty($conf->global->MAIN_DISABLE_EDIT_PREDEF_PRICEHT) && empty($senderissupplier)) { ?> - // Get the HT price for the product and display it - console.log("Load price without tax and set it into #price_ht"); - $.post('/product/ajax/products.php?action=fetch', - { 'id': $(this).val(), 'socid' : socid; ?> }, - function(data) { jQuery("#price_ht").val(data.price_ht); }, - 'json' - ); + var pbq = parseInt($('option:selected', this).attr('data-pbq')); + if ((jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').val()) && ! isNaN(pbq) && pbq > 0) + { + console.log("We are in a price per qty context, we do not call ajax/product"); + } else { + global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || ! empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { ?> + if (isNaN(pbq)) { console.log("We use experimental option PRODUIT_CUSTOMER_PRICES_BY_QTY or PRODUIT_CUSTOMER_PRICES_BY_QTY but we are not yet able to get the id of pbq from product combo list, so load of price may be 0 if product has differet prices"); } + + // Get the HT price for the product and display it + console.log("Load unit price without tax and set it into #price_ht for product id="+$(this).val()+" socid=socid; ?>"); + $.post('/product/ajax/products.php?action=fetch', + { 'id': $(this).val(), 'socid': socid; ?> }, + function(data) { + console.log("Load unit price end, we got value "+data.price_ht); + jQuery("#price_ht").val(data.price_ht); + }, + 'json' + ); + } rights->margins->creer) { $langs->load('stocks'); @@ -648,95 +662,96 @@ if (!empty($usemargins) && $user->rights->margins->creer) $("#fournprice_predef").find("option").remove(); $("#fournprice_predef").hide(); $("#buying_price").val("").show(); + /* Call post to load content of combo list fournprice_predef */ $.post('/fourn/ajax/getSupplierPrices.php?bestpricefirst=1', { 'idprod': $(this).val() }, function(data) { - if (data && data.length > 0) - { - var options = ''; var defaultkey = ''; var defaultprice = ''; var bestpricefound = 0; - - var bestpriceid = 0; var bestpricevalue = 0; - var pmppriceid = 0; var pmppricevalue = 0; - var costpriceid = 0; var costpricevalue = 0; - - /* setup of margin calculation */ - var defaultbuyprice = 'global->MARGIN_TYPE)) - { - if ($conf->global->MARGIN_TYPE == '1') print 'bestsupplierprice'; - if ($conf->global->MARGIN_TYPE == 'pmp') print 'pmp'; - if ($conf->global->MARGIN_TYPE == 'costprice') print 'costprice'; - } ?>'; - console.log("we will set the field for margin. defaultbuyprice="+defaultbuyprice); - - var i = 0; - $(data).each(function() { - /* Warning: Lines must be processed in order: best supplier price, then pmpprice line then costprice */ - if (this.id != 'pmpprice' && this.id != 'costprice') + if (data && data.length > 0) { - i++; - this.price = parseFloat(this.price); // to fix when this.price >0 - // If margin is calculated on best supplier price, we set it by defaut (but only if value is not 0) - //console.log("id="+this.id+"-price="+this.price+"-"+(this.price > 0)); - if (bestpricefound == 0 && this.price > 0) { defaultkey = this.id; defaultprice = this.price; bestpriceid = this.id; bestpricevalue = this.price; bestpricefound=1; } // bestpricefound is used to take the first price > 0 - } - if (this.id == 'pmpprice') - { - // If margin is calculated on PMP, we set it by defaut (but only if value is not 0) - console.log("id="+this.id+"-price="+this.price); - if ('pmp' == defaultbuyprice || 'costprice' == defaultbuyprice) + var options = ''; var defaultkey = ''; var defaultprice = ''; var bestpricefound = 0; + + var bestpriceid = 0; var bestpricevalue = 0; + var pmppriceid = 0; var pmppricevalue = 0; + var costpriceid = 0; var costpricevalue = 0; + + /* setup of margin calculation */ + var defaultbuyprice = 'global->MARGIN_TYPE)) { - if (this.price > 0) { - defaultkey = this.id; defaultprice = this.price; pmppriceid = this.id; pmppricevalue = this.price; - //console.log("pmppricevalue="+pmppricevalue); + if ($conf->global->MARGIN_TYPE == '1') print 'bestsupplierprice'; + if ($conf->global->MARGIN_TYPE == 'pmp') print 'pmp'; + if ($conf->global->MARGIN_TYPE == 'costprice') print 'costprice'; + } ?>'; + console.log("we will set the field for margin. defaultbuyprice="+defaultbuyprice); + + var i = 0; + $(data).each(function() { + /* Warning: Lines must be processed in order: best supplier price, then pmpprice line then costprice */ + if (this.id != 'pmpprice' && this.id != 'costprice') + { + i++; + this.price = parseFloat(this.price); // to fix when this.price >0 + // If margin is calculated on best supplier price, we set it by defaut (but only if value is not 0) + //console.log("id="+this.id+"-price="+this.price+"-"+(this.price > 0)); + if (bestpricefound == 0 && this.price > 0) { defaultkey = this.id; defaultprice = this.price; bestpriceid = this.id; bestpricevalue = this.price; bestpricefound=1; } // bestpricefound is used to take the first price > 0 } - } - } - if (this.id == 'costprice') - { - // If margin is calculated on Cost price, we set it by defaut (but only if value is not 0) - console.log("id="+this.id+"-price="+this.price+"-pmppricevalue="+pmppricevalue); - if ('costprice' == defaultbuyprice) + if (this.id == 'pmpprice') + { + // If margin is calculated on PMP, we set it by defaut (but only if value is not 0) + console.log("id="+this.id+"-price="+this.price); + if ('pmp' == defaultbuyprice || 'costprice' == defaultbuyprice) + { + if (this.price > 0) { + defaultkey = this.id; defaultprice = this.price; pmppriceid = this.id; pmppricevalue = this.price; + //console.log("pmppricevalue="+pmppricevalue); + } + } + } + if (this.id == 'costprice') + { + // If margin is calculated on Cost price, we set it by defaut (but only if value is not 0) + console.log("id="+this.id+"-price="+this.price+"-pmppricevalue="+pmppricevalue); + if ('costprice' == defaultbuyprice) + { + if (this.price > 0) { defaultkey = this.id; defaultprice = this.price; costpriceid = this.id; costpricevalue = this.price; } + else if (pmppricevalue > 0) { defaultkey = 'pmpprice'; defaultprice = pmppricevalue; } + } + } + options += ''; + }); + options += ''; + + console.log("finally selected defaultkey="+defaultkey+" defaultprice for buying price="+defaultprice); + + $("#fournprice_predef").html(options).show(); + if (defaultkey != '') { - if (this.price > 0) { defaultkey = this.id; defaultprice = this.price; costpriceid = this.id; costpricevalue = this.price; } - else if (pmppricevalue > 0) { defaultkey = 'pmpprice'; defaultprice = pmppricevalue; } + $("#fournprice_predef").val(defaultkey); } + + /* At loading, no product are yet selected, so we hide field of buying_price */ + $("#buying_price").hide(); + + /* Define default price at loading */ + var defaultprice = $("#fournprice_predef").find('option:selected').attr("price"); + $("#buying_price").val(defaultprice); + + $("#fournprice_predef").change(function() { + console.log("change on fournprice_predef"); + /* Hide field buying_price according to choice into list (if 'inputprice' or not) */ + var linevalue=$(this).find('option:selected').val(); + var pricevalue = $(this).find('option:selected').attr("price"); + if (linevalue != 'inputprice' && linevalue != 'pmpprice') { + $("#buying_price").val(pricevalue).hide(); /* We set value then hide field */ + } + if (linevalue == 'inputprice') { + $('#buying_price').show(); + } + if (linevalue == 'pmpprice') { + $("#buying_price").val(pricevalue); + $('#buying_price').hide(); + } + }); } - options += ''; - }); - options += ''; - - console.log("finally selected defaultkey="+defaultkey+" defaultprice="+defaultprice); - - $("#fournprice_predef").html(options).show(); - if (defaultkey != '') - { - $("#fournprice_predef").val(defaultkey); - } - - /* At loading, no product are yet selected, so we hide field of buying_price */ - $("#buying_price").hide(); - - /* Define default price at loading */ - var defaultprice = $("#fournprice_predef").find('option:selected').attr("price"); - $("#buying_price").val(defaultprice); - - $("#fournprice_predef").change(function() { - console.log("change on fournprice_predef"); - /* Hide field buying_price according to choice into list (if 'inputprice' or not) */ - var linevalue=$(this).find('option:selected').val(); - var pricevalue = $(this).find('option:selected').attr("price"); - if (linevalue != 'inputprice' && linevalue != 'pmpprice') { - $("#buying_price").val(pricevalue).hide(); /* We set value then hide field */ - } - if (linevalue == 'inputprice') { - $('#buying_price').show(); - } - if (linevalue == 'pmpprice') { - $("#buying_price").val(pricevalue); - $('#buying_price').hide(); - } - }); - } }, 'json'); @@ -744,15 +759,20 @@ if (!empty($usemargins) && $user->rights->margins->creer) } ?> - /* To process customer price per quantity */ + /* To process customer price per quantity (CUSTOMER_PRICE_PER_QTY works only if combo product is not an ajax after x key pressed) */ var pbq = parseInt($('option:selected', this).attr('data-pbq')); + var pbqup = parseInt($('option:selected', this).attr('data-pbqup')); + var pbqbase = $('option:selected', this).attr('data-pbqbase'); var pbqqty = parseFloat($('option:selected', this).attr('data-pbqqty')); var pbqpercent = parseFloat($('option:selected', this).attr('data-pbqpercent')); - if ((jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').val()) && typeof pbq !== "undefined") + if ((jQuery('#idprod').val() > 0 || jQuery('#idprodfournprice').val()) && ! isNaN(pbq) && pbq > 0) { - console.log("We choose a price by quanty price_by_qty id = "+pbq+" price_by_qty qty = "+pbqqty+" price_by_qty percent = "+pbqpercent); + var pbqupht = pbqup; /* TODO support of price per qty TTC not yet available */ + + console.log("We choose a price by quanty price_by_qty id = "+pbq+" price_by_qty upht = "+pbqupht+" price_by_qty qty = "+pbqqty+" price_by_qty percent = "+pbqpercent); jQuery("#pbq").val(pbq); + jQuery("#price_ht").val(pbqupht); if (jQuery("#qty").val() < pbqqty) { jQuery("#qty").val(pbqqty); @@ -809,7 +829,6 @@ if (!empty($usemargins) && $user->rights->margins->creer) jQuery("#price_ht").val('').hide(); jQuery("#multicurrency_price_ht").val('').hide(); - jQuery("#price_ht").val(''); jQuery("#price_ttc, #fourn_ref, #tva_tx, #title_vat, #title_up_ht_currency, #title_up_ttc, #title_up_ttc_currency").hide(); jQuery("#np_marginRate, #np_markRate, .np_marginRate, .np_markRate, #units, #title_units").hide(); jQuery("#buying_price").show(); diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index 7c76a5c0e07..278b8eabdd8 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -260,7 +260,7 @@ $coldisplay++; //Line extrafield if (!empty($extrafields)) { - print $line->showOptionals($extrafields, 'edit', array('class'=>'tredited', 'colspan'=>$coldisplay), '', '', empty($conf->global->MAIN_EXTRAFIELDS_IN_ONE_TD)?0:1); + print $line->showOptionals($extrafields, 'edit', array('class'=>'tredited', 'colspan'=>$coldisplay), '', '', 1); } ?> diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index 19a10e0f560..59f2e1ef57c 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -356,7 +356,7 @@ print "
'.$langs->trans("DONATION_ART885").''.$langs->trans("DONATION_ART978").''; if ($conf->use_javascript_ajax) { - print ajax_constantonoff('DONATION_ART885'); + print ajax_constantonoff('DONATION_ART978'); } else { $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("DONATION_ART885", $arrval, $conf->global->DONATION_ART885); + print $form->selectarray("DONATION_ART978", $arrval, $conf->global->DONATION_ART978); } print '
\n"; diff --git a/htdocs/don/class/api_donations.class.php b/htdocs/don/class/api_donations.class.php index 4adef57e816..95ea92f1ff3 100644 --- a/htdocs/don/class/api_donations.class.php +++ b/htdocs/don/class/api_donations.class.php @@ -284,10 +284,10 @@ class Donations extends DolibarrApi * * @url POST {id}/validate * - * @throws 304 - * @throws 401 - * @throws 404 - * @throws 500 + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 * * @return array */ diff --git a/htdocs/don/index.php b/htdocs/don/index.php index 6366d0fb6e6..39155dae768 100644 --- a/htdocs/don/index.php +++ b/htdocs/don/index.php @@ -137,10 +137,10 @@ if ($conf->use_javascript_ajax) include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; $dolgraph = new DolGraph(); $dolgraph->SetData($dataseries); - $dolgraph->setShowLegend(1); + $dolgraph->setShowLegend(2); $dolgraph->setShowPercent(1); $dolgraph->SetType(array('pie')); - $dolgraph->setWidth('100%'); + $dolgraph->setHeight('200'); $dolgraph->draw('idgraphstatus'); print $dolgraph->show($total ? 0 : 1); @@ -159,7 +159,7 @@ $totalnb = 0; foreach ($listofstatus as $status) { print '
'.$donstatic->LibStatut($status, 4).''.$donstatic->LibStatut($status, 4).''.(!empty($nb[$status]) ? $nb[$status] : ' ').''.(!empty($nb[$status]) ?price($somme[$status], 'MT') : ' ').''.(!empty($nb[$status]) ?price(price2num($somme[$status] / $nb[$status], 'MT')) : ' ').''; + $liststatus = array( + Don::STATUS_DRAFT=>$langs->trans("DonationStatusPromiseNotValidated"), + Don::STATUS_VALIDATED=>$langs->trans("DonationStatusPromiseValidated"), + Don::STATUS_PAID=>$langs->trans("DonationStatusPaid"), + Don::STATUS_CANCELED=>$langs->trans("Canceled") + ); + print $form->selectarray('search_status', $liststatus, $search_status, -4, 0, 0, '', 0, 0, 0, '', 'maxwidth100'); + print ''; $searchpicto=$form->showFilterAndCheckAddButtons(0); print $searchpicto; diff --git a/htdocs/don/payment/payment.php b/htdocs/don/payment/payment.php index abdc35c850e..b3ab7e2d360 100644 --- a/htdocs/don/payment/payment.php +++ b/htdocs/don/payment/payment.php @@ -29,12 +29,12 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; $langs->load("bills"); -$chid=GETPOST("rowid"); -$action=GETPOST('action', 'aZ09'); +$chid = GETPOST("rowid"); +$action = GETPOST('action', 'aZ09'); $amounts = array(); // Security check -$socid=0; +$socid = 0; if ($user->socid > 0) { $socid = $user->socid; } @@ -48,7 +48,7 @@ $object = new Don($db); if ($action == 'add_payment') { - $error=0; + $error = 0; if ($_POST["cancel"]) { @@ -59,7 +59,7 @@ if ($action == 'add_payment') $datepaid = dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]); - if (! $_POST["paymenttype"] > 0) + if (!$_POST["paymenttype"] > 0) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("PaymentMode")), null, 'errors'); $error++; @@ -69,13 +69,13 @@ if ($action == 'add_payment') setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Date")), null, 'errors'); $error++; } - if (! empty($conf->banque->enabled) && ! $_POST["accountid"] > 0) + if (!empty($conf->banque->enabled) && !$_POST["accountid"] > 0) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AccountToCredit")), null, 'errors'); $error++; } - if (! $error) + if (!$error) { $paymentid = 0; @@ -92,11 +92,11 @@ if ($action == 'add_payment') if (count($amounts) <= 0) { $error++; - $errmsg='ErrorNoPaymentDefined'; + $errmsg = 'ErrorNoPaymentDefined'; setEventMessages($errmsg, null, 'errors'); } - if (! $error) + if (!$error) { $db->begin(); @@ -104,34 +104,34 @@ if ($action == 'add_payment') $payment = new PaymentDonation($db); $payment->chid = $chid; $payment->datepaid = $datepaid; - $payment->amounts = $amounts; // Tableau de montant + $payment->amounts = $amounts; // Tableau de montant $payment->paymenttype = GETPOST("paymenttype", 'int'); $payment->num_payment = GETPOST("num_payment", 'alphanohtml'); $payment->note_public = GETPOST("note_public", 'none'); - if (! $error) + if (!$error) { $paymentid = $payment->create($user); if ($paymentid < 0) { - $errmsg=$payment->error; + $errmsg = $payment->error; setEventMessages($errmsg, null, 'errors'); $error++; } } - if (! $error) + if (!$error) { - $result=$payment->addPaymentToBank($user, 'payment_donation', '(DonationPayment)', $_POST['accountid'], '', ''); - if (! $result > 0) + $result = $payment->addPaymentToBank($user, 'payment_donation', '(DonationPayment)', $_POST['accountid'], '', ''); + if (!$result > 0) { - $errmsg=$payment->error; + $errmsg = $payment->error; setEventMessages($errmsg, null, 'errors'); $error++; } } - if (! $error) + if (!$error) { $db->commit(); $loc = DOL_URL_ROOT.'/don/card.php?rowid='.$chid; @@ -153,18 +153,18 @@ if ($action == 'add_payment') * View */ -$form=new Form($db); +$form = new Form($db); llxHeader(); $sql = "SELECT sum(p.amount) as total"; -$sql.= " FROM ".MAIN_DB_PREFIX."payment_donation as p"; -$sql.= " WHERE p.fk_donation = ".$chid; +$sql .= " FROM ".MAIN_DB_PREFIX."payment_donation as p"; +$sql .= " WHERE p.fk_donation = ".$chid; $resql = $db->query($sql); if ($resql) { - $obj=$db->fetch_object($resql); + $obj = $db->fetch_object($resql); $sumpaid = $obj->total; $db->free(); } @@ -191,20 +191,20 @@ if ($action == 'create') print '
'.$langs->trans("Date").''; $datepaid = dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]); - $datepayment=empty($conf->global->MAIN_AUTOFILL_DATE)?(empty($_POST["remonth"])?-1:$datepaid):0; + $datepayment = empty($conf->global->MAIN_AUTOFILL_DATE) ? (empty($_POST["remonth"]) ?-1 : $datepaid) : 0; print $form->selectDate($datepayment, '', 0, 0, 0, "add_payment", 1, 1, 0, '', '', $object->date, '', 1, $langs->trans("DonationDate")); print "
'.$langs->trans("PaymentMode").''; - $form->select_types_paiements(isset($_POST["paymenttype"])?$_POST["paymenttype"]:$object->paymenttype, "paymenttype"); + $form->select_types_paiements(GETPOSTISSET("paymenttype") ? GETPOST("paymenttype") : $object->paymenttype, "paymenttype"); print "
'.$langs->trans('AccountToCredit').''; - $form->select_comptes(isset($_POST["accountid"])?$_POST["accountid"]:$object->accountid, "accountid", 0, '', 1); // Show open bank account list + $form->select_comptes(GETPOSTISSET("accountid") ? GETPOST("accountid") : $object->accountid, "accountid", 0, '', 1); // Show open bank account list print '
'.$langs->trans("Amount").'
'.$form->editfieldkey("TrackingNumber", 'tracking_number', $object->tracking_number, $object, $user->rights->expedition->creer).''; - print $form->editfieldval("TrackingNumber", 'tracking_number', $object->tracking_url, $object, $user->rights->expedition->creer, 'string', $object->tracking_number); + print $form->editfieldval("TrackingNumber", 'tracking_number', $object->tracking_url, $object, $user->rights->expedition->creer, 'safehtmlstring', $object->tracking_number); print '
'."\n"; print '"; print ''; print '\n"; print ''; @@ -264,7 +264,7 @@ if ($action == 'create' || empty($action)) print ''; print ''; print ''; } diff --git a/htdocs/exports/class/export.class.php b/htdocs/exports/class/export.class.php index 78d8ea09166..bf00027b58a 100644 --- a/htdocs/exports/class/export.class.php +++ b/htdocs/exports/class/export.class.php @@ -547,7 +547,7 @@ class Export $indice = 0; asort($array_selected); - dol_syslog(get_class($this)."::".__FUNCTION__." ".$model.", ".$datatoexport.", ".implode(",", $array_selected)); + dol_syslog(__METHOD__." ".$model.", ".$datatoexport.", ".implode(",", $array_selected)); // Check parameters or context properties if (empty($this->array_export_fields) || !is_array($this->array_export_fields)) @@ -588,7 +588,7 @@ class Export // Run the sql $this->sqlusedforexport = $sql; - dol_syslog(get_class($this)."::".__FUNCTION__."", LOG_DEBUG); + dol_syslog(__METHOD__, LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index f910001a5e0..6543747d1f7 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -33,7 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/export/modules_export.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; // Load translation files required by the page -$langs->loadlangs(array('admin', 'exports', 'other', 'users', 'companies', 'projects', 'suppliers', 'products', 'bank')); +$langs->loadlangs(array('admin', 'exports', 'other', 'users', 'companies', 'projects', 'suppliers', 'products', 'bank', 'bills')); // Everybody should be able to go on this page //if (! $user->admin) @@ -147,6 +147,7 @@ $htmlother = new FormOther($db); $formfile = new FormFile($db); $sqlusedforexport = ''; +$head = array(); $upload_dir = $conf->export->dir_temp.'/'.$user->id; //$usefilters=($conf->global->MAIN_FEATURES_LEVEL > 1); @@ -410,12 +411,12 @@ if ($step == 4 && $action == 'submitFormField') $newcode = (string) preg_replace('/\./', '_', $code); //print 'xxx'.$code."=".$newcode."=".$type."=".$_POST[$newcode]."\n
"; $filterqualified = 1; - if (!isset($_POST[$newcode]) || $_POST[$newcode] == '') $filterqualified = 0; - elseif (preg_match('/^List/', $type) && (is_numeric($_POST[$newcode]) && $_POST[$newcode] <= 0)) $filterqualified = 0; + if (!GETPOSTISSET($newcode) || GETPOST($newcode, 'restricthtml') == '') $filterqualified = 0; + elseif (preg_match('/^List/', $type) && (is_numeric(GETPOST($newcode, 'restricthtml')) && GETPOST($newcode, 'restricthtml') <= 0)) $filterqualified = 0; if ($filterqualified) { //print 'Filter on '.$newcode.' type='.$type.' value='.$_POST[$newcode]."\n"; - $objexport->array_export_FilterValue[0][$code] = $_POST[$newcode]; + $objexport->array_export_FilterValue[0][$code] = GETPOST($newcode, 'restricthtml'); } } $array_filtervalue = (!empty($objexport->array_export_FilterValue[0]) ? $objexport->array_export_FilterValue[0] : ''); @@ -938,7 +939,7 @@ if ($step == 4 && $datatoexport) // List of filtered fiels if (isset($objexport->array_export_TypeFields[0]) && is_array($objexport->array_export_TypeFields[0])) { - print ''; + print ''; $list = ''; if (!empty($array_filtervalue)) { @@ -952,7 +953,7 @@ if ($step == 4 && $datatoexport) } } } - print ''; + print ''; print ''; } @@ -1266,22 +1267,17 @@ if ($step == 5 && $datatoexport) print ''; - print '
'.$langs->trans("Date").''; - $datepaid = dol_mktime(12, 0, 0, $_POST["remonth"], $_POST["reday"], $_POST["reyear"]); + $datepaid = dol_mktime(12, 0, 0, GETPOST("remonth", 'int'), GETPOST("reday", 'int'), GETPOST("reyear", 'int')); $datepayment=empty($conf->global->MAIN_AUTOFILL_DATE)?(empty($_POST["remonth"])?-1:$datepaid):0; print $form->selectDate($datepayment, '', '', '', '', "add_payment", 1, 1); print "
'.$langs->trans("PaymentMode").''; - $form->select_types_paiements(isset($_POST["fk_typepayment"])?$_POST["fk_typepayment"]:$expensereport->fk_typepayment, "fk_typepayment"); + $form->select_types_paiements(GETPOSTISSET("fk_typepayment") ? GETPOST("fk_typepayment", 'alpha') : $expensereport->fk_c_paiement, "fk_typepayment"); print "
'.$langs->trans('AccountToDebit').''; - $form->select_comptes(isset($_POST["accountid"])?$_POST["accountid"]:$expensereport->accountid, "accountid", 0, '', 1); // Show open bank account list + $form->select_comptes(GETPOSTISSET("accountid") ? GETPOST("accountid", "int") : $expensereport->accountid, "accountid", 0, '', 1); // Show open bank account list print '
'.$langs->trans("FilteredFields").'
'.$langs->trans("FilteredFields").''.(!empty($list) ? $list : $langs->trans("None")).''.(!empty($list) ? $list : ''.$langs->trans("None").'').'
'; - if ($sqlusedforexport && $user->admin) { - print ''; + print info_admin($langs->trans("SQLUsedForExport").':
'.$sqlusedforexport, 0, 0, 1, '', 'TechnicalInformation'); } - print '
'; - print info_admin($langs->trans("SQLUsedForExport").':
'.$sqlusedforexport); - print '
'; if (!is_dir($conf->export->dir_temp)) dol_mkdir($conf->export->dir_temp); // Show existing generated documents // NB: La fonction show_documents rescanne les modules qd genallowed=1, sinon prend $liste - print $formfile->showdocuments('export', '', $upload_dir, $_SERVER["PHP_SELF"].'?step=5&datatoexport='.$datatoexport, $liste, 1, (!empty($_POST['model']) ? $_POST['model'] : 'csv'), 1, 1, 0, 0, 0, '', ' ', '', '', ''); + print $formfile->showdocuments('export', '', $upload_dir, $_SERVER["PHP_SELF"].'?step=5&datatoexport='.$datatoexport, $liste, 1, (!empty($_POST['model']) ? $_POST['model'] : 'csv'), 1, 1, 0, 0, 0, '', 'none', '', '', ''); } llxFooter(); diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index c096a889ab4..ad96829d7b9 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -96,6 +96,8 @@ if ($id > 0 || !empty($ref)) $permissionnote = $user->rights->ficheinter->creer; // Used by the include of actions_setnotes.inc.php $permissiondellink = $user->rights->ficheinter->creer; // Used by the include of actions_dellink.inc.php +$error = 0; + /* * Actions @@ -284,99 +286,100 @@ if (empty($reshook)) $lines = $srcobject->lines; } - $fk_parent_line = 0; - $num = count($lines); + if (is_array($lines)) { + $num = count($lines); - for ($i = 0; $i < $num; $i++) - { - $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : Product::TYPE_PRODUCT); + for ($i = 0; $i < $num; $i++) + { + $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : Product::TYPE_PRODUCT); - if ($product_type == Product::TYPE_SERVICE || !empty($conf->global->FICHINTER_PRINT_PRODUCTS)) { //only services except if config includes products - $duration = 3600; // Default to one hour + if ($product_type == Product::TYPE_SERVICE || !empty($conf->global->FICHINTER_PRINT_PRODUCTS)) { //only services except if config includes products + $duration = 3600; // Default to one hour - // Predefined products & services - if ($lines[$i]->fk_product > 0) - { - $prod = new Product($db); - $prod->id = $lines[$i]->fk_product; + // Predefined products & services + if ($lines[$i]->fk_product > 0) + { + $prod = new Product($db); + $prod->id = $lines[$i]->fk_product; - // Define output language - if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { - $prod->getMultiLangs(); - // We show if duration is present on service (so we get it) - $prod->fetch($lines[$i]->fk_product); - $outputlangs = $langs; - $newlang = ''; - if (empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09'); - if (empty($newlang)) $newlang = $srcobject->thirdparty->default_lang; - if (!empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); + // Define output language + if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + $prod->getMultiLangs(); + // We show if duration is present on service (so we get it) + $prod->fetch($lines[$i]->fk_product); + $outputlangs = $langs; + $newlang = ''; + if (empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09'); + 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; + } else { + $prod->fetch($lines[$i]->fk_product); + $label = $lines[$i]->product_label; } - $label = (!empty($prod->multilangs[$outputlangs->defaultlang]["libelle"])) ? $prod->multilangs[$outputlangs->defaultlang]["libelle"] : $lines[$i]->product_label; - } else { - $prod->fetch($lines[$i]->fk_product); - $label = $lines[$i]->product_label; - } - if ($prod->duration_value && $conf->global->FICHINTER_USE_SERVICE_DURATION) { - switch ($prod->duration_unit) { - default: - case 'h': - $mult = 3600; - break; - case 'd': - $mult = 3600 * 24; - break; - case 'w': - $mult = 3600 * 24 * 7; - break; - case 'm': - $mult = (int) 3600 * 24 * (365 / 12); // Average month duration - break; - case 'y': - $mult = 3600 * 24 * 365; - break; + if ($prod->duration_value && $conf->global->FICHINTER_USE_SERVICE_DURATION) { + switch ($prod->duration_unit) { + default: + case 'h': + $mult = 3600; + break; + case 'd': + $mult = 3600 * 24; + break; + case 'w': + $mult = 3600 * 24 * 7; + break; + case 'm': + $mult = (int) 3600 * 24 * (365 / 12); // Average month duration + break; + case 'y': + $mult = 3600 * 24 * 365; + break; + } + $duration = $prod->duration_value * $mult * $lines[$i]->qty; } - $duration = $prod->duration_value * $mult * $lines[$i]->qty; - } - $desc = $lines[$i]->product_ref; - $desc .= ' - '; - $desc .= $label; + $desc = $lines[$i]->product_ref; + $desc .= ' - '; + $desc .= $label; + $desc .= '
'; + } + // Common part (predefined or free line) + $desc .= dol_htmlentitiesbr($lines[$i]->desc); $desc .= '
'; - } - // Common part (predefined or free line) - $desc .= dol_htmlentitiesbr($lines[$i]->desc); - $desc .= '
'; - $desc .= ' ('.$langs->trans('Quantity').': '.$lines[$i]->qty.')'; + $desc .= ' ('.$langs->trans('Quantity').': '.$lines[$i]->qty.')'; - $timearray = dol_getdate(mktime()); - $date_intervention = dol_mktime(0, 0, 0, $timearray['mon'], $timearray['mday'], $timearray['year']); + $timearray = dol_getdate(dol_now()); + $date_intervention = dol_mktime(0, 0, 0, $timearray['mon'], $timearray['mday'], $timearray['year']); - if ($product_type == Product::TYPE_PRODUCT) { - $duration = 0; - } + if ($product_type == Product::TYPE_PRODUCT) { + $duration = 0; + } - $predef = ''; + $predef = ''; - // Extrafields - $extrafields->fetch_name_optionals_label($object->table_element_line); - $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef); + // Extrafields + $extrafields->fetch_name_optionals_label($object->table_element_line); + $array_options = $extrafields->getOptionalsFromPost($object->table_element_line, $predef); - $result = $object->addline( - $user, - $id, - $desc, - $date_intervention, - $duration, - $array_options - ); + $result = $object->addline( + $user, + $id, + $desc, + $date_intervention, + $duration, + $array_options + ); - if ($result < 0) - { - $error++; - break; + if ($result < 0) + { + $error++; + break; + } } } } @@ -818,10 +821,7 @@ llxHeader('', $langs->trans("Intervention")); if ($action == 'create') { - /* - * Mode creation - * Creation d'une nouvelle fiche d'intervention - */ + // Create new intervention $soc = new Societe($db); @@ -831,11 +831,12 @@ if ($action == 'create') if ($socid) $res = $soc->fetch($socid); - if (GETPOST('origin') && GETPOST('originid')) + if (GETPOST('origin', 'alphanohtml') && GETPOST('originid', 'int')) { // Parse element/subelement (ex: project_task) - $element = $subelement = GETPOST('origin'); - if (preg_match('/^([^_]+)_([^_]+)/i', GETPOST('origin'), $regs)) + $regs = array(); + $element = $subelement = GETPOST('origin', 'alphanohtml'); + if (preg_match('/^([^_]+)_([^_]+)/i', GETPOST('origin', 'alphanohtml'), $regs)) { $element = $regs[1]; $subelement = $regs[2]; @@ -843,7 +844,7 @@ if ($action == 'create') if ($element == 'project') { - $projectid = GETPOST('originid'); + $projectid = GETPOST('originid', 'int'); } else { @@ -941,7 +942,7 @@ if ($action == 'create') $numprojet = $formproject->select_projects($soc->id, $projectid, 'projectid'); if ($numprojet == 0) { - print '  
'.$langs->trans("AddProject").''; + print '   '; } print ''; } @@ -954,7 +955,7 @@ if ($action == 'create') $numcontrat = $formcontract->select_contract($soc->id, GETPOST('contratid', 'int'), 'contratid', 0, 1); if ($numcontrat == 0) { - print '   '.$langs->trans("AddContract").''; + print '   '; } print ''; } @@ -1063,9 +1064,11 @@ if ($action == 'create') } else { + print '
'; + print ''; + dol_fiche_head(''); - print ''; if (is_object($objectsrc)) { print ''; @@ -1076,6 +1079,7 @@ if ($action == 'create') print ''; print ''; print '
'.$langs->trans("ThirdParty").''; print $form->select_company('', 'socid', '', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300'); + print ' '; print '
'; diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index 9f180fc24b0..1ae4364a77d 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -36,6 +36,35 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; */ class Fichinter extends CommonObject { + + public $fields=array( + 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), + 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>15), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>20), + 'fk_contrat' =>array('type'=>'integer', 'label'=>'Fk contrat', 'enabled'=>1, 'visible'=>-1, 'position'=>25), + 'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>30), + 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>35), + 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>40, 'index'=>1), + 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>45), + 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>50), + 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>55), + 'datei' =>array('type'=>'date', 'label'=>'Datei', 'enabled'=>1, 'visible'=>-1, 'position'=>60), + 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>65), + 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>70), + 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>75), + 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Fk statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500), + 'dateo' =>array('type'=>'date', 'label'=>'Dateo', 'enabled'=>1, 'visible'=>-1, 'position'=>85), + 'datee' =>array('type'=>'date', 'label'=>'Datee', 'enabled'=>1, 'visible'=>-1, 'position'=>90), + 'datet' =>array('type'=>'date', 'label'=>'Datet', 'enabled'=>1, 'visible'=>-1, 'position'=>95), + 'duree' =>array('type'=>'double', 'label'=>'Duree', 'enabled'=>1, 'visible'=>-1, 'position'=>100), + 'description' =>array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>105,'showoncombobox'=>1), + 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>110), + 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>115), + 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>120), + 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>125), + 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>130), + 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>135), + ); /** * @var string ID to identify managed object */ @@ -544,7 +573,7 @@ class Fichinter extends CommonObject { $num = $this->ref; } - $this->newref = $num; + $this->newref = dol_sanitizeFileName($num); $sql = "UPDATE ".MAIN_DB_PREFIX."fichinter"; $sql .= " SET fk_statut = 1"; @@ -753,8 +782,10 @@ class Fichinter extends CommonObject $result = ''; $label = ''.$langs->trans("ShowIntervention").''; - if (!empty($this->ref)) - $label .= '
'.$langs->trans('Ref').': '.$this->ref; + $label .= '
'.$langs->trans('Ref').': '.$this->ref; + if (isset($this->statut)) { + $label .= '
'.$langs->trans("Status").": ".$this->getLibStatut(5); + } $url = DOL_URL_ROOT.'/fichinter/card.php?id='.$this->id; diff --git a/htdocs/fichinter/class/fichinterrec.class.php b/htdocs/fichinter/class/fichinterrec.class.php index 92a42d1ffdf..4a6dab2dd8c 100644 --- a/htdocs/fichinter/class/fichinterrec.class.php +++ b/htdocs/fichinter/class/fichinterrec.class.php @@ -243,10 +243,9 @@ class FichinterRec extends Fichinter * @param int $rowid Id of object to load * @param string $ref Reference of fichinter * @param string $ref_ext External reference of fichinter - * @param int $ref_int Internal reference of other object * @return int >0 if OK, <0 if KO, 0 if not found */ - public function fetch($rowid = 0, $ref = '', $ref_ext = '', $ref_int = '') + public function fetch($rowid = 0, $ref = '', $ref_ext = '') { $sql = 'SELECT f.titre, f.fk_soc'; $sql .= ', f.datec, f.duree, f.fk_projet, f.fk_contrat, f.description'; @@ -258,11 +257,6 @@ class FichinterRec extends Fichinter if ($rowid > 0) $sql .= ' WHERE f.rowid='.$rowid; elseif ($ref) $sql .= " WHERE f.titre='".$this->db->escape($ref)."'"; - /* This field are not used for template fichinter - if ($ref_ext) $sql.= " AND f.ref_ext='".$this->db->escape($ref_ext)."'"; - if ($ref_int) $sql.= " AND f.ref_int='".$this->db->escape($ref_int)."'"; - */ - dol_syslog(get_class($this)."::fetch rowid=".$rowid, LOG_DEBUG); $result = $this->db->query($sql); diff --git a/htdocs/fichinter/class/fichinterstats.class.php b/htdocs/fichinter/class/fichinterstats.class.php index 98eb218e9ef..0a4daa03955 100644 --- a/htdocs/fichinter/class/fichinterstats.class.php +++ b/htdocs/fichinter/class/fichinterstats.class.php @@ -191,10 +191,11 @@ class FichinterStats extends Stats /** * Return nb, amount of predefined product for year * - * @param int $year Year to scan - * @return array Array of values + * @param int $year Year to scan + * @param int $limit Limit + * @return array Array of values */ - public function getAllByProduct($year) + public function getAllByProduct($year, $limit = 0) { global $user; @@ -208,6 +209,6 @@ class FichinterStats extends Stats $sql.= $this->db->order('nb', 'DESC'); //$sql.= $this->db->plimit(20); - return $this->_getAllByProduct($sql); + return $this->_getAllByProduct($sql, $limit); } } diff --git a/htdocs/fichinter/index.php b/htdocs/fichinter/index.php index cd18699ccdb..6bde087fa61 100644 --- a/htdocs/fichinter/index.php +++ b/htdocs/fichinter/index.php @@ -140,10 +140,10 @@ if ($resql) include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; $dolgraph = new DolGraph(); $dolgraph->SetData($dataseries); - $dolgraph->setShowLegend(1); + $dolgraph->setShowLegend(2); $dolgraph->setShowPercent(1); $dolgraph->SetType(array('pie')); - $dolgraph->setWidth('100%'); + $dolgraph->setHeight('200'); $dolgraph->draw('idgraphstatus'); print $dolgraph->show($total ? 0 : 1); $data = array('series'=>$dataseries); diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 03000bdb44d..71e251fd9e7 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -204,7 +204,7 @@ foreach ($arrayfields as $tmpkey => $tmpval) $sql = "SELECT"; $sql .= " f.ref, f.rowid, f.fk_statut, f.description, f.datec as date_creation, f.tms as date_update, f.note_private,"; if (empty($conf->global->FICHINTER_DISABLE_DETAILS) && $atleastonefieldinlines) $sql .= "fd.rowid as lineid, fd.description as descriptiondetail, fd.date as dp, fd.duree,"; -$sql .= " s.nom as name, s.rowid as socid, s.client"; +$sql .= " s.nom as name, s.rowid as socid, s.client, s.fournisseur, s.email, s.status as thirdpartystatus"; if (!empty($conf->projet->enabled)) { $sql .= ", pr.rowid as projet_id, pr.ref as projet_ref, pr.title as projet_title"; } @@ -479,6 +479,13 @@ if ($resql) $objectstatic->ref = $obj->ref; $objectstatic->statut = $obj->fk_statut; + $companystatic->name=$obj->name; + $companystatic->id=$obj->socid; + $companystatic->client=$obj->client; + $companystatic->fournisseur=$obj->fournisseur; + $companystatic->email=$obj->email; + $companystatic->status=$obj->thirdpartystatus; + print ''; if (!empty($arrayfields['f.ref']['checked'])) @@ -521,9 +528,6 @@ if ($resql) if (! empty($arrayfields['s.nom']['checked'])) { print ''; - $companystatic->name=$obj->name; - $companystatic->id=$obj->socid; - $companystatic->client=$obj->client; print $companystatic->getNomUrl(1, '', 44); print ''; if (! $i) $totalarray['nbfield']++; diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index 18e2992930c..d8f7dad8ac0 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -165,7 +165,8 @@ if (! defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck)) if ($csrfattack) { //print 'NOCSRFCHECK='.defined('NOCSRFCHECK').' REQUEST_METHOD='.$_SERVER['REQUEST_METHOD'].' HTTP_HOST='.$_SERVER['HTTP_HOST'].' HTTP_REFERER='.$_SERVER['HTTP_REFERER']; - print "Access refused by CSRF protection in main.inc.php. Referer of form (".$_SERVER['HTTP_REFERER'].") is outside the server that serve this page (with method = ".$_SERVER['REQUEST_METHOD'].").\n"; + // Note: We can't use dol_escape_htmltag here to escape output because lib functions.lib.ph is not yet loaded. + print "Access refused by CSRF protection in main.inc.php. Referer of form (".htmlentities($_SERVER['HTTP_REFERER'], ENT_COMPAT, 'UTF-8').") is outside the server that serve this page (with method = ".htmlentities($_SERVER['REQUEST_METHOD'], ENT_COMPAT, 'UTF-8').").\n"; print "If you access your server behind a proxy using url rewriting, you might check that all HTTP headers are propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file to remove this security check).\n"; die; } diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index 23031d09d90..8051b9684f9 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -809,16 +809,6 @@ if ($object->id > 0) } } - if ($user->rights->fournisseur->facture->creer) - { - $langs->load("bills"); - if ($object->status == 1) { - print ''.$langs->trans("AddBill").''; - } else { - print ''.$langs->trans("AddBill").''; - } - } - if ($user->rights->fournisseur->facture->creer) { if (!empty($orders2invoice) && $orders2invoice > 0) @@ -836,6 +826,16 @@ if ($object->id > 0) else print ''; } + if ($user->rights->fournisseur->facture->creer) + { + $langs->load("bills"); + if ($object->status == 1) { + print ''.$langs->trans("AddBill").''; + } else { + print ''.$langs->trans("AddBill").''; + } + } + // Add action if (!empty($conf->agenda->enabled) && !empty($conf->global->MAIN_REPEATTASKONEACHTAB) && $object->status == 1) { diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 21e5e82c13b..204471bc9e7 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -194,8 +194,8 @@ class SupplierInvoices extends DolibarrApi * * @return int ID of supplier invoice * - * @throws 401 - * @throws 500 + * @throws RestException 401 + * @throws RestException 500 */ public function post($request_data = null) { @@ -226,8 +226,8 @@ class SupplierInvoices extends DolibarrApi * * @return int * - * @throws 401 - * @throws 404 + * @throws RestException 401 + * @throws RestException 404 */ public function put($id, $request_data = null) { @@ -262,9 +262,9 @@ class SupplierInvoices extends DolibarrApi * * @return array * - * @throws 401 - * @throws 404 - * @throws 500 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 500 */ public function delete($id) { @@ -304,11 +304,11 @@ class SupplierInvoices extends DolibarrApi * * @return array * - * @throws 304 - * @throws 401 - * @throws 404 - * @throws 405 - * @throws 500 + * @throws RestException 304 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 + * @throws RestException 500 */ public function validate($id, $idwarehouse = 0, $notrigger = 0) { @@ -348,10 +348,10 @@ class SupplierInvoices extends DolibarrApi * @url GET {id}/payments * * @return array - * @throws 400 - * @throws 401 - * @throws 404 - * @throws 405 + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 + * @throws RestException 405 */ public function getPayments($id) { @@ -396,9 +396,9 @@ class SupplierInvoices extends DolibarrApi * @url POST {id}/payments * * @return int Payment ID - * @throws 400 - * @throws 401 - * @throws 404 + * @throws RestException 400 + * @throws RestException 401 + * @throws RestException 404 */ public function addPayment($id, $datepaye, $paiementid, $closepaidinvoices, $accountid, $num_paiement = '', $comment = '', $chqemetteur = '', $chqbank = '') { diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php index 37ac4c55e9d..cb2e27b1a97 100644 --- a/htdocs/fourn/class/api_supplier_orders.class.php +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -252,8 +252,8 @@ class SupplierOrders extends DolibarrApi /** * Delete supplier order * - * @param int $id Supplier order ID - * @return type + * @param int $id Supplier order ID + * @return array Array of result */ public function delete($id) { diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index bd74d52a4d5..9197c14be5c 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -183,6 +183,60 @@ class CommandeFournisseur extends CommonOrder public $multicurrency_total_tva; public $multicurrency_total_ttc; + + + public $fields = array( + 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), + 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>15), + 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>20), + 'ref' =>array('type'=>'varchar(255)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'showoncombobox'=>1, 'position'=>25), + 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>30, 'index'=>1), + 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>35), + 'ref_supplier' =>array('type'=>'varchar(255)', 'label'=>'RefSupplier', 'enabled'=>1, 'visible'=>-1, 'position'=>40), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>45), + 'date_creation' =>array('type'=>'datetime', 'label'=>'Date creation', 'enabled'=>1, 'visible'=>-1, 'position'=>50), + 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>55), + 'date_approve' =>array('type'=>'datetime', 'label'=>'Date approve', 'enabled'=>1, 'visible'=>-1, 'position'=>60), + 'date_approve2' =>array('type'=>'datetime', 'label'=>'Date approve2', 'enabled'=>1, 'visible'=>-1, 'position'=>65), + 'date_commande' =>array('type'=>'date', 'label'=>'Date commande', 'enabled'=>1, 'visible'=>-1, 'position'=>70), + 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>75), + 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>80), + 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>85), + 'fk_user_approve' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserApproval', 'enabled'=>1, 'visible'=>-1, 'position'=>90), + 'fk_user_approve2' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserSecondApproval', 'enabled'=>1, 'visible'=>-1, 'position'=>95), + 'source' =>array('type'=>'smallint(6)', 'label'=>'Source', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>100), + 'billed' =>array('type'=>'smallint(6)', 'label'=>'Billed', 'enabled'=>1, 'visible'=>-1, 'position'=>110), + 'amount_ht' =>array('type'=>'double(24,8)', 'label'=>'Amount ht', 'enabled'=>1, 'visible'=>-1, 'position'=>115), + 'remise_percent' =>array('type'=>'double', 'label'=>'Remise percent', 'enabled'=>1, 'visible'=>-1, 'position'=>120), + 'remise' =>array('type'=>'double', 'label'=>'Remise', 'enabled'=>1, 'visible'=>-1, 'position'=>125), + 'tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>-1, 'position'=>130, 'isameasure'=>1), + 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>135, 'isameasure'=>1), + 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>140, 'isameasure'=>1), + 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>145, 'isameasure'=>1), + 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>150, 'isameasure'=>1), + 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>155), + 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>160), + 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'ModelPDF', 'enabled'=>1, 'visible'=>0, 'position'=>165), + 'fk_input_method' =>array('type'=>'integer', 'label'=>'InputMethod', 'enabled'=>1, 'visible'=>-1, 'position'=>170), + 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'position'=>175), + 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>-1, 'position'=>180), + 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>190), + 'date_livraison' =>array('type'=>'datetime', 'label'=>'DeliveryDate', 'enabled'=>1, 'visible'=>-1, 'position'=>195), + 'fk_account' =>array('type'=>'integer', 'label'=>'Fk account', 'enabled'=>1, 'visible'=>-1, 'position'=>200), + 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>1, 'visible'=>-1, 'position'=>205), + 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermLocation', 'enabled'=>1, 'visible'=>-1, 'position'=>210), + 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'Fk multicurrency', 'enabled'=>1, 'visible'=>-1, 'position'=>215), + 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCode', 'enabled'=>1, 'visible'=>-1, 'position'=>220), + 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>1, 'visible'=>-1, 'position'=>225), + 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>230), + 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalVAT', 'enabled'=>1, 'visible'=>-1, 'position'=>235), + 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>240), + 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>-1, 'position'=>245), + 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'position'=>500), + 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900), + ); + + /** * Draft status */ @@ -387,6 +441,7 @@ class CommandeFournisseur extends CommonOrder */ public function fetch_lines($only_product = 0) { + global $conf; // phpcs:enable //$result=$this->fetch_lines(); $this->lines = array(); @@ -399,8 +454,12 @@ class CommandeFournisseur extends CommonOrder $sql .= " l.fk_unit,"; $sql .= " l.date_start, l.date_end,"; $sql .= ' l.fk_multicurrency, l.multicurrency_code, l.multicurrency_subprice, l.multicurrency_total_ht, l.multicurrency_total_tva, l.multicurrency_total_ttc'; + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) + $sql .= ", pfp.rowid as fk_pfp, pfp.packaging"; $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as l"; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON l.fk_product = pfp.fk_product and l.ref = pfp.ref_fourn"; $sql .= " WHERE l.fk_commande = ".$this->id; if ($only_product) $sql .= ' AND p.fk_product_type = 0'; $sql .= " ORDER BY l.rang, l.rowid"; @@ -451,7 +510,13 @@ class CommandeFournisseur extends CommonOrder $line->ref_fourn = $objp->ref_supplier; // The supplier ref of price when product was added. May have change since $line->ref_supplier = $objp->ref_supplier; // The supplier ref of price when product was added. May have change since - $line->date_start = $this->db->jdate($objp->date_start); + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) + { + $line->fk_fournprice = $objp->fk_pfp; + $line->packaging = $objp->packaging; + } + + $line->date_start = $this->db->jdate($objp->date_start); $line->date_end = $this->db->jdate($objp->date_end); $line->fk_unit = $objp->fk_unit; @@ -522,7 +587,7 @@ class CommandeFournisseur extends CommonOrder { $num = $this->ref; } - $this->newref = $num; + $this->newref = dol_sanitizeFileName($num); $sql = 'UPDATE '.MAIN_DB_PREFIX."commande_fournisseur"; $sql .= " SET ref='".$this->db->escape($num)."',"; @@ -906,7 +971,7 @@ class CommandeFournisseur extends CommonOrder { $num = $this->ref; } - $this->newref = $num; + $this->newref = dol_sanitizeFileName($num); // Do we have to change status now ? (If double approval is required and first approval, we keep status to 1 = validated) $movetoapprovestatus = true; @@ -1310,7 +1375,7 @@ class CommandeFournisseur extends CommonOrder false, $this->lines[$i]->date_start, $this->lines[$i]->date_end, - 0, + $this->lines[$i]->array_options, $this->lines[$i]->fk_unit ); if ($result < 0) @@ -1420,9 +1485,9 @@ class CommandeFournisseur extends CommonOrder $this->db->begin(); - // get lines so they will be clone - foreach ($this->lines as $line) - $line->fetch_optionals(); + // get extrafields so they will be clone + foreach($this->lines as $line) + $line->fetch_optionals(); // Load source object $objFrom = clone $this; @@ -1631,6 +1696,26 @@ class CommandeFournisseur extends CommonOrder return -1; } } + + // redefine quantity according to packaging + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) + { + $prod = new Product($this->db, $fk_product); + $prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, 'none', ($this->fk_soc ? $this->fk_soc : $this->socid)); + if ($qty < $prod->packaging) + { + $qty = $prod->packaging; + } + else + { + if (($qty % $prod->packaging) > 0) + { + $coeff = intval($qty / $prod->packaging) + 1; + $qty = $prod->packaging * $coeff; + setEventMessage($langs->trans('QtyRecalculatedWithPackaging'), 'mesgs'); + } + } + } } else { @@ -2582,6 +2667,25 @@ class CommandeFournisseur extends CommonOrder $this->line->fk_commande = $this->id; //$this->line->label=$label; $this->line->desc = $desc; + + // redefine quantity according to packaging + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) + { + if ($qty < $this->line->packaging) + { + $qty = $this->line->packaging; + } + else + { + if (($qty % $this->line->packaging) > 0) + { + $coeff = intval($qty / $this->line->packaging) + 1; + $qty = $this->line->packaging * $coeff; + setEventMessage($langs->trans('QtyRecalculatedWithPackaging'), 'mesgs'); + } + } + } + $this->line->qty = $qty; $this->line->ref_supplier = $ref_supplier; @@ -3336,6 +3440,8 @@ class CommandeFournisseurLigne extends CommonOrderLine */ public function fetch($rowid) { + global $conf; + $sql = 'SELECT cd.rowid, cd.fk_commande, cd.fk_product, cd.product_type, cd.description, cd.qty, cd.tva_tx, cd.special_code,'; $sql .= ' cd.localtax1_tx, cd.localtax2_tx, cd.localtax1_type, cd.localtax2_type, cd.ref,'; $sql .= ' cd.remise, cd.remise_percent, cd.subprice,'; @@ -3344,8 +3450,12 @@ class CommandeFournisseurLigne extends CommonOrderLine $sql .= ' p.ref as product_ref, p.label as product_libelle, p.description as product_desc,'; $sql .= ' cd.date_start, cd.date_end, cd.fk_unit,'; $sql .= ' cd.multicurrency_subprice, cd.multicurrency_total_ht, cd.multicurrency_total_tva, cd.multicurrency_total_ttc'; + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) + $sql .= ", pfp.rowid as fk_pfp, pfp.packaging"; $sql .= ' FROM '.MAIN_DB_PREFIX.'commande_fournisseurdet as cd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid'; + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON cd.fk_product = pfp.fk_product and cd.ref = pfp.ref_fourn"; $sql .= ' WHERE cd.rowid = '.$rowid; $result = $this->db->query($sql); if ($result) @@ -3383,6 +3493,11 @@ class CommandeFournisseurLigne extends CommonOrderLine $this->product_ref = $objp->product_ref; $this->product_libelle = $objp->product_libelle; $this->product_desc = $objp->product_desc; + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) + { + $this->packaging = $objp->packaging; + $this->fk_fournprice = $objp->fk_pfp; + } $this->date_start = $this->db->jdate($objp->date_start); $this->date_end = $this->db->jdate($objp->date_end); diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 231a5e9e910..d54e2da4eb1 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -217,6 +217,59 @@ class FactureFournisseur extends CommonInvoice */ public $fk_facture_source; + + public $fields = array( + 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), + 'ref' =>array('type'=>'varchar(255)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>15), + 'ref_supplier' =>array('type'=>'varchar(255)', 'label'=>'RefSupplier', 'enabled'=>1, 'visible'=>-1, 'position'=>20), + 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>25, 'index'=>1), + 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'RefExt', 'enabled'=>1, 'visible'=>0, 'position'=>30), + 'type' =>array('type'=>'smallint(6)', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35), + 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>40), + 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>45), + 'datef' =>array('type'=>'date', 'label'=>'Date', 'enabled'=>1, 'visible'=>-1, 'position'=>50), + 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>55), + 'libelle' =>array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>-1, 'position'=>60), + 'paye' =>array('type'=>'smallint(6)', 'label'=>'Paye', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>65), + 'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>70), + 'remise' =>array('type'=>'double(24,8)', 'label'=>'Discount', 'enabled'=>1, 'visible'=>-1, 'position'=>75), + 'close_code' =>array('type'=>'varchar(16)', 'label'=>'CloseCode', 'enabled'=>1, 'visible'=>-1, 'position'=>80), + 'close_note' =>array('type'=>'varchar(128)', 'label'=>'CloseNote', 'enabled'=>1, 'visible'=>-1, 'position'=>85), + 'tva' =>array('type'=>'double(24,8)', 'label'=>'Tva', 'enabled'=>1, 'visible'=>-1, 'position'=>90), + 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'Localtax1', 'enabled'=>1, 'visible'=>-1, 'position'=>95), + 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'Localtax2', 'enabled'=>1, 'visible'=>-1, 'position'=>100), + 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'TotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>105), + 'total_tva' =>array('type'=>'double(24,8)', 'label'=>'TotalVAT', 'enabled'=>1, 'visible'=>-1, 'position'=>110), + 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>115), + 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>125), + 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>130), + 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>135), + 'fk_facture_source' =>array('type'=>'integer', 'label'=>'Fk facture source', 'enabled'=>1, 'visible'=>-1, 'position'=>140), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>1, 'visible'=>-1, 'position'=>145), + 'fk_account' =>array('type'=>'integer', 'label'=>'Account', 'enabled'=>1, 'visible'=>-1, 'position'=>150), + 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'position'=>155), + 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>-1, 'position'=>160), + 'date_lim_reglement' =>array('type'=>'date', 'label'=>'DateLimReglement', 'enabled'=>1, 'visible'=>-1, 'position'=>165), + 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>170), + 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>175), + 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'ModelPdf', 'enabled'=>1, 'visible'=>0, 'position'=>180), + 'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>190), + 'fk_incoterms' =>array('type'=>'integer', 'label'=>'IncotermCode', 'enabled'=>1, 'visible'=>-1, 'position'=>195), + 'location_incoterms' =>array('type'=>'varchar(255)', 'label'=>'IncotermLocation', 'enabled'=>1, 'visible'=>-1, 'position'=>200), + 'fk_multicurrency' =>array('type'=>'integer', 'label'=>'MulticurrencyId', 'enabled'=>1, 'visible'=>-1, 'position'=>205), + 'multicurrency_code' =>array('type'=>'varchar(255)', 'label'=>'MulticurrencyCode', 'enabled'=>1, 'visible'=>-1, 'position'=>210), + 'multicurrency_tx' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyRate', 'enabled'=>1, 'visible'=>-1, 'position'=>215), + 'multicurrency_total_ht' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalHT', 'enabled'=>1, 'visible'=>-1, 'position'=>220), + 'multicurrency_total_tva' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalVAT', 'enabled'=>1, 'visible'=>-1, 'position'=>225), + 'multicurrency_total_ttc' =>array('type'=>'double(24,8)', 'label'=>'MulticurrencyTotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>230), + 'date_pointoftax' =>array('type'=>'date', 'label'=>'Date pointoftax', 'enabled'=>1, 'visible'=>-1, 'position'=>235), + 'date_valid' =>array('type'=>'date', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>240), + 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>245), + 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), + 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900), + ); + + /** * Standard invoice */ @@ -1360,7 +1413,7 @@ class FactureFournisseur extends CommonInvoice { $num = $this->ref; } - $this->newref = $num; + $this->newref = dol_sanitizeFileName($num); $sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn"; $sql .= " SET ref='".$num."', fk_statut = 1, fk_user_valid = ".$user->id.", date_valid = '".$this->db->idate($now)."'"; @@ -1953,7 +2006,7 @@ class FactureFournisseur extends CommonInvoice if (is_array($array_options) && count($array_options) > 0) { // We replace values in this->line->array_options only for entries defined into $array_options foreach ($array_options as $key => $value) { - $this->line->array_options[$key] = $array_options[$key]; + $line->array_options[$key] = $array_options[$key]; } } @@ -2234,7 +2287,7 @@ class FactureFournisseur extends CommonInvoice if ($facturestatic->hasDelay()) { $response->nbtodolate++; - $response->url_late=DOL_URL_ROOT.'/fourn/facture/list.php?option=late&mainmenu=billing&leftmenu=suppliers_bills'; + $response->url_late = DOL_URL_ROOT.'/fourn/facture/list.php?option=late&mainmenu=billing&leftmenu=suppliers_bills'; } } $this->db->free($resql); @@ -2305,6 +2358,9 @@ class FactureFournisseur extends CommonInvoice elseif ($this->type == self::TYPE_CREDIT_NOTE) $label = $langs->transnoentitiesnoconv("ShowInvoiceAvoir").': '.$this->ref; elseif ($this->type == self::TYPE_DEPOSIT) $label = $langs->transnoentitiesnoconv("ShowInvoiceDeposit").': '.$this->ref; if ($moretitle) $label .= ' - '.$moretitle; + if (isset($this->statut) && isset($this->alreadypaid)) { + $label .= '
'.$langs->trans("Status").": ".$this->getLibStatut(5, $this->alreadypaid); + } $ref = $this->ref; if (empty($ref)) $ref = $this->id; diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 717a617b0ca..332e33ece59 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -273,6 +273,7 @@ class ProductFournisseur extends Product $charges = price2num($charges, 'MU'); $qty = price2num($qty, 'MS'); $unitBuyPrice = price2num($buyprice / $qty, 'MU'); + $packaging = ($this->packaging < $qty) ? $qty : $this->packaging; $error = 0; $now = dol_now(); @@ -359,6 +360,7 @@ class ProductFournisseur extends Product $sql .= " supplier_reputation = ".(empty($supplier_reputation) ? 'NULL' : "'".$this->db->escape($supplier_reputation)."'").","; $sql .= " barcode = ".(empty($barcode) ? 'NULL' : "'".$this->db->escape($barcode)."'").","; $sql .= " fk_barcode_type = ".(empty($fk_barcode_type) ? 'NULL' : "'".$this->db->escape($fk_barcode_type)."'"); + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", packaging = ".(empty($packaging) ? 1 : $packaging); $sql .= " WHERE rowid = ".$this->product_fourn_price_id; // TODO Add price_base_type and price_ttc @@ -408,6 +410,7 @@ class ProductFournisseur extends Product $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price("; $sql .= " multicurrency_price, multicurrency_unitprice, multicurrency_tx, fk_multicurrency, multicurrency_code,"; $sql .= "datec, fk_product, fk_soc, ref_fourn, desc_fourn, fk_user, price, quantity, remise_percent, remise, unitprice, tva_tx, charges, fk_availability, default_vat_code, info_bits, entity, delivery_time_days, supplier_reputation, barcode, fk_barcode_type)"; + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", packaging"; $sql .= " values("; $sql .= (isset($multicurrency_buyprice) ? "'".$this->db->escape(price2num($multicurrency_buyprice))."'" : 'null').","; $sql .= (isset($multicurrency_unitBuyPrice) ? "'".$this->db->escape(price2num($multicurrency_unitBuyPrice))."'" : 'null').","; @@ -435,13 +438,14 @@ class ProductFournisseur extends Product $sql .= (empty($supplier_reputation) ? 'NULL' : "'".$this->db->escape($supplier_reputation)."'").","; $sql .= (empty($barcode) ? 'NULL' : "'".$this->db->escape($barcode)."'").","; $sql .= (empty($fk_barcode_type) ? 'NULL' : "'".$this->db->escape($fk_barcode_type)."'"); + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", ".(empty($this->packaging) ? 1 : $this->db->escape($this->packaging)); $sql .= ")"; $this->product_fourn_price_id = 0; $resql = $this->db->query($sql); if ($resql) { - $this->product_fourn_price_id = $this->db->last_insert_id(MAIN_DB_PREFIX . "product_fournisseur_price"); + $this->product_fourn_price_id = $this->db->last_insert_id(MAIN_DB_PREFIX."product_fournisseur_price"); } else { $error++; @@ -501,6 +505,7 @@ class ProductFournisseur extends Product $sql .= " pfp.supplier_reputation, pfp.fk_user, pfp.datec,"; $sql .= " pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code,"; $sql .= " pfp.barcode, pfp.fk_barcode_type"; + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", pfp.packaging"; $sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; $sql .= " WHERE pfp.rowid = ".(int) $rowid; @@ -544,6 +549,12 @@ class ProductFournisseur extends Product $this->fourn_barcode = $obj->barcode; $this->fourn_fk_barcode_type = $obj->fk_barcode_type; } + + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { + $this->packaging = $obj->packaging; + if ($this->packaging < $this->fourn_qty) $this->packaging = $this->fourn_qty; + } + if (empty($ignore_expression) && !empty($this->fk_supplier_price_expression)) { $priceparser = new PriceParser($this->db); @@ -598,7 +609,8 @@ class ProductFournisseur extends Product $sql .= " pfp.price, pfp.quantity, pfp.unitprice, pfp.remise_percent, pfp.remise, pfp.tva_tx, pfp.fk_availability, pfp.charges, pfp.info_bits, pfp.delivery_time_days, pfp.supplier_reputation,"; $sql .= " pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code, pfp.datec, pfp.tms,"; $sql .= " pfp.barcode, pfp.fk_barcode_type"; - $sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp, ".MAIN_DB_PREFIX."societe as s"; + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", pfp.packaging"; + $sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp, ".MAIN_DB_PREFIX."societe as s"; $sql .= " WHERE pfp.entity IN (".getEntity('productsupplierprice').")"; $sql .= " AND pfp.fk_soc = s.rowid"; $sql .= " AND s.status=1"; // only enabled company selected @@ -647,6 +659,11 @@ class ProductFournisseur extends Product $prodfourn->fourn_multicurrency_id = $record["fk_multicurrency"]; $prodfourn->fourn_multicurrency_code = $record["multicurrency_code"]; + if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { + $prodfourn->packaging = $record["packaging"]; + if ($prodfourn->packaging < $prodfourn->fourn_qty) $prodfourn->packaging = $prodfourn->fourn_qty; + } + if ($conf->barcode->enabled) { $prodfourn->barcode = $record["barcode"]; $prodfourn->fk_barcode_type = $record["fk_barcode_type"]; diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 9adad176ab2..17d81c40c72 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -1661,8 +1661,8 @@ if ($action == 'create') $langs->load('projects'); print ''.$langs->trans('Project').''; - $formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1); - print '   id).'">'.$langs->trans("AddProject").''; + $formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) ? $societe->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 0, 0, 'maxwidth500'); + print '   id).'">'; print ''; } diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index eb9093888af..dd55bb36ffb 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -273,7 +273,7 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner) if (empty($conf->multicurrency->enabled) && empty($conf->dynamicprices->enabled)) { $dto = GETPOST("dto_".$reg[1].'_'.$reg[2]); //update supplier price - if (isset($_POST[$saveprice])) { + if (GETPOSTISSET($saveprice)) { // TODO Use class $sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price"; $sql .= " SET unitprice='".GETPOST($pu)."'"; diff --git a/htdocs/fourn/commande/index.php b/htdocs/fourn/commande/index.php index b09b67ba1d3..25c4868fd5e 100644 --- a/htdocs/fourn/commande/index.php +++ b/htdocs/fourn/commande/index.php @@ -137,10 +137,10 @@ if ($resql) include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; $dolgraph = new DolGraph(); $dolgraph->SetData($dataseries); - $dolgraph->setShowLegend(1); + $dolgraph->setShowLegend(2); $dolgraph->setShowPercent(1); $dolgraph->SetType(array('pie')); - $dolgraph->setWidth('100%'); + $dolgraph->setHeight('200'); $dolgraph->draw('idgraphstatus'); print $dolgraph->show($total ? 0 : 1); @@ -159,17 +159,14 @@ else /* * Legends / Status - * - * Motivo: Mostrar todos os Status e dar a possibilidade de filtrar apenas um deles - * Reason: Show all Status and give the possibility to filter only one */ -$sql = "SELECT count(cf.rowid), fk_statut"; +$sql = "SELECT count(cf.rowid) as nb, cf.fk_statut"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."commande_fournisseur as cf"; if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql .= " WHERE cf.fk_soc = s.rowid"; -$sql .= " AND s.entity = ".$conf->entity; +$sql .= " AND cf.entity IN (".getEntity("supplier_order").")"; // Thirdparty sharing is mandatory with supplier order sharing if ($user->socid) $sql .= ' AND cf.fk_soc = '.$user->socid; if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; $sql .= " GROUP BY cf.fk_statut"; @@ -189,11 +186,11 @@ if ($resql) while ($i < $num) { - $row = $db->fetch_row($resql); + $obj = $db->fetch_object($resql); print ''; - print ''.$commandestatic->LibStatut($row[1]).''; - print ''.$row[0].' '.$commandestatic->LibStatut($row[1], 3).''; + print ''.$commandestatic->LibStatut($obj->nb).''; + print ''.$obj->nb.' '.$commandestatic->LibStatut($obj->fk_statut, 3).''; print "\n"; $i++; @@ -218,7 +215,7 @@ if (!empty($conf->fournisseur->enabled)) $sql .= ", ".MAIN_DB_PREFIX."societe as s"; if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql .= " WHERE c.fk_soc = s.rowid"; - $sql .= " AND c.entity = ".$conf->entity; + $sql .= " AND c.entity IN (".getEntity("supplier_order").")"; // Thirdparty sharing is mandatory with supplier order sharing $sql .= " AND c.fk_statut = 0"; if (!empty($socid)) $sql .= " AND c.fk_soc = ".$socid; if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; @@ -254,17 +251,25 @@ if (!empty($conf->fournisseur->enabled)) /* * List of users allowed */ -$sql = "SELECT u.rowid, u.lastname, u.firstname, u.email"; -$sql .= " FROM ".MAIN_DB_PREFIX."user as u,"; -$sql .= " ".MAIN_DB_PREFIX."user_rights as ur"; -$sql .= ", ".MAIN_DB_PREFIX."rights_def as rd"; -$sql .= " WHERE u.rowid = ur.fk_user"; -$sql .= " AND (u.entity IN (0,".$conf->entity.")"; -$sql .= " AND rd.entity = ".$conf->entity.")"; -$sql .= " AND ur.fk_id = rd.id"; -$sql .= " AND module = 'fournisseur'"; -$sql .= " AND perms = 'commande'"; -$sql .= " AND subperms = 'approuver'"; + +$sql = "SELECT"; +if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { + $sql .= " DISTINCT"; +} +$sql .= " u.rowid, u.lastname, u.firstname, u.email, u.statut"; +$sql .= " FROM ".MAIN_DB_PREFIX."user as u"; +if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) +{ + $sql .= ",".MAIN_DB_PREFIX."usergroup_user as ug"; + $sql .= " WHERE ((ug.fk_user = u.rowid"; + $sql .= " AND ug.entity IN (".getEntity('usergroup')."))"; + $sql .= " OR u.entity = 0)"; // Show always superadmin +} +else +{ + $sql .= " WHERE (u.entity IN (".getEntity('user').")"; +} +$sql .= " AND u.fk_soc IS NULL"; // An external user can not approved $resql = $db->query($sql); if ($resql) @@ -281,15 +286,23 @@ if ($resql) { $obj = $db->fetch_object($resql); - print ''; - print ''; + $userstatic = new User($db); $userstatic->id = $obj->rowid; - $userstatic->lastname = $obj->lastname; - $userstatic->firstname = $obj->firstname; - $userstatic->email = $obj->email; - print $userstatic->getNomUrl(1); - print ''; - print "\n"; + $userstatic->getrights('fournisseur'); + + if (!empty($userstatic->rights->fournisseur->commande->approuver)) + { + print ''; + print ''; + $userstatic->lastname = $obj->lastname; + $userstatic->firstname = $obj->firstname; + $userstatic->email = $obj->email; + $userstatic->statut = $obj->statut; + print $userstatic->getNomUrl(1); + print ''; + print "\n"; + } + $i++; } print "

"; diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 71881d34103..78cb4ecf7c7 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -80,6 +80,11 @@ $search_sale = GETPOST('search_sale', 'int'); $search_total_ht = GETPOST('search_total_ht', 'alpha'); $search_total_vat = GETPOST('search_total_vat', 'alpha'); $search_total_ttc = GETPOST('search_total_ttc', 'alpha'); +$search_multicurrency_code = GETPOST('search_multicurrency_code', 'alpha'); +$search_multicurrency_tx = GETPOST('search_multicurrency_tx', 'alpha'); +$search_multicurrency_montant_ht = GETPOST('search_multicurrency_montant_ht', 'alpha'); +$search_multicurrency_montant_vat = GETPOST('search_multicurrency_montant_vat', 'alpha'); +$search_multicurrency_montant_ttc = GETPOST('search_multicurrency_montant_ttc', 'alpha'); $optioncss = GETPOST('optioncss', 'alpha'); $search_billed = GETPOST('search_billed', 'int'); $search_project_ref = GETPOST('search_project_ref', 'alpha'); @@ -146,6 +151,11 @@ $arrayfields = array( 'cf.total_ht'=>array('label'=>$langs->trans("AmountHT"), 'checked'=>1), 'cf.total_vat'=>array('label'=>$langs->trans("AmountVAT"), 'checked'=>0), 'cf.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>0), + 'cf.multicurrency_code'=>array('label'=>'Currency', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'cf.multicurrency_tx'=>array('label'=>'CurrencyRate', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'cf.multicurrency_total_ht'=>array('label'=>'MulticurrencyAmountHT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'cf.multicurrency_total_vat'=>array('label'=>'MulticurrencyAmountVAT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'cf.multicurrency_total_ttc'=>array('label'=>'MulticurrencyAmountTTC', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), 'cf.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), 'cf.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), 'cf.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), @@ -201,6 +211,11 @@ if (empty($reshook)) $search_total_ht = ''; $search_total_vat = ''; $search_total_ttc = ''; + $search_multicurrency_code = ''; + $search_multicurrency_tx = ''; + $search_multicurrency_montant_ht = ''; + $search_multicurrency_montant_vat = ''; + $search_multicurrency_montant_ttc = ''; $search_project_ref = ''; $search_status = -1; $search_orderyear = ''; @@ -485,6 +500,7 @@ $sql .= ' s.rowid as socid, s.nom as name, s.town, s.zip, s.fk_pays, s.client, s $sql .= " typent.code as typent_code,"; $sql .= " state.code_departement as state_code, state.nom as state_name,"; $sql .= " cf.rowid, cf.ref, cf.ref_supplier, cf.fk_statut, cf.billed, cf.total_ht, cf.tva as total_tva, cf.total_ttc, cf.fk_user_author, cf.date_commande as date_commande, cf.date_livraison as date_delivery,"; +$sql .= ' cf.fk_multicurrency, cf.multicurrency_code, cf.multicurrency_tx, cf.multicurrency_total_ht, cf.multicurrency_total_tva as multicurrency_total_vat, cf.multicurrency_total_ttc,'; $sql .= ' cf.date_creation as date_creation, cf.tms as date_update,'; $sql .= ' cf.note_public, cf.note_private,'; $sql .= " p.rowid as project_id, p.ref as project_ref, p.title as project_title,"; @@ -543,6 +559,11 @@ if ($search_user > 0) $sql .= " AND ec.fk_c_type_contact = tc.rowid AND tc.eleme if ($search_total_ht != '') $sql .= natural_search('cf.total_ht', $search_total_ht, 1); if ($search_total_vat != '') $sql .= natural_search('cf.tva', $search_total_vat, 1); if ($search_total_ttc != '') $sql .= natural_search('cf.total_ttc', $search_total_ttc, 1); +if ($search_multicurrency_code != '') $sql .= ' AND cf.multicurrency_code = "' . $db->escape($search_multicurrency_code) . '"'; +if ($search_multicurrency_tx != '') $sql .= natural_search('cf.multicurrency_tx', $search_multicurrency_tx, 1); +if ($search_multicurrency_montant_ht != '') $sql .= natural_search('cf.multicurrency_total_ht', $search_multicurrency_montant_ht, 1); +if ($search_multicurrency_montant_vat != '') $sql .= natural_search('cf.multicurrency_total_tva', $search_multicurrency_montant_vat, 1); +if ($search_multicurrency_montant_ttc != '') $sql .= natural_search('cf.multicurrency_total_ttc', $search_multicurrency_montant_ttc, 1); if ($search_project_ref != '') $sql .= natural_search("p.ref", $search_project_ref); // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; @@ -613,6 +634,11 @@ if ($resql) if ($search_sale > 0) $param .= '&search_sale='.$search_sale; if ($search_total_ht != '') $param .= '&search_total_ht='.$search_total_ht; if ($search_total_ttc != '') $param .= "&search_total_ttc=".$search_total_ttc; + if ($search_multicurrency_code != '') $param .= '&search_multicurrency_code='.urlencode($search_multicurrency_code); + if ($search_multicurrency_tx != '') $param .= '&search_multicurrency_tx='.urlencode($search_multicurrency_tx); + if ($search_multicurrency_montant_ht != '') $param .= '&search_multicurrency_montant_ht='.urlencode($search_multicurrency_montant_ht); + if ($search_multicurrency_montant_vat != '') $param .= '&search_multicurrency_montant_vat='.urlencode($search_multicurrency_montant_vat); + if ($search_multicurrency_montant_ttc != '') $param .= '&search_multicurrency_montant_ttc='.urlencode($search_multicurrency_montant_ttc); if ($search_refsupp) $param .= "&search_refsupp=".$search_refsupp; if ($search_status >= 0) $param .= "&search_status=".$search_status; if ($search_project_ref >= 0) $param .= "&search_project_ref=".$search_project_ref; @@ -844,6 +870,41 @@ if ($resql) print ''; print ''; } + if (!empty($arrayfields['cf.multicurrency_code']['checked'])) + { + // Currency + print ''; + print $form->selectMultiCurrency($search_multicurrency_code, 'search_multicurrency_code', 1); + print ''; + } + if (!empty($arrayfields['cf.multicurrency_tx']['checked'])) + { + // Currency rate + print ''; + print ''; + print ''; + } + if (!empty($arrayfields['cf.multicurrency_total_ht']['checked'])) + { + // Amount + print ''; + print ''; + print ''; + } + if (!empty($arrayfields['cf.multicurrency_total_vat']['checked'])) + { + // Amount + print ''; + print ''; + print ''; + } + if (!empty($arrayfields['cf.multicurrency_total_ttc']['checked'])) + { + // Amount + print ''; + print ''; + print ''; + } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; @@ -902,6 +963,11 @@ if ($resql) if (!empty($arrayfields['cf.total_ht']['checked'])) print_liste_field_titre($arrayfields['cf.total_ht']['label'], $_SERVER["PHP_SELF"], "cf.total_ht", "", $param, '', $sortfield, $sortorder, 'right '); if (!empty($arrayfields['cf.total_vat']['checked'])) print_liste_field_titre($arrayfields['cf.total_vat']['label'], $_SERVER["PHP_SELF"], "cf.tva", "", $param, '', $sortfield, $sortorder, 'right '); if (!empty($arrayfields['cf.total_ttc']['checked'])) print_liste_field_titre($arrayfields['cf.total_ttc']['label'], $_SERVER["PHP_SELF"], "cf.total_ttc", "", $param, '', $sortfield, $sortorder, 'right '); + if (!empty($arrayfields['cf.multicurrency_code']['checked'])) print_liste_field_titre($arrayfields['cf.multicurrency_code']['label'], $_SERVER['PHP_SELF'], 'cf.multicurrency_code', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['cf.multicurrency_tx']['checked'])) print_liste_field_titre($arrayfields['cf.multicurrency_tx']['label'], $_SERVER['PHP_SELF'], 'cf.multicurrency_tx', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['cf.multicurrency_total_ht']['checked'])) print_liste_field_titre($arrayfields['cf.multicurrency_total_ht']['label'], $_SERVER['PHP_SELF'], 'cf.multicurrency_total_ht', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['cf.multicurrency_total_vat']['checked'])) print_liste_field_titre($arrayfields['cf.multicurrency_total_vat']['label'], $_SERVER['PHP_SELF'], 'cf.multicurrency_total_tva', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['cf.multicurrency_total_ttc']['checked'])) print_liste_field_titre($arrayfields['cf.multicurrency_total_ttc']['label'], $_SERVER['PHP_SELF'], 'cf.multicurrency_total_ttc', '', $param, 'class="right"', $sortfield, $sortorder); // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields @@ -1086,6 +1152,40 @@ if ($resql) $totalarray['val']['cf.total_ttc'] += $obj->total_ttc; } + // Currency + if (!empty($arrayfields['cf.multicurrency_code']['checked'])) + { + print ''.$obj->multicurrency_code . ' - ' . $langs->trans('Currency' . $obj->multicurrency_code)."\n"; + if (!$i) $totalarray['nbfield']++; + } + + // Currency rate + if (!empty($arrayfields['cf.multicurrency_tx']['checked'])) + { + print ''; + $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $obj->rowid, $obj->multicurrency_tx, 'none', $obj->multicurrency_code); + print "\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount HT + if (!empty($arrayfields['cf.multicurrency_total_ht']['checked'])) + { + print ''.price($obj->multicurrency_total_ht)."\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount VAT + if (!empty($arrayfields['cf.multicurrency_total_vat']['checked'])) + { + print ''.price($obj->multicurrency_total_vat)."\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount TTC + if (!empty($arrayfields['cf.multicurrency_total_ttc']['checked'])) + { + print ''.price($obj->multicurrency_total_ttc)."\n"; + if (!$i) $totalarray['nbfield']++; + } + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index ffdfb07baa0..f901500cc6f 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -657,7 +657,7 @@ if (empty($reshook)) $_GET['socid'] = $_POST['socid']; $error++; } - if (!($_POST['fac_replacement'] > 0)) { + if (! (GETPOST('fac_replacement', 'int') > 0)) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ReplaceInvoice")), null, 'errors'); } @@ -870,7 +870,7 @@ if (empty($reshook)) if (!$error && $_POST['origin'] && $_POST['originid']) { // Parse element/subelement (ex: project_task) - $element = $subelement = GETPOST('origin'); + $element = $subelement = GETPOST('origin', 'alpha'); /*if (preg_match('/^([^_]+)_([^_]+)/i',$_POST['origin'],$regs)) { $element = $regs[1]; @@ -894,8 +894,8 @@ if (empty($reshook)) { $element = 'projet'; } - $object->origin = GETPOST('origin'); - $object->origin_id = GETPOST('originid'); + $object->origin = GETPOST('origin', 'alpha'); + $object->origin_id = GETPOST('originid', 'int'); require_once DOL_DOCUMENT_ROOT.'/'.$element.'/class/'.$subelement.'.class.php'; @@ -917,6 +917,10 @@ if (empty($reshook)) } } } + elseif (!empty($object->origin) && !empty($object->origin_id)) + { + $object->linkedObjectsIds[$object->origin] = $object->origin_id; + } $id = $object->create($user); diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 9b865cae3e6..48d56d8e502 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -84,6 +84,11 @@ $search_montant_vat = GETPOST('search_montant_vat', 'alpha'); $search_montant_localtax1 = GETPOST('search_montant_localtax1', 'alpha'); $search_montant_localtax2 = GETPOST('search_montant_localtax2', 'alpha'); $search_montant_ttc = GETPOST('search_montant_ttc', 'alpha'); +$search_multicurrency_code = GETPOST('search_multicurrency_code', 'alpha'); +$search_multicurrency_tx = GETPOST('search_multicurrency_tx', 'alpha'); +$search_multicurrency_montant_ht = GETPOST('search_multicurrency_montant_ht', 'alpha'); +$search_multicurrency_montant_vat = GETPOST('search_multicurrency_montant_vat', 'alpha'); +$search_multicurrency_montant_ttc = GETPOST('search_multicurrency_montant_ttc', 'alpha'); $search_status = GETPOST('search_status', 'int'); $search_paymentmode = GETPOST('search_paymentmode', 'int'); $search_town = GETPOST('search_town', 'alpha'); @@ -167,6 +172,13 @@ $arrayfields = array( 'f.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>0), 'dynamount_payed'=>array('label'=>$langs->trans("Payed"), 'checked'=>0), 'rtp'=>array('label'=>$langs->trans("Rest"), 'checked'=>0), + 'f.multicurrency_code'=>array('label'=>'Currency', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'f.multicurrency_tx'=>array('label'=>'CurrencyRate', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'f.multicurrency_total_ht'=>array('label'=>'MulticurrencyAmountHT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'f.multicurrency_total_vat'=>array('label'=>'MulticurrencyAmountVAT', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'f.multicurrency_total_ttc'=>array('label'=>'MulticurrencyAmountTTC', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'multicurrency_dynamount_payed'=>array('label'=>'MulticurrencyAlreadyPaid', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), + 'multicurrency_rtp'=>array('label'=>'MulticurrencyRemainderToPay', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1)), // Not enabled by default because slow 'f.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), 'f.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), 'f.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), @@ -218,6 +230,11 @@ if (empty($reshook)) $search_montant_localtax1=''; $search_montant_localtax2=''; $search_montant_ttc=''; + $search_multicurrency_code = ''; + $search_multicurrency_tx = ''; + $search_multicurrency_montant_ht = ''; + $search_multicurrency_montant_vat = ''; + $search_multicurrency_montant_ttc = ''; $search_status=''; $search_paymentmode=''; $search_town=''; @@ -269,6 +286,7 @@ if ($search_all || $search_product_category > 0) $sql = 'SELECT DISTINCT'; $sql .= " f.rowid as facid, f.ref, f.ref_supplier, f.type, f.datef, f.date_lim_reglement as datelimite, f.fk_mode_reglement,"; $sql .= " f.total_ht, f.total_ttc, f.total_tva as total_vat, f.paye as paye, f.fk_statut as fk_statut, f.libelle as label, f.datec as date_creation, f.tms as date_update,"; $sql .= " f.localtax1 as total_localtax1, f.localtax2 as total_localtax2,"; +$sql .= ' f.fk_multicurrency, f.multicurrency_code, f.multicurrency_tx, f.multicurrency_total_ht, f.multicurrency_total_tva as multicurrency_total_vat, f.multicurrency_total_ttc,'; $sql .= " f.note_public, f.note_private,"; $sql .= " s.rowid as socid, s.nom as name, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta as code_compta_client, s.code_compta_fournisseur,"; $sql .= " typent.code as typent_code,"; @@ -336,6 +354,11 @@ if ($search_montant_vat != '') $sql .= natural_search('f.total_tva', $search_mon if ($search_montant_localtax1 != '') $sql .= natural_search('f.localtax1', $search_montant_localtax1, 1); if ($search_montant_localtax2 != '') $sql .= natural_search('f.localtax2', $search_montant_localtax2, 1); if ($search_montant_ttc != '') $sql .= natural_search('f.total_ttc', $search_montant_ttc, 1); +if ($search_multicurrency_code != '') $sql .= ' AND f.multicurrency_code = "' . $db->escape($search_multicurrency_code) . '"'; +if ($search_multicurrency_tx != '') $sql .= natural_search('f.multicurrency_tx', $search_multicurrency_tx, 1); +if ($search_multicurrency_montant_ht != '') $sql .= natural_search('f.multicurrency_total_ht', $search_multicurrency_montant_ht, 1); +if ($search_multicurrency_montant_vat != '') $sql .= natural_search('f.multicurrency_total_tva', $search_multicurrency_montant_vat, 1); +if ($search_multicurrency_montant_ttc != '') $sql .= natural_search('f.multicurrency_total_ttc', $search_multicurrency_montant_ttc, 1); if ($search_status != '' && $search_status >= 0) $sql .= " AND f.fk_statut = ".$db->escape($search_status); if ($search_paymentmode > 0) $sql .= " AND f.fk_mode_reglement = ".$search_paymentmode.""; $sql .= dolSqlDateFilter("f.datef", $day, $month, $year); @@ -433,8 +456,8 @@ if ($resql) } $param = '&socid='.$socid; - if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.$contextpage; - if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.$limit; + if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage); + if ($limit > 0 && $limit != $conf->liste_limit) $param .= '&limit='.urlencode($limit); if ($search_all) $param .= '&search_all='.urlencode($search_all); if ($day) $param .= '&day='.urlencode($day); if ($month) $param .= '&month='.urlencode($month); @@ -452,12 +475,17 @@ if ($resql) if ($search_montant_localtax1 != '') $param .= '&search_montant_localtax1='.urlencode($search_montant_localtax1); if ($search_montant_localtax2 != '') $param .= '&search_montant_localtax2='.urlencode($search_montant_localtax2); if ($search_montant_ttc != '') $param .= '&search_montant_ttc='.urlencode($search_montant_ttc); + if ($search_multicurrency_code != '') $param .= '&search_multicurrency_code='.urlencode($search_multicurrency_code); + if ($search_multicurrency_tx != '') $param .= '&search_multicurrency_tx='.urlencode($search_multicurrency_tx); + if ($search_multicurrency_montant_ht != '') $param .= '&search_multicurrency_montant_ht='.urlencode($search_multicurrency_montant_ht); + if ($search_multicurrency_montant_vat != '') $param .= '&search_multicurrency_montant_vat='.urlencode($search_multicurrency_montant_vat); + if ($search_multicurrency_montant_ttc != '') $param .= '&search_multicurrency_montant_ttc='.urlencode($search_multicurrency_montant_ttc); if ($search_amount_no_tax) $param .= '&search_amount_no_tax='.urlencode($search_amount_no_tax); if ($search_amount_all_tax) $param .= '&search_amount_all_tax='.urlencode($search_amount_all_tax); if ($search_status >= 0) $param .= "&search_status=".urlencode($search_status); - if ($show_files) $param .= '&show_files='.$show_files; - if ($option) $param .= "&option=".$option; - if ($optioncss != '') $param .= '&optioncss='.$optioncss; + if ($show_files) $param .= '&show_files='.urlencode($show_files); + if ($option) $param .= "&option=".urlencode($option); + if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss); // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; @@ -741,6 +769,51 @@ if ($resql) print ''; print ''; } + if (!empty($arrayfields['f.multicurrency_code']['checked'])) + { + // Currency + print ''; + print $form->selectMultiCurrency($search_multicurrency_code, 'search_multicurrency_code', 1); + print ''; + } + if (!empty($arrayfields['f.multicurrency_tx']['checked'])) + { + // Currency rate + print ''; + print ''; + print ''; + } + if (!empty($arrayfields['f.multicurrency_total_ht']['checked'])) + { + // Amount + print ''; + print ''; + print ''; + } + if (!empty($arrayfields['f.multicurrency_total_vat']['checked'])) + { + // Amount + print ''; + print ''; + print ''; + } + if (!empty($arrayfields['f.multicurrency_total_ttc']['checked'])) + { + // Amount + print ''; + print ''; + print ''; + } + if (!empty($arrayfields['multicurrency_dynamount_payed']['checked'])) + { + print ''; + print ''; + } + if (!empty($arrayfields['multicurrency_rtp']['checked'])) + { + print ''; + print ''; + } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; @@ -798,6 +871,13 @@ if ($resql) if (!empty($arrayfields['f.total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.total_ttc']['label'], $_SERVER['PHP_SELF'], 'f.total_ttc', '', $param, '', $sortfield, $sortorder, 'right '); if (!empty($arrayfields['dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['dynamount_payed']['label'], $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, 'right '); if (!empty($arrayfields['rtp']['checked'])) print_liste_field_titre($arrayfields['rtp']['label'], $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, 'right '); + if (!empty($arrayfields['f.multicurrency_code']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_code']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_code', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['f.multicurrency_tx']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_tx']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_tx', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['f.multicurrency_total_ht']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_total_ht']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_total_ht', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['f.multicurrency_total_vat']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_total_vat']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_total_tva', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['f.multicurrency_total_ttc']['checked'])) print_liste_field_titre($arrayfields['f.multicurrency_total_ttc']['label'], $_SERVER['PHP_SELF'], 'f.multicurrency_total_ttc', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['multicurrency_dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['multicurrency_dynamount_payed']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + if (!empty($arrayfields['multicurrency_rtp']['checked'])) print_liste_field_titre($arrayfields['multicurrency_rtp']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields @@ -831,6 +911,11 @@ if ($resql) $facturestatic->statut = $obj->fk_statut; $facturestatic->note_public = $obj->note_public; $facturestatic->note_private = $obj->note_private; + $facturestatic->multicurrency_code = $obj->multicurrency_code; + $facturestatic->multicurrency_tx = $obj->multicurrency_tx; + $facturestatic->multicurrency_total_ht = $obj->multicurrency_total_ht; + $facturestatic->multicurrency_total_tva = $obj->multicurrency_total_vat; + $facturestatic->multicurrency_total_ttc = $obj->multicurrency_total_ttc; $thirdparty->id = $obj->socid; $thirdparty->name = $obj->name; @@ -848,6 +933,14 @@ if ($resql) $totaldeposits = $facturestatic->getSumDepositsUsed(); $totalpay = $paiement + $totalcreditnotes + $totaldeposits; $remaintopay = $obj->total_ttc - $totalpay; + $multicurrency_paiement = $facturestatic->getSommePaiement(1); + $multicurrency_totalcreditnotes = $facturestatic->getSumCreditNotesUsed(1); + $multicurrency_totaldeposits = $facturestatic->getSumDepositsUsed(1); + $multicurrency_totalpay = $multicurrency_paiement + $multicurrency_totalcreditnotes + $multicurrency_totaldeposits; + $multicurrency_remaintopay = price2num($facturestatic->multicurrency_total_ttc - $multicurrency_totalpay); + + $facturestatic->alreadypaid = ($paiement ? $paiement : 0); + //If invoice has been converted and the conversion has been used, we dont have remain to pay on invoice if ($facturestatic->type == FactureFournisseur::TYPE_CREDIT_NOTE) { @@ -879,7 +972,7 @@ if ($resql) // Supplier ref if (!empty($arrayfields['f.ref_supplier']['checked'])) { - print ''; + print ''; print $obj->ref_supplier; print ''; if (!$i) $totalarray['nbfield']++; @@ -1054,6 +1147,54 @@ if ($resql) $totalarray['val']['rtp'] += $remaintopay; } + // Currency + if (!empty($arrayfields['f.multicurrency_code']['checked'])) + { + print ''.$obj->multicurrency_code . ' - ' . $langs->trans('Currency' . $obj->multicurrency_code)."\n"; + if (!$i) $totalarray['nbfield']++; + } + + // Currency rate + if (!empty($arrayfields['f.multicurrency_tx']['checked'])) + { + print ''; + $form->form_multicurrency_rate($_SERVER['PHP_SELF'] . '?id=' . $obj->rowid, $obj->multicurrency_tx, 'none', $obj->multicurrency_code); + print "\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount HT + if (!empty($arrayfields['f.multicurrency_total_ht']['checked'])) + { + print ''.price($obj->multicurrency_total_ht)."\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount VAT + if (!empty($arrayfields['f.multicurrency_total_vat']['checked'])) + { + print ''.price($obj->multicurrency_total_vat)."\n"; + if (!$i) $totalarray['nbfield']++; + } + // Amount TTC + if (!empty($arrayfields['f.multicurrency_total_ttc']['checked'])) + { + print ''.price($obj->multicurrency_total_ttc)."\n"; + if (!$i) $totalarray['nbfield']++; + } + if (!empty($arrayfields['multicurrency_dynamount_payed']['checked'])) + { + print ''.(!empty($multicurrency_totalpay) ?price($multicurrency_totalpay, 0, $langs) : ' ').''; // TODO Use a denormalized field + if (!$i) $totalarray['nbfield']++; + } + + // Pending amount + if (!empty($arrayfields['multicurrency_rtp']['checked'])) + { + print ''; + print (!empty($multicurrency_remaintopay) ? price($multicurrency_remaintopay, 0, $langs) : ' '); + print ''; // TODO Use a denormalized field + if (!$i) $totalarray['nbfield']++; + } + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; @@ -1081,7 +1222,6 @@ if ($resql) if (!empty($arrayfields['f.fk_statut']['checked'])) { print ''; - // TODO $paiement is not yet defined print $facturestatic->LibStatut($obj->paye, $obj->fk_statut, 5, $paiement, $obj->type); print ""; if (!$i) $totalarray['nbfield']++; diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index e0a679d1321..1b6f8257977 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -297,9 +297,13 @@ if (empty($reshook)) $paiement->datepaye = $datepaye; $paiement->amounts = $amounts; // Array of amounts $paiement->multicurrency_amounts = $multicurrency_amounts; - $paiement->paiementid = $_POST['paiementid']; - $paiement->num_paiement = $_POST['num_paiement']; - $paiement->note = $_POST['comment']; + $paiement->paiementid = GETPOST('paiementid', 'int'); + + $paiement->num_payment = GETPOST('num_paiement', 'alpha'); + $paiement->note_private = GETPOST('comment', 'alpha'); + $paiement->num_paiement = $paiement->num_payment; // For bacward compatibility + $paiement->note = $paiement->note_private; // For bacward compatibility + if (!$error) { $paiement_id = $paiement->create($user, (GETPOST('closepaidinvoices') == 'on' ? 1 : 0), $thirdparty); diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index 4c4a5212abd..075ca5f5524 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -716,7 +716,7 @@ class Holiday extends CommonObject { $num = $this->ref; } - $this->newref = $num; + $this->newref = dol_sanitizeFileName($num); // Update status $sql = "UPDATE ".MAIN_DB_PREFIX."holiday SET"; @@ -1654,21 +1654,24 @@ class Holiday extends CommonObject { if ($type) { - // Si utilisateur de Dolibarr - - $sql = "SELECT u.rowid"; - $sql .= " FROM ".MAIN_DB_PREFIX."user as u"; + // If user of Dolibarr + $sql = "SELECT"; + if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { + $sql .= " DISTINCT"; + } + $sql.= " u.rowid"; + $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug"; - $sql .= " WHERE (ug.fk_user = u.rowid"; - $sql .= " AND ug.entity = ".$conf->entity.")"; - $sql .= " OR u.admin = 1"; + $sql .= " WHERE ((ug.fk_user = u.rowid"; + $sql .= " AND ug.entity IN (".getEntity('usergroup')."))"; + $sql .= " OR u.entity = 0)"; // Show always superadmin } else { - $sql .= " WHERE u.entity IN (0,".$conf->entity.")"; + $sql .= " WHERE u.entity IN (".getEntity('user').")"; } $sql .= " AND u.statut > 0"; if ($filters) $sql .= $filters; @@ -1709,7 +1712,7 @@ class Holiday extends CommonObject // We want only list of vacation balance for user ids $sql = "SELECT DISTINCT cpu.fk_user"; $sql .= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u"; - $sql .= " WHERE cpu.fk_user = u.user"; + $sql .= " WHERE cpu.fk_user = u.rowid"; if ($filters) $sql .= $filters; $resql = $this->db->query($sql); @@ -1750,17 +1753,24 @@ class Holiday extends CommonObject // List for Dolibarr users if ($type) { - $sql = "SELECT u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user"; + // If user of Dolibarr + $sql = "SELECT"; + if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { + $sql .= " DISTINCT"; + } + $sql.= " u.rowid, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user"; $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { - $sql.= ", ".MAIN_DB_PREFIX."usergroup_user as ug"; - $sql.= " WHERE (ug.fk_user = u.rowid"; - $sql.= " AND ug.entity = ".$conf->entity.")"; - $sql.= " OR u.admin = 1"; - } else { - $sql.= " WHERE u.entity IN (0,".$conf->entity.")"; + $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug"; + $sql .= " WHERE ((ug.fk_user = u.rowid"; + $sql .= " AND ug.entity IN (".getEntity('usergroup')."))"; + $sql .= " OR u.entity = 0)"; // Show always superadmin + } + else + { + $sql .= " WHERE u.entity IN (".getEntity('user').")"; } $sql.= " AND u.statut > 0"; diff --git a/htdocs/includes/ace/ChangeLog.txt b/htdocs/includes/ace/ChangeLog.txt index 237a2cdd66f..824f8750e12 100644 --- a/htdocs/includes/ace/ChangeLog.txt +++ b/htdocs/includes/ace/ChangeLog.txt @@ -1,3 +1,12 @@ +2020.01.14 Version 1.4.8 +* highlight both matched braces, and highlight unmatched brace in red +* improve snippet manager +* compatibility with webpack file-loader v5 +* improve vim mode + +2019.10.17 Version 1.4.7 +* add placeholder option + 2019.09.08 Version 1.4.6 * restore native behavior of ctrl-p on mac (jumptomatching command is moved to cmd-\) * improve snippet manager diff --git a/htdocs/includes/ace/ace.d.ts b/htdocs/includes/ace/ace.d.ts index 3d7ce109bb7..dd1a2952a06 100644 --- a/htdocs/includes/ace/ace.d.ts +++ b/htdocs/includes/ace/ace.d.ts @@ -214,6 +214,7 @@ export namespace Ace { wrapBehavioursEnabled: boolean; autoScrollEditorIntoView: boolean; keyboardHandler: string; + placeholder: string; value: string; session: EditSession; } diff --git a/htdocs/includes/ace/kitchen-sink.html b/htdocs/includes/ace/kitchen-sink.html index e4bab25a335..27014fa6004 100644 --- a/htdocs/includes/ace/kitchen-sink.html +++ b/htdocs/includes/ace/kitchen-sink.html @@ -8,7 +8,7 @@ diff --git a/htdocs/includes/ace/package.json b/htdocs/includes/ace/package.json index 16587d65d90..a00dddeb40a 100644 --- a/htdocs/includes/ace/package.json +++ b/htdocs/includes/ace/package.json @@ -2,7 +2,7 @@ "name": "ace-builds", "main": "./src-noconflict/ace.js", "typings": "ace.d.ts", - "version": "1.4.6", + "version": "1.4.8", "description": "Ace (Ajax.org Cloud9 Editor)", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" diff --git a/htdocs/includes/ace/src/ace.js b/htdocs/includes/ace/src/ace.js index 378ba7cf463..43d9931a3c4 100644 --- a/htdocs/includes/ace/src/ace.js +++ b/htdocs/includes/ace/src/ace.js @@ -880,10 +880,10 @@ if (!Date.now) { return new Date().getTime(); }; } -var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" + +var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" + "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + "\u2029\uFEFF"; -if (!String.prototype.trim || ws.trim()) { +if (!String.prototype.trim) { ws = "[" + ws + "]"; var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), trimEndRegexp = new RegExp(ws + ws + "*$"); @@ -1404,26 +1404,30 @@ var useragent = require("./useragent"); var pressedKeys = null; var ts = 0; +var activeListenerOptions; +function detectListenerOptionsSupport() { + activeListenerOptions = false; + try { + document.createComment("").addEventListener("test", function() {}, { + get passive() { + activeListenerOptions = {passive: false}; + } + }); + } catch(e) {} +} + +function getListenerOptions() { + if (activeListenerOptions == undefined) + detectListenerOptionsSupport(); + return activeListenerOptions; +} + exports.addListener = function(elem, type, callback) { - if (elem.addEventListener) { - return elem.addEventListener(type, callback, false); - } - if (elem.attachEvent) { - var wrapper = function() { - callback.call(elem, window.event); - }; - callback._wrapper = wrapper; - elem.attachEvent("on" + type, wrapper); - } + return elem.addEventListener(type, callback, getListenerOptions()); }; exports.removeListener = function(elem, type, callback) { - if (elem.removeEventListener) { - return elem.removeEventListener(type, callback, false); - } - if (elem.detachEvent) { - elem.detachEvent("on" + type, callback._wrapper || callback); - } + return elem.removeEventListener(type, callback, getListenerOptions()); }; exports.stopEvent = function(e) { exports.stopPropagation(e); @@ -1434,27 +1438,18 @@ exports.stopEvent = function(e) { exports.stopPropagation = function(e) { if (e.stopPropagation) e.stopPropagation(); - else - e.cancelBubble = true; }; exports.preventDefault = function(e) { if (e.preventDefault) e.preventDefault(); - else - e.returnValue = false; }; exports.getButton = function(e) { if (e.type == "dblclick") return 0; if (e.type == "contextmenu" || (useragent.isMac && (e.ctrlKey && !e.altKey && !e.shiftKey))) return 2; - if (e.preventDefault) { - return e.button; - } - else { - return {1:0, 2:2, 4:1}[e.button]; - } + return e.button; }; exports.capture = function(el, eventHandler, releaseCaptureHandler) { @@ -1560,30 +1555,16 @@ exports.addMultiMouseDownListener = function(elements, timeouts, eventHandler, c else if (clicks > 1) return eventHandler[callbackName](eventNames[clicks], e); } - function onDblclick(e) { - clicks = 2; - if (timer) - clearTimeout(timer); - timer = setTimeout(function() {timer = null;}, timeouts[clicks - 1] || 600); - eventHandler[callbackName]("mousedown", e); - eventHandler[callbackName](eventNames[clicks], e); - } if (!Array.isArray(elements)) elements = [elements]; elements.forEach(function(el) { exports.addListener(el, "mousedown", onMousedown); - if (useragent.isOldIE) - exports.addListener(el, "dblclick", onDblclick); }); }; -var getModifierHash = useragent.isMac && useragent.isOpera && !("KeyboardEvent" in window) - ? function(e) { - return 0 | (e.metaKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.ctrlKey ? 8 : 0); - } - : function(e) { - return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0); - }; +var getModifierHash = function(e) { + return 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0) | (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0); +}; exports.getModifierString = function(e) { return keys.KEY_MODS[getModifierHash(e)]; @@ -2228,6 +2209,7 @@ var TextInput = function(parentNode, host) { var lastValue = ""; var lastSelectionStart = 0; var lastSelectionEnd = 0; + var lastRestoreEnd = 0; try { var isFocused = document.activeElement === text; } catch(e) {} event.addListener(text, "blur", function(e) { @@ -2447,9 +2429,8 @@ var TextInput = function(parentNode, host) { endIndex = 0; } inserted = inserted.slice(0, endIndex); - if (!fromInput && restoreStart == inserted.length && !extendLeft && !extendRight && !restoreEnd) + if (!fromInput && !inserted && !restoreStart && !extendLeft && !extendRight && !restoreEnd) return ""; - sendingText = true; if (inserted && !extendLeft && !extendRight && !restoreStart && !restoreEnd || commandMode) { host.onTextInput(inserted); @@ -2466,6 +2447,7 @@ var TextInput = function(parentNode, host) { lastValue = value; lastSelectionStart = selectionStart; lastSelectionEnd = selectionEnd; + lastRestoreEnd = restoreEnd; return inserted; } }; @@ -2628,7 +2610,7 @@ var TextInput = function(parentNode, host) { = inComposition.context.compositionStartOffset; } inComposition.markerRange.end.column = inComposition.markerRange.start.column - + lastSelectionEnd - inComposition.selectionStart; + + lastSelectionEnd - inComposition.selectionStart + lastRestoreEnd; } } }; @@ -3786,10 +3768,11 @@ exports.DragdropHandler = DragdropHandler; }); -define("ace/mouse/touch_handler",["require","exports","module","ace/mouse/mouse_event","ace/lib/dom"], function(require, exports, module) { +define("ace/mouse/touch_handler",["require","exports","module","ace/mouse/mouse_event","ace/lib/event","ace/lib/dom"], function(require, exports, module) { "use strict"; var MouseEvent = require("./mouse_event").MouseEvent; +var event = require("../lib/event"); var dom = require("../lib/dom"); exports.addTouchListeners = function(el, editor) { @@ -3916,12 +3899,12 @@ exports.addTouchListeners = function(el, editor) { } mode = "wait"; } - el.addEventListener("contextmenu", function(e) { + event.addListener(el, "contextmenu", function(e) { if (!pressed) return; var textarea = editor.textInput.getElement(); textarea.focus(); }); - el.addEventListener("touchstart", function (e) { + event.addListener(el, "touchstart", function (e) { var touches = e.touches; if (longTouchTimer || touches.length > 1) { clearTimeout(longTouchTimer); @@ -3995,7 +3978,7 @@ exports.addTouchListeners = function(el, editor) { touchStartT = t; }); - el.addEventListener("touchend", function (e) { + event.addListener(el, "touchend", function (e) { pressed = editor.$mouseHandler.isMousePressed = false; if (animationTimer) clearInterval(animationTimer); if (mode == "zoom") { @@ -4015,7 +3998,7 @@ exports.addTouchListeners = function(el, editor) { clearTimeout(longTouchTimer); longTouchTimer = null; }); - el.addEventListener("touchmove", function (e) { + event.addListener(el, "touchmove", function (e) { if (longTouchTimer) { clearTimeout(longTouchTimer); longTouchTimer = null; @@ -4577,7 +4560,7 @@ function deHyphenate(str) { return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); }); } -exports.version = "1.4.6"; +exports.version = "1.4.8"; }); @@ -5677,6 +5660,8 @@ var Selection = function(session) { }; this.$setSelection = function(anchorRow, anchorColumn, cursorRow, cursorColumn) { + if (this.$silent) + return; var wasEmpty = this.$isEmpty; var wasMultiselect = this.inMultiSelectMode; this.$silent = true; @@ -6070,14 +6055,19 @@ var Selection = function(session) { else this.$desiredColumn = screenPos.column; } - + + if (rows != 0 && this.session.lineWidgets && this.session.lineWidgets[this.lead.row]) { + var widget = this.session.lineWidgets[this.lead.row]; + if (rows < 0) + rows -= widget.rowsAbove || 0; + else if (rows > 0) + rows += widget.rowCount - (widget.rowsAbove || 0); + } + var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column, offsetX); if (rows !== 0 && chars === 0 && docPos.row === this.lead.row && docPos.column === this.lead.column) { - if (this.session.lineWidgets && this.session.lineWidgets[docPos.row]) { - if (docPos.row > 0 || rows > 0) - docPos.row++; - } + } this.moveCursorTo(docPos.row, docPos.column + chars, chars === 0); }; @@ -9710,7 +9700,7 @@ function BracketMatch() { var line = this.getLine(pos.row); var before = true, range; - var chr = line.charAt(pos.column-1); + var chr = line.charAt(pos.column - 1); var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/); if (!match) { chr = line.charAt(pos.column); @@ -9745,6 +9735,29 @@ function BracketMatch() { return range; }; + this.getMatchingBracketRanges = function(pos) { + var line = this.getLine(pos.row); + + var chr = line.charAt(pos.column - 1); + var match = chr && chr.match(/([\(\[\{])|([\)\]\}])/); + if (!match) { + chr = line.charAt(pos.column); + pos = {row: pos.row, column: pos.column + 1}; + match = chr && chr.match(/([\(\[\{])|([\)\]\}])/); + } + + if (!match) + return null; + + var startRange = new Range(pos.row, pos.column - 1, pos.row, pos.column); + var bracketPos = match[1] ? this.$findClosingBracket(match[1], pos) + : this.$findOpeningBracket(match[2], pos); + if (!bracketPos) + return [startRange]; + var endRange = new Range(bracketPos.row, bracketPos.column, bracketPos.row, bracketPos.column + 1); + + return [startRange, endRange]; + }; this.$brackets = { ")": "(", @@ -11147,15 +11160,14 @@ EditSession.$uid = 0; this.lineWidgets = null; this.getRowLength = function(row) { + var h = 1; if (this.lineWidgets) - var h = this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0; - else - h = 0; - if (!this.$useWrapMode || !this.$wrapData[row]) { - return 1 + h; - } else { - return this.$wrapData[row].length + 1 + h; - } + h += this.lineWidgets[row] && this.lineWidgets[row].rowCount || 0; + + if (!this.$useWrapMode || !this.$wrapData[row]) + return h; + else + return this.$wrapData[row].length + h; }; this.getRowLineCount = function(row) { if (!this.$useWrapMode || !this.$wrapData[row]) { @@ -11367,6 +11379,9 @@ EditSession.$uid = 0; wrapIndent = screenRowOffset > 0 ? wrapRow.indent : 0; } } + + if (this.lineWidgets && this.lineWidgets[row] && this.lineWidgets[row].rowsAbove) + screenRow += this.lineWidgets[row].rowsAbove; return { row: screenRow, @@ -13034,6 +13049,26 @@ exports.commands = [{ }, readOnly: true, scrollIntoView: "none" +}, { + name: "addLineAfter", + exec: function(editor) { + editor.selection.clearSelection(); + editor.navigateLineEnd(); + editor.insert("\n"); + }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" +}, { + name: "addLineBefore", + exec: function(editor) { + editor.selection.clearSelection(); + var cursor = editor.getCursorPosition(); + editor.selection.moveTo(cursor.row - 1, Number.MAX_VALUE); + editor.insert("\n"); + if (cursor.row === 0) editor.navigateUp(); + }, + multiSelectAction: "forEach", + scrollIntoView: "cursor" }, { name: "openCommandPallete", description: "Open command pallete", @@ -13419,28 +13454,46 @@ Editor.$uid = 0; }; this.$highlightBrackets = function() { - if (this.session.$bracketHighlight) { - this.session.removeMarker(this.session.$bracketHighlight); - this.session.$bracketHighlight = null; - } - if (this.$highlightPending) { return; } var self = this; this.$highlightPending = true; - setTimeout(function() { + setTimeout(function () { self.$highlightPending = false; var session = self.session; if (!session || !session.bgTokenizer) return; - var pos = session.findMatchingBracket(self.getCursorPosition()); - if (pos) { - var range = new Range(pos.row, pos.column, pos.row, pos.column + 1); - } else if (session.$mode.getMatching) { - var range = session.$mode.getMatching(self.session); + if (session.$bracketHighlight) { + session.$bracketHighlight.markerIds.forEach(function(id) { + session.removeMarker(id); + }); + session.$bracketHighlight = null; } - if (range) - session.$bracketHighlight = session.addMarker(range, "ace_bracket", "text"); + var ranges = session.getMatchingBracketRanges(self.getCursorPosition()); + if (!ranges && session.$mode.getMatching) + ranges = session.$mode.getMatching(self.session); + if (!ranges) + return; + + var markerType = "ace_bracket"; + if (!Array.isArray(ranges)) { + ranges = [ranges]; + } else if (ranges.length == 1) { + markerType = "ace_error_bracket"; + } + if (ranges.length == 2) { + if (Range.comparePoints(ranges[0].end, ranges[1].start) == 0) + ranges = [Range.fromPoints(ranges[0].start, ranges[1].end)]; + else if (Range.comparePoints(ranges[0].start, ranges[1].end) == 0) + ranges = [Range.fromPoints(ranges[1].start, ranges[0].end)]; + } + + session.$bracketHighlight = { + ranges: ranges, + markerIds: ranges.map(function(range) { + return session.addMarker(range, markerType, "text"); + }) + }; }, 50); }; this.$highlightTags = function() { @@ -14263,6 +14316,7 @@ Editor.$uid = 0; ["up", "down"], ["before", "after"], ["even", "odd"], + ["in", "out"], ["inside", "outside"], ["next", "previous"], ["increase", "decrease"], @@ -14870,9 +14924,11 @@ Editor.$uid = 0; this.destroy = function() { this.renderer.destroy(); this._signal("destroy", this); - if (this.session) { + if (this.session) this.session.destroy(); - } + if (this._$emitInputEvent) + this._$emitInputEvent.cancel(); + this.session = null; }; this.setAutoScrollEditorIntoView = function(enable) { if (!enable) @@ -15028,6 +15084,31 @@ config.defineOptions(Editor.prototype, "editor", { relativeNumberRenderer.detach(this); } }, + placeholder: { + set: function(message) { + if (!this.$updatePlaceholder) { + this.$updatePlaceholder = function() { + var value = this.renderer.$composition || this.getValue(); + if (value && this.renderer.placeholderNode) { + this.renderer.off("afterRender", this.$updatePlaceholder); + dom.removeCssClass(this.container, "ace_hasPlaceholder"); + this.renderer.placeholderNode.remove(); + this.renderer.placeholderNode = null; + } else if (!value && !this.renderer.placeholderNode) { + this.renderer.on("afterRender", this.$updatePlaceholder); + dom.addCssClass(this.container, "ace_hasPlaceholder"); + var el = dom.createElement("div"); + el.className = "ace_placeholder"; + el.textContent = this.$placeholder || ""; + this.renderer.placeholderNode = el; + this.renderer.content.appendChild(this.renderer.placeholderNode); + } + }.bind(this); + this.on("input", this.$updatePlaceholder); + } + this.$updatePlaceholder(); + } + }, hScrollBarAlwaysVisible: "renderer", vScrollBarAlwaysVisible: "renderer", @@ -15118,6 +15199,7 @@ var UndoManager = function() { this.add = function(delta, allowMerge, session) { if (this.$fromUndo) return; if (delta == this.$lastDelta) return; + if (!this.$keepRedoStack) this.$redoStack.length = 0; if (allowMerge === false || !this.lastDeltas) { this.lastDeltas = []; this.$undoStack.push(this.lastDeltas); @@ -15194,6 +15276,25 @@ var UndoManager = function() { if (to == null) to = this.$rev + 1; }; + + this.validateDeltaBoundaries = function(deltaSet, docLength, invertAction) { + if (!deltaSet) { + return false; + } + return deltaSet.every(function(delta) { + var action = delta.action; + if (invertAction && delta.action === "insert") action = "remove"; + if (invertAction && delta.action === "remove") action = "insert"; + switch(action) { + case "insert": + return delta.start.row <= docLength; + case "remove": + return delta.start.row < docLength && delta.end.row < docLength; + default: + return true; + } + }); + }; this.undo = function(session, dontSelect) { this.lastDeltas = null; var stack = this.$undoStack; @@ -15211,7 +15312,7 @@ var UndoManager = function() { var deltaSet = stack.pop(); var undoSelectionRange = null; - if (deltaSet && deltaSet.length) { + if (this.validateDeltaBoundaries(deltaSet, session.getLength(), true)) { undoSelectionRange = session.undoChanges(deltaSet, dontSelect); this.$redoStack.push(deltaSet); this.$syncRev(); @@ -15239,7 +15340,7 @@ var UndoManager = function() { var deltaSet = this.$redoStack.pop(); var redoSelectionRange = null; - if (deltaSet) { + if (this.validateDeltaBoundaries(deltaSet, session.getLength(), false)) { redoSelectionRange = session.redoChanges(deltaSet, dontSelect); this.$undoStack.push(deltaSet); this.$syncRev(); @@ -15618,7 +15719,7 @@ var Lines = function(element, canvasHeight) { }; this.computeLineHeight = function(row, config, session) { - return config.lineHeight * session.getRowLength(row); + return config.lineHeight * session.getRowLineCount(row); }; this.getLength = function() { @@ -15645,10 +15746,10 @@ var Lines = function(element, canvasHeight) { fragment.appendChild(cell[i].element); } this.element.appendChild(fragment); - } else { + } else { this.cells.push(cell); this.element.appendChild(cell.element); - } + } }; this.unshift = function(cell) { @@ -15662,10 +15763,10 @@ var Lines = function(element, canvasHeight) { this.element.insertBefore(fragment, this.element.firstChild); else this.element.appendChild(fragment); - } else { + } else { this.cells.unshift(cell); this.element.insertAdjacentElement("afterbegin", cell.element); - } + } }; this.last = function() { @@ -17633,6 +17734,7 @@ position: absolute;\ box-sizing: border-box;\ min-width: 100%;\ contain: style size layout;\ +font-variant-ligatures: no-common-ligatures;\ }\ .ace_dragging .ace_scroller:before{\ position: absolute;\ @@ -17764,7 +17866,6 @@ margin-top: 1px;\ [ace_nocontext=true] {\ transform: none!important;\ filter: none!important;\ -perspective: none!important;\ clip-path: none!important;\ mask : none!important;\ contain: none!important;\ @@ -17843,6 +17944,9 @@ border-bottom: 1px solid;\ .ace_hidden-cursors .ace_cursor {\ opacity: 0.2;\ }\ +.ace_hasPlaceholder .ace_hidden-cursors .ace_cursor {\ +opacity: 0;\ +}\ .ace_smooth-blinking .ace_cursor {\ transition: opacity 0.18s;\ }\ @@ -17879,6 +17983,11 @@ z-index: 5;\ position: absolute;\ z-index: 6;\ }\ +.ace_marker-layer .ace_error_bracket {\ +position: absolute;\ +border-bottom: 1px solid #DE5555;\ +border-radius: 0;\ +}\ .ace_marker-layer .ace_active-line {\ position: absolute;\ z-index: 2;\ @@ -18062,6 +18171,14 @@ opacity:1;\ }\ .ace_mobile-button:active {\ background-color: #ddd;\ +}\ +.ace_placeholder {\ +font-family: arial;\ +transform: scale(0.9);\ +transform-origin: left;\ +white-space: pre;\ +opacity: 0.7;\ +margin: 0 10px;\ }"; var useragent = require("./lib/useragent"); @@ -18522,7 +18639,6 @@ var VirtualRenderer = function(container, theme) { if (composition.useTextareaForIME) { var val = this.textarea.value; w = this.characterWidth * (this.session.$getStringScreenWidth(val)[0]); - h += 2; } else { posTop += this.lineHeight + 2; @@ -18649,7 +18765,7 @@ var VirtualRenderer = function(container, theme) { this.$textLayer.checkForSizeChanges(); } - this._signal("beforeRender"); + this._signal("beforeRender", changes); if (this.session && this.session.$bidiHandler) this.session.$bidiHandler.updateCharacterWidths(this.$fontMetrics); @@ -18697,7 +18813,7 @@ var VirtualRenderer = function(container, theme) { this.$markerFront.update(config); this.$cursorLayer.update(config); this.$moveTextAreaToCursor(); - this._signal("afterRender"); + this._signal("afterRender", changes); return; } if (changes & this.CHANGE_SCROLL) { @@ -18717,7 +18833,7 @@ var VirtualRenderer = function(container, theme) { this.$markerFront.update(config); this.$cursorLayer.update(config); this.$moveTextAreaToCursor(); - this._signal("afterRender"); + this._signal("afterRender", changes); return; } @@ -18753,7 +18869,7 @@ var VirtualRenderer = function(container, theme) { this.$markerBack.update(config); } - this._signal("afterRender"); + this._signal("afterRender", changes); }; @@ -19185,7 +19301,7 @@ var VirtualRenderer = function(container, theme) { this.$moveTextAreaToCursor(); this.$cursorLayer.element.style.display = "none"; } - else { + else { composition.markerId = this.session.addMarker(composition.markerRange, "ace_composition_marker", "text"); } }; @@ -20079,10 +20195,20 @@ exports.defaultCommands = [{ scrollIntoView: "cursor", readOnly: true }, { - name: "splitIntoLines", + name: "toggleSplitSelectionIntoLines", + description: "Split into lines", + exec: function(editor) { + if (editor.multiSelect.rangeCount > 1) + editor.multiSelect.joinSelections(); + else + editor.multiSelect.splitIntoLines(); + }, + bindKey: {win: "Ctrl-Alt-L", mac: "Ctrl-Alt-L"}, + readOnly: true +}, { + name: "splitSelectionIntoLines", description: "Split into lines", exec: function(editor) { editor.multiSelect.splitIntoLines(); }, - bindKey: {win: "Ctrl-Alt-L", mac: "Ctrl-Alt-L"}, readOnly: true }, { name: "alignCursors", @@ -20177,7 +20303,6 @@ var EditSession = require("./edit_session").EditSession; return $blockChangeEvents || this.fromOrientedRange(range); }; - this.toSingleRange = function(range) { range = range || this.ranges[0]; var removed = this.rangeList.removeAll(); @@ -20242,45 +20367,36 @@ var EditSession = require("./edit_session").EditSession; this.getAllRanges = function() { return this.rangeCount ? this.rangeList.ranges.concat() : [this.getRange()]; }; - this.splitIntoLines = function () { - if (this.rangeCount > 1) { - var ranges = this.rangeList.ranges; - var lastRange = ranges[ranges.length - 1]; - var range = Range.fromPoints(ranges[0].start, lastRange.end); - - this.toSingleRange(); - this.setSelectionRange(range, lastRange.cursor == lastRange.start); - } else { - var range = this.getRange(); - var isBackwards = this.isBackwards(); - var startRow = range.start.row; + var ranges = this.ranges.length ? this.ranges : [this.getRange()]; + var newRanges = []; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + var row = range.start.row; var endRow = range.end.row; - if (startRow == endRow) { - if (isBackwards) - var start = range.end, end = range.start; - else - var start = range.start, end = range.end; - - this.addRange(Range.fromPoints(end, end)); - this.addRange(Range.fromPoints(start, start)); - return; + if (row === endRow) { + newRanges.push(range.clone()); + } else { + newRanges.push(new Range(row, range.start.column, row, this.session.getLine(row).length)); + while (++row < endRow) + newRanges.push(this.getLineRange(row, true)); + newRanges.push(new Range(endRow, 0, endRow, range.end.column)); } - - var rectSel = []; - var r = this.getLineRange(startRow, true); - r.start.column = range.start.column; - rectSel.push(r); - - for (var i = startRow + 1; i < endRow; i++) - rectSel.push(this.getLineRange(i, true)); - - r = this.getLineRange(endRow, true); - r.end.column = range.end.column; - rectSel.push(r); - - rectSel.forEach(this.addRange, this); + if (i == 0 && !this.isBackwards()) + newRanges = newRanges.reverse(); } + this.toSingleRange(); + for (var i = newRanges.length; i--;) + this.addRange(newRanges[i]); + }; + + this.joinSelections = function () { + var ranges = this.rangeList.ranges; + var lastRange = ranges[ranges.length - 1]; + var range = Range.fromPoints(ranges[0].start, lastRange.end); + + this.toSingleRange(); + this.setSelectionRange(range, lastRange.cursor == lastRange.start); }; this.toggleBlockSelection = function () { if (this.rangeCount > 1) { @@ -21146,13 +21262,10 @@ var dom = require("../lib/dom"); dom.importCssString(exports.cssText, exports.cssClass); }); -define("ace/line_widgets",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/range"], function(require, exports, module) { +define("ace/line_widgets",["require","exports","module","ace/lib/dom"], function(require, exports, module) { "use strict"; -var oop = require("./lib/oop"); var dom = require("./lib/dom"); -var Range = require("./range").Range; - function LineWidgets(session) { this.session = session; @@ -21266,14 +21379,21 @@ function LineWidgets(session) { var len = delta.end.row - startRow; if (len === 0) { - } else if (delta.action == 'remove') { + } else if (delta.action == "remove") { var removed = lineWidgets.splice(startRow + 1, len); + if (!lineWidgets[startRow] && removed[removed.length - 1]) { + lineWidgets[startRow] = removed.pop(); + } removed.forEach(function(w) { w && this.removeLineWidget(w); }, this); this.$updateRows(); } else { var args = new Array(len); + if (lineWidgets[startRow] && lineWidgets[startRow].column != null) { + if (delta.start.column > lineWidgets[startRow].column) + startRow++; + } args.unshift(startRow, 0); lineWidgets.splice.apply(lineWidgets, args); this.$updateRows(); @@ -21298,7 +21418,7 @@ function LineWidgets(session) { this.session.lineWidgets = null; }; - this.addLineWidget = function(w) { + this.$registerLineWidget = function(w) { if (!this.session.lineWidgets) this.session.lineWidgets = new Array(this.session.getLength()); @@ -21312,9 +21432,15 @@ function LineWidgets(session) { } this.session.lineWidgets[w.row] = w; - + return w; + }; + + this.addLineWidget = function(w) { + this.$registerLineWidget(w); w.session = this.session; + if (!this.editor) return w; + var renderer = this.editor.renderer; if (w.html && !w.el) { w.el = dom.createElement("div"); @@ -21326,13 +21452,13 @@ function LineWidgets(session) { w.el.style.zIndex = 5; renderer.container.appendChild(w.el); w._inDocument = true; - } - - if (!w.coverGutter) { - w.el.style.zIndex = 3; - } - if (w.pixelHeight == null) { - w.pixelHeight = w.el.offsetHeight; + + if (!w.coverGutter) { + w.el.style.zIndex = 3; + } + if (w.pixelHeight == null) { + w.pixelHeight = w.el.offsetHeight; + } } if (w.rowCount == null) { w.rowCount = w.pixelHeight / renderer.layerConfig.lineHeight; diff --git a/htdocs/includes/ace/src/ext-code_lens.js b/htdocs/includes/ace/src/ext-code_lens.js new file mode 100644 index 00000000000..4b7e4340f22 --- /dev/null +++ b/htdocs/includes/ace/src/ext-code_lens.js @@ -0,0 +1,234 @@ +define("ace/ext/code_lens",["require","exports","module","ace/line_widgets","ace/lib/lang","ace/lib/dom","ace/editor","ace/config"], function(require, exports, module) { +"use strict"; +var LineWidgets = require("../line_widgets").LineWidgets; +var lang = require("../lib/lang"); +var dom = require("../lib/dom"); + +function clearLensElements(renderer) { + var textLayer = renderer.$textLayer; + var lensElements = textLayer.$lenses; + if (lensElements) + lensElements.forEach(function(el) {el.remove(); }); + textLayer.$lenses = null; +} + +function renderWidgets(changes, renderer) { + var changed = changes & renderer.CHANGE_LINES + || changes & renderer.CHANGE_FULL + || changes & renderer.CHANGE_SCROLL + || changes & renderer.CHANGE_TEXT; + if (!changed) + return; + + var session = renderer.session; + var lineWidgets = renderer.session.lineWidgets; + var textLayer = renderer.$textLayer; + var lensElements = textLayer.$lenses; + if (!lineWidgets) { + if (lensElements) + clearLensElements(renderer); + return; + } + + var textCells = renderer.$textLayer.$lines.cells; + var config = renderer.layerConfig; + var padding = renderer.$padding; + + if (!lensElements) + lensElements = textLayer.$lenses = []; + + + var index = 0; + for (var i = 0; i < textCells.length; i++) { + var row = textCells[i].row; + var widget = lineWidgets[row]; + var lenses = widget && widget.lenses; + + if (!lenses || !lenses.length) continue; + + var lensContainer = lensElements[index]; + if (!lensContainer) { + lensContainer = lensElements[index] + = dom.buildDom(["div", {class: "ace_codeLens"}], renderer.container); + } + lensContainer.style.height = config.lineHeight + "px"; + index++; + + for (var j = 0; j < lenses.length; j++) { + var el = lensContainer.childNodes[2 * j]; + if (!el) { + if (j != 0) lensContainer.appendChild(dom.createTextNode("\xa0|\xa0")); + el = dom.buildDom(["a"], lensContainer); + } + el.textContent = lenses[j].title; + el.lensCommand = lenses[j]; + } + while (lensContainer.childNodes.length > 2 * j - 1) + lensContainer.lastChild.remove(); + + var top = renderer.$cursorLayer.getPixelPosition({ + row: row, + column: 0 + }, true).top - config.lineHeight * widget.rowsAbove - config.offset; + lensContainer.style.top = top + "px"; + + var left = renderer.gutterWidth; + var indent = session.getLine(row).search(/\S|$/); + if (indent == -1) + indent = 0; + left += indent * config.characterWidth; + left -= renderer.scrollLeft; + lensContainer.style.paddingLeft = padding + left + "px"; + } + while (index < lensElements.length) + lensElements.pop().remove(); +} + +function clearCodeLensWidgets(session) { + if (!session.lineWidgets) return; + var widgetManager = session.widgetManager; + session.lineWidgets.forEach(function(widget) { + if (widget && widget.lenses) + widgetManager.removeLineWidget(widget); + }); +} + +exports.setLenses = function(session, lenses) { + var firstRow = Number.MAX_VALUE; + + clearCodeLensWidgets(session); + lenses && lenses.forEach(function(lens) { + var row = lens.start.row; + var column = lens.start.column; + var widget = session.lineWidgets && session.lineWidgets[row]; + if (!widget || !widget.lenses) { + widget = session.widgetManager.$registerLineWidget({ + rowCount: 1, + rowsAbove: 1, + row: row, + column: column, + lenses: [] + }); + } + widget.lenses.push(lens.command); + if (row < firstRow) + firstRow = row; + }); + session._emit("changeFold", {data: {start: {row: firstRow}}}); +}; + +function attachToEditor(editor) { + editor.codeLensProviders = []; + editor.renderer.on("afterRender", renderWidgets); + editor.$codeLensClickHandler = function(e) { + var command = e.target.lensCommand; + if (command) + editor.execCommand(command.id, command.arguments); + }; + editor.container.addEventListener("click", editor.$codeLensClickHandler); + editor.$updateLenses = function() { + var session = editor.session; + if (!session) return; + + if (!session.widgetManager) { + session.widgetManager = new LineWidgets(session); + session.widgetManager.attach(editor); + } + + var providersToWaitNum = editor.codeLensProviders.length; + var lenses = []; + editor.codeLensProviders.forEach(function(provider) { + provider.provideCodeLenses(session, function(currentLenses) { + currentLenses.forEach(function(lens) { + lenses.push(lens); + }); + providersToWaitNum--; + if (providersToWaitNum == 0) { + applyLenses(); + } + }); + }); + + function applyLenses() { + var cursor = session.selection.cursor; + var oldRow = session.documentToScreenRow(cursor); + exports.setLenses(session, lenses); + + var lastDelta = session.$undoManager && session.$undoManager.$lastDelta; + if (lastDelta && lastDelta.action == "remove" && lastDelta.lines.length > 1) + return; + var row = session.documentToScreenRow(cursor); + var lineHeight = editor.renderer.layerConfig.lineHeight; + var top = session.getScrollTop() + (row - oldRow) * lineHeight; + session.setScrollTop(top); + } + }; + var updateLenses = lang.delayedCall(editor.$updateLenses); + editor.$updateLensesOnInput = function() { + updateLenses.delay(250); + }; + editor.on("input", editor.$updateLensesOnInput); +} + +function detachFromEditor(editor) { + editor.off("input", editor.$updateLensesOnInput); + editor.renderer.off("afterRender", renderWidgets); + if (editor.$codeLensClickHandler) + editor.container.removeEventListener("click", editor.$codeLensClickHandler); +} + +exports.registerCodeLensProvider = function(editor, codeLensProvider) { + editor.setOption("enableCodeLens", true); + editor.codeLensProviders.push(codeLensProvider); + editor.$updateLensesOnInput(); +}; + +exports.clear = function(session) { + exports.setLenses(session, null); +}; + +var Editor = require("../editor").Editor; +require("../config").defineOptions(Editor.prototype, "editor", { + enableCodeLens: { + set: function(val) { + if (val) { + attachToEditor(this); + } else { + detachFromEditor(this); + } + } + } +}); + +dom.importCssString("\ +.ace_codeLens {\ + position: absolute;\ + color: #aaa;\ + font-size: 88%;\ + background: inherit;\ + width: 100%;\ + display: flex;\ + align-items: flex-end;\ + pointer-events: none;\ +}\ +.ace_codeLens > a {\ + cursor: pointer;\ + pointer-events: auto;\ +}\ +.ace_codeLens > a:hover {\ + color: #0000ff;\ + text-decoration: underline;\ +}\ +.ace_dark > .ace_codeLens > a:hover {\ + color: #4e94ce;\ +}\ +", ""); + +}); (function() { + window.require(["ace/ext/code_lens"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/ext-emmet.js b/htdocs/includes/ace/src/ext-emmet.js index 30425a69273..3cb3818d1b5 100644 --- a/htdocs/includes/ace/src/ext-emmet.js +++ b/htdocs/includes/ace/src/ext-emmet.js @@ -747,15 +747,16 @@ var TabstopManager = function(editor) { this.onChange = function(delta) { var isRemove = delta.action[0] == "r"; - var parents = this.selectedTabstop && this.selectedTabstop.parents || {}; + var selectedTabstop = this.selectedTabstop || {}; + var parents = selectedTabstop.parents || {}; var tabstops = (this.tabstops || []).slice(); for (var i = 0; i < tabstops.length; i++) { var ts = tabstops[i]; - var active = ts == this.selectedTabstop || parents[ts.index]; + var active = ts == selectedTabstop || parents[ts.index]; ts.rangeList.$bias = active ? 0 : 1; - if (delta.action == "remove" && ts !== this.selectedTabstop) { - var parentActive = ts.parents && ts.parents[this.selectedTabstop.index]; + if (delta.action == "remove" && ts !== selectedTabstop) { + var parentActive = ts.parents && ts.parents[selectedTabstop.index]; var startIndex = ts.rangeList.pointIndex(delta.start, parentActive); startIndex = startIndex < 0 ? -startIndex - 1 : startIndex + 1; var endIndex = ts.rangeList.pointIndex(delta.end, parentActive); @@ -868,8 +869,6 @@ var TabstopManager = function(editor) { var ranges = this.ranges; tabstops.forEach(function(ts, index) { var dest = this.$openTabstops[index] || ts; - ts.rangeList = new RangeList(); - ts.rangeList.$bias = 0; for (var i = 0; i < ts.length; i++) { var p = ts[i]; @@ -879,7 +878,6 @@ var TabstopManager = function(editor) { range.original = p; range.tabstop = dest; ranges.push(range); - ts.rangeList.ranges.push(range); if (dest != ts) dest.unshift(range); else @@ -897,6 +895,9 @@ var TabstopManager = function(editor) { this.$openTabstops[index] = dest; } this.addTabstopMarkers(dest); + dest.rangeList = dest.rangeList || new RangeList(); + dest.rangeList.$bias = 0; + dest.rangeList.addList(dest); }, this); if (arg.length > 2) { @@ -939,21 +940,18 @@ var TabstopManager = function(editor) { this.keyboardHandler = new HashHandler(); this.keyboardHandler.bindKeys({ - "Tab": function(ed) { - if (exports.snippetManager && exports.snippetManager.expandWithTab(ed)) { + "Tab": function(editor) { + if (exports.snippetManager && exports.snippetManager.expandWithTab(editor)) return; - } - - ed.tabstopManager.tabNext(1); + editor.tabstopManager.tabNext(1); + editor.renderer.scrollCursorIntoView(); }, - "Shift-Tab": function(ed) { - ed.tabstopManager.tabNext(-1); + "Shift-Tab": function(editor) { + editor.tabstopManager.tabNext(-1); + editor.renderer.scrollCursorIntoView(); }, - "Esc": function(ed) { - ed.tabstopManager.detach(); - }, - "Return": function(ed) { - return false; + "Esc": function(editor) { + editor.tabstopManager.detach(); } }); }).call(TabstopManager.prototype); diff --git a/htdocs/includes/ace/src/ext-keybinding_menu.js b/htdocs/includes/ace/src/ext-keybinding_menu.js index 501c5f9ccad..4f980686e68 100644 --- a/htdocs/includes/ace/src/ext-keybinding_menu.js +++ b/htdocs/includes/ace/src/ext-keybinding_menu.js @@ -65,6 +65,7 @@ dom.importCssString(cssText); module.exports.overlayPage = function overlayPage(editor, contentElement, callback) { var closer = document.createElement('div'); + var ignoreFocusOut = false; function documentEscListener(e) { if (e.keyCode === 27) { @@ -76,17 +77,28 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba if (!closer) return; document.removeEventListener('keydown', documentEscListener); closer.parentNode.removeChild(closer); - editor.focus(); + if (editor) { + editor.focus(); + } closer = null; callback && callback(); } + function setIgnoreFocusOut(ignore) { + ignoreFocusOut = ignore; + if (ignore) { + closer.style.pointerEvents = "none"; + contentElement.style.pointerEvents = "auto"; + } + } closer.style.cssText = 'margin: 0; padding: 0; ' + 'position: fixed; top:0; bottom:0; left:0; right:0;' + 'z-index: 9990; ' + - 'background-color: rgba(0, 0, 0, 0.3);'; - closer.addEventListener('click', function() { - close(); + (editor ? 'background-color: rgba(0, 0, 0, 0.3);' : ''); + closer.addEventListener('click', function(e) { + if (!ignoreFocusOut) { + close(); + } }); document.addEventListener('keydown', documentEscListener); @@ -96,9 +108,12 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba closer.appendChild(contentElement); document.body.appendChild(closer); - editor.blur(); + if (editor) { + editor.blur(); + } return { - close: close + close: close, + setIgnoreFocusOut: setIgnoreFocusOut }; }; diff --git a/htdocs/includes/ace/src/ext-language_tools.js b/htdocs/includes/ace/src/ext-language_tools.js index 80af02df566..7e6967e0d7a 100644 --- a/htdocs/includes/ace/src/ext-language_tools.js +++ b/htdocs/includes/ace/src/ext-language_tools.js @@ -747,15 +747,16 @@ var TabstopManager = function(editor) { this.onChange = function(delta) { var isRemove = delta.action[0] == "r"; - var parents = this.selectedTabstop && this.selectedTabstop.parents || {}; + var selectedTabstop = this.selectedTabstop || {}; + var parents = selectedTabstop.parents || {}; var tabstops = (this.tabstops || []).slice(); for (var i = 0; i < tabstops.length; i++) { var ts = tabstops[i]; - var active = ts == this.selectedTabstop || parents[ts.index]; + var active = ts == selectedTabstop || parents[ts.index]; ts.rangeList.$bias = active ? 0 : 1; - if (delta.action == "remove" && ts !== this.selectedTabstop) { - var parentActive = ts.parents && ts.parents[this.selectedTabstop.index]; + if (delta.action == "remove" && ts !== selectedTabstop) { + var parentActive = ts.parents && ts.parents[selectedTabstop.index]; var startIndex = ts.rangeList.pointIndex(delta.start, parentActive); startIndex = startIndex < 0 ? -startIndex - 1 : startIndex + 1; var endIndex = ts.rangeList.pointIndex(delta.end, parentActive); @@ -868,8 +869,6 @@ var TabstopManager = function(editor) { var ranges = this.ranges; tabstops.forEach(function(ts, index) { var dest = this.$openTabstops[index] || ts; - ts.rangeList = new RangeList(); - ts.rangeList.$bias = 0; for (var i = 0; i < ts.length; i++) { var p = ts[i]; @@ -879,7 +878,6 @@ var TabstopManager = function(editor) { range.original = p; range.tabstop = dest; ranges.push(range); - ts.rangeList.ranges.push(range); if (dest != ts) dest.unshift(range); else @@ -897,6 +895,9 @@ var TabstopManager = function(editor) { this.$openTabstops[index] = dest; } this.addTabstopMarkers(dest); + dest.rangeList = dest.rangeList || new RangeList(); + dest.rangeList.$bias = 0; + dest.rangeList.addList(dest); }, this); if (arg.length > 2) { @@ -939,21 +940,18 @@ var TabstopManager = function(editor) { this.keyboardHandler = new HashHandler(); this.keyboardHandler.bindKeys({ - "Tab": function(ed) { - if (exports.snippetManager && exports.snippetManager.expandWithTab(ed)) { + "Tab": function(editor) { + if (exports.snippetManager && exports.snippetManager.expandWithTab(editor)) return; - } - - ed.tabstopManager.tabNext(1); + editor.tabstopManager.tabNext(1); + editor.renderer.scrollCursorIntoView(); }, - "Shift-Tab": function(ed) { - ed.tabstopManager.tabNext(-1); + "Shift-Tab": function(editor) { + editor.tabstopManager.tabNext(-1); + editor.renderer.scrollCursorIntoView(); }, - "Esc": function(ed) { - ed.tabstopManager.detach(); - }, - "Return": function(ed) { - return false; + "Esc": function(editor) { + editor.tabstopManager.detach(); } }); }).call(TabstopManager.prototype); @@ -1355,7 +1353,7 @@ exports.parForEach = function(array, fn, callback) { } }; -var ID_REGEX = /[a-zA-Z_0-9\$\-\u00A2-\uFFFF]/; +var ID_REGEX = /[a-zA-Z_0-9\$\-\u00A2-\u2000\u2070-\uFFFF]/; exports.retrievePrecedingIdentifier = function(text, pos, regex) { regex = regex || ID_REGEX; diff --git a/htdocs/includes/ace/src/ext-modelist.js b/htdocs/includes/ace/src/ext-modelist.js index 0032ecd178f..8b771ffeb99 100644 --- a/htdocs/includes/ace/src/ext-modelist.js +++ b/htdocs/includes/ace/src/ext-modelist.js @@ -101,6 +101,7 @@ var supportedModes = { Jade: ["jade|pug"], Java: ["java"], JavaScript: ["js|jsm|jsx"], + JSON5: ["json5"], JSON: ["json"], JSONiq: ["jq"], JSP: ["jsp"], @@ -131,6 +132,7 @@ var supportedModes = { Nix: ["nix"], Nim: ["nim"], NSIS: ["nsi|nsh"], + Nunjucks: ["nunjucks|nunjs|nj|njk"], ObjectiveC: ["m|mm"], OCaml: ["ml|mli"], Pascal: ["pas|p"], diff --git a/htdocs/includes/ace/src/ext-options.js b/htdocs/includes/ace/src/ext-options.js index e01961df4ed..d1d01cefa05 100644 --- a/htdocs/includes/ace/src/ext-options.js +++ b/htdocs/includes/ace/src/ext-options.js @@ -65,6 +65,7 @@ dom.importCssString(cssText); module.exports.overlayPage = function overlayPage(editor, contentElement, callback) { var closer = document.createElement('div'); + var ignoreFocusOut = false; function documentEscListener(e) { if (e.keyCode === 27) { @@ -76,17 +77,28 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba if (!closer) return; document.removeEventListener('keydown', documentEscListener); closer.parentNode.removeChild(closer); - editor.focus(); + if (editor) { + editor.focus(); + } closer = null; callback && callback(); } + function setIgnoreFocusOut(ignore) { + ignoreFocusOut = ignore; + if (ignore) { + closer.style.pointerEvents = "none"; + contentElement.style.pointerEvents = "auto"; + } + } closer.style.cssText = 'margin: 0; padding: 0; ' + 'position: fixed; top:0; bottom:0; left:0; right:0;' + 'z-index: 9990; ' + - 'background-color: rgba(0, 0, 0, 0.3);'; - closer.addEventListener('click', function() { - close(); + (editor ? 'background-color: rgba(0, 0, 0, 0.3);' : ''); + closer.addEventListener('click', function(e) { + if (!ignoreFocusOut) { + close(); + } }); document.addEventListener('keydown', documentEscListener); @@ -96,9 +108,12 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba closer.appendChild(contentElement); document.body.appendChild(closer); - editor.blur(); + if (editor) { + editor.blur(); + } return { - close: close + close: close, + setIgnoreFocusOut: setIgnoreFocusOut }; }; @@ -207,6 +222,7 @@ var supportedModes = { Jade: ["jade|pug"], Java: ["java"], JavaScript: ["js|jsm|jsx"], + JSON5: ["json5"], JSON: ["json"], JSONiq: ["jq"], JSP: ["jsp"], @@ -237,6 +253,7 @@ var supportedModes = { Nix: ["nix"], Nim: ["nim"], NSIS: ["nsi|nsh"], + Nunjucks: ["nunjucks|nunjs|nj|njk"], ObjectiveC: ["m|mm"], OCaml: ["ml|mli"], Pascal: ["pas|p"], @@ -396,9 +413,9 @@ exports.themes = themeData.map(function(data) { define("ace/ext/options",["require","exports","module","ace/ext/menu_tools/overlay_page","ace/lib/dom","ace/lib/oop","ace/config","ace/lib/event_emitter","ace/ext/modelist","ace/ext/themelist"], function(require, exports, module) { "use strict"; -var overlayPage = require('./menu_tools/overlay_page').overlayPage; - +require("./menu_tools/overlay_page"); + var dom = require("../lib/dom"); var oop = require("../lib/oop"); var config = require("../config"); @@ -437,7 +454,8 @@ var optionGroups = { { caption : "Ace", value : null }, { caption : "Vim", value : "ace/keyboard/vim" }, { caption : "Emacs", value : "ace/keyboard/emacs" }, - { caption : "Sublime", value : "ace/keyboard/sublime" } + { caption : "Sublime", value : "ace/keyboard/sublime" }, + { caption : "VSCode", value : "ace/keyboard/vscode" } ] }, "Font Size": { diff --git a/htdocs/includes/ace/src/ext-prompt.js b/htdocs/includes/ace/src/ext-prompt.js index 815c7cda214..bcc99f70806 100644 --- a/htdocs/includes/ace/src/ext-prompt.js +++ b/htdocs/includes/ace/src/ext-prompt.js @@ -387,7 +387,7 @@ exports.parForEach = function(array, fn, callback) { } }; -var ID_REGEX = /[a-zA-Z_0-9\$\-\u00A2-\uFFFF]/; +var ID_REGEX = /[a-zA-Z_0-9\$\-\u00A2-\u2000\u2070-\uFFFF]/; exports.retrievePrecedingIdentifier = function(text, pos, regex) { regex = regex || ID_REGEX; @@ -1179,15 +1179,16 @@ var TabstopManager = function(editor) { this.onChange = function(delta) { var isRemove = delta.action[0] == "r"; - var parents = this.selectedTabstop && this.selectedTabstop.parents || {}; + var selectedTabstop = this.selectedTabstop || {}; + var parents = selectedTabstop.parents || {}; var tabstops = (this.tabstops || []).slice(); for (var i = 0; i < tabstops.length; i++) { var ts = tabstops[i]; - var active = ts == this.selectedTabstop || parents[ts.index]; + var active = ts == selectedTabstop || parents[ts.index]; ts.rangeList.$bias = active ? 0 : 1; - if (delta.action == "remove" && ts !== this.selectedTabstop) { - var parentActive = ts.parents && ts.parents[this.selectedTabstop.index]; + if (delta.action == "remove" && ts !== selectedTabstop) { + var parentActive = ts.parents && ts.parents[selectedTabstop.index]; var startIndex = ts.rangeList.pointIndex(delta.start, parentActive); startIndex = startIndex < 0 ? -startIndex - 1 : startIndex + 1; var endIndex = ts.rangeList.pointIndex(delta.end, parentActive); @@ -1300,8 +1301,6 @@ var TabstopManager = function(editor) { var ranges = this.ranges; tabstops.forEach(function(ts, index) { var dest = this.$openTabstops[index] || ts; - ts.rangeList = new RangeList(); - ts.rangeList.$bias = 0; for (var i = 0; i < ts.length; i++) { var p = ts[i]; @@ -1311,7 +1310,6 @@ var TabstopManager = function(editor) { range.original = p; range.tabstop = dest; ranges.push(range); - ts.rangeList.ranges.push(range); if (dest != ts) dest.unshift(range); else @@ -1329,6 +1327,9 @@ var TabstopManager = function(editor) { this.$openTabstops[index] = dest; } this.addTabstopMarkers(dest); + dest.rangeList = dest.rangeList || new RangeList(); + dest.rangeList.$bias = 0; + dest.rangeList.addList(dest); }, this); if (arg.length > 2) { @@ -1371,21 +1372,18 @@ var TabstopManager = function(editor) { this.keyboardHandler = new HashHandler(); this.keyboardHandler.bindKeys({ - "Tab": function(ed) { - if (exports.snippetManager && exports.snippetManager.expandWithTab(ed)) { + "Tab": function(editor) { + if (exports.snippetManager && exports.snippetManager.expandWithTab(editor)) return; - } - - ed.tabstopManager.tabNext(1); + editor.tabstopManager.tabNext(1); + editor.renderer.scrollCursorIntoView(); }, - "Shift-Tab": function(ed) { - ed.tabstopManager.tabNext(-1); + "Shift-Tab": function(editor) { + editor.tabstopManager.tabNext(-1); + editor.renderer.scrollCursorIntoView(); }, - "Esc": function(ed) { - ed.tabstopManager.detach(); - }, - "Return": function(ed) { - return false; + "Esc": function(editor) { + editor.tabstopManager.detach(); } }); }).call(TabstopManager.prototype); @@ -2004,6 +2002,7 @@ dom.importCssString(cssText); module.exports.overlayPage = function overlayPage(editor, contentElement, callback) { var closer = document.createElement('div'); + var ignoreFocusOut = false; function documentEscListener(e) { if (e.keyCode === 27) { @@ -2015,17 +2014,28 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba if (!closer) return; document.removeEventListener('keydown', documentEscListener); closer.parentNode.removeChild(closer); - editor.focus(); + if (editor) { + editor.focus(); + } closer = null; callback && callback(); } + function setIgnoreFocusOut(ignore) { + ignoreFocusOut = ignore; + if (ignore) { + closer.style.pointerEvents = "none"; + contentElement.style.pointerEvents = "auto"; + } + } closer.style.cssText = 'margin: 0; padding: 0; ' + 'position: fixed; top:0; bottom:0; left:0; right:0;' + 'z-index: 9990; ' + - 'background-color: rgba(0, 0, 0, 0.3);'; - closer.addEventListener('click', function() { - close(); + (editor ? 'background-color: rgba(0, 0, 0, 0.3);' : ''); + closer.addEventListener('click', function(e) { + if (!ignoreFocusOut) { + close(); + } }); document.addEventListener('keydown', documentEscListener); @@ -2035,9 +2045,12 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba closer.appendChild(contentElement); document.body.appendChild(closer); - editor.blur(); + if (editor) { + editor.blur(); + } return { - close: close + close: close, + setIgnoreFocusOut: setIgnoreFocusOut }; }; @@ -2146,6 +2159,7 @@ var supportedModes = { Jade: ["jade|pug"], Java: ["java"], JavaScript: ["js|jsm|jsx"], + JSON5: ["json5"], JSON: ["json"], JSONiq: ["jq"], JSP: ["jsp"], @@ -2176,6 +2190,7 @@ var supportedModes = { Nix: ["nix"], Nim: ["nim"], NSIS: ["nsi|nsh"], + Nunjucks: ["nunjucks|nunjs|nj|njk"], ObjectiveC: ["m|mm"], OCaml: ["ml|mli"], Pascal: ["pas|p"], @@ -2305,14 +2320,18 @@ function prompt(editor, message, options, callback) { var cmdLine = $singleLineEditor(); cmdLine.session.setUndoManager(new UndoManager()); - cmdLine.setOption("fontSize", editor.getOption("fontSize")); - var el = dom.buildDom(["div", {class: "ace_prompt_container"}]); + var el = dom.buildDom(["div", {class: "ace_prompt_container" + (options.hasDescription ? " input-box-with-description" : "")}]); var overlay = overlayPage(editor, el, done); el.appendChild(cmdLine.container); - editor.cmdLine = cmdLine; - cmdLine.setValue(message, 1); + if (editor) { + editor.cmdLine = cmdLine; + cmdLine.setOption("fontSize", editor.getOption("fontSize")); + } + if (message) { + cmdLine.setValue(message, 1); + } if (options.selection) { cmdLine.selection.setRange({ start: cmdLine.session.doc.indexToPosition(options.selection[0]), @@ -2348,14 +2367,26 @@ function prompt(editor, message, options, callback) { cmdLine.session.bgTokenizer.setTokenizer(tokenizer); } + if (options.placeholder) { + cmdLine.setOption("placeholder", options.placeholder); + } + + if (options.hasDescription) { + var promptTextContainer = dom.buildDom(["div", {class: "ace_prompt_text_container"}]); + dom.buildDom(options.prompt || "Press 'Enter' to confirm or 'Escape' to cancel", promptTextContainer); + el.appendChild(promptTextContainer); + } + + overlay.setIgnoreFocusOut(options.ignoreFocusOut); + function accept() { var val; - if (popup.getCursorPosition().row > 0) { + if (popup && popup.getCursorPosition().row > 0) { val = valueFromRecentList(); } else { val = cmdLine.getValue(); } - var curData = popup.getData(popup.getRow()); + var curData = popup ? popup.getData(popup.getRow()) : val; if (curData && !curData.error) { done(); options.onAccept && options.onAccept({ @@ -2365,22 +2396,29 @@ function prompt(editor, message, options, callback) { } } - cmdLine.commands.bindKeys({ + var keys = { "Enter": accept, "Esc|Shift-Esc": function() { options.onCancel && options.onCancel(cmdLine.getValue(), cmdLine); done(); - }, - "Up": function(editor) { popup.goTo("up"); valueFromRecentList();}, - "Down": function(editor) { popup.goTo("down"); valueFromRecentList();}, - "Ctrl-Up|Ctrl-Home": function(editor) { popup.goTo("start"); valueFromRecentList();}, - "Ctrl-Down|Ctrl-End": function(editor) { popup.goTo("end"); valueFromRecentList();}, - "Tab": function(editor) { - popup.goTo("down"); valueFromRecentList(); - }, - "PageUp": function(editor) { popup.gotoPageUp(); valueFromRecentList();}, - "PageDown": function(editor) { popup.gotoPageDown(); valueFromRecentList();} - }); + } + }; + + if (popup) { + Object.assign(keys, { + "Up": function(editor) { popup.goTo("up"); valueFromRecentList();}, + "Down": function(editor) { popup.goTo("down"); valueFromRecentList();}, + "Ctrl-Up|Ctrl-Home": function(editor) { popup.goTo("start"); valueFromRecentList();}, + "Ctrl-Down|Ctrl-End": function(editor) { popup.goTo("end"); valueFromRecentList();}, + "Tab": function(editor) { + popup.goTo("down"); valueFromRecentList(); + }, + "PageUp": function(editor) { popup.gotoPageUp(); valueFromRecentList();}, + "PageDown": function(editor) { popup.gotoPageDown(); valueFromRecentList();} + }); + } + + cmdLine.commands.bindKeys(keys); function done() { overlay.close(); @@ -2413,7 +2451,9 @@ function prompt(editor, message, options, callback) { } cmdLine.resize(true); - popup.resize(true); + if (popup) { + popup.resize(true); + } cmdLine.focus(); openPrompt = { diff --git a/htdocs/includes/ace/src/ext-settings_menu.js b/htdocs/includes/ace/src/ext-settings_menu.js index d10afac8f34..ebfa4108519 100644 --- a/htdocs/includes/ace/src/ext-settings_menu.js +++ b/htdocs/includes/ace/src/ext-settings_menu.js @@ -65,6 +65,7 @@ dom.importCssString(cssText); module.exports.overlayPage = function overlayPage(editor, contentElement, callback) { var closer = document.createElement('div'); + var ignoreFocusOut = false; function documentEscListener(e) { if (e.keyCode === 27) { @@ -76,17 +77,28 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba if (!closer) return; document.removeEventListener('keydown', documentEscListener); closer.parentNode.removeChild(closer); - editor.focus(); + if (editor) { + editor.focus(); + } closer = null; callback && callback(); } + function setIgnoreFocusOut(ignore) { + ignoreFocusOut = ignore; + if (ignore) { + closer.style.pointerEvents = "none"; + contentElement.style.pointerEvents = "auto"; + } + } closer.style.cssText = 'margin: 0; padding: 0; ' + 'position: fixed; top:0; bottom:0; left:0; right:0;' + 'z-index: 9990; ' + - 'background-color: rgba(0, 0, 0, 0.3);'; - closer.addEventListener('click', function() { - close(); + (editor ? 'background-color: rgba(0, 0, 0, 0.3);' : ''); + closer.addEventListener('click', function(e) { + if (!ignoreFocusOut) { + close(); + } }); document.addEventListener('keydown', documentEscListener); @@ -96,9 +108,12 @@ module.exports.overlayPage = function overlayPage(editor, contentElement, callba closer.appendChild(contentElement); document.body.appendChild(closer); - editor.blur(); + if (editor) { + editor.blur(); + } return { - close: close + close: close, + setIgnoreFocusOut: setIgnoreFocusOut }; }; @@ -207,6 +222,7 @@ var supportedModes = { Jade: ["jade|pug"], Java: ["java"], JavaScript: ["js|jsm|jsx"], + JSON5: ["json5"], JSON: ["json"], JSONiq: ["jq"], JSP: ["jsp"], @@ -237,6 +253,7 @@ var supportedModes = { Nix: ["nix"], Nim: ["nim"], NSIS: ["nsi|nsh"], + Nunjucks: ["nunjucks|nunjs|nj|njk"], ObjectiveC: ["m|mm"], OCaml: ["ml|mli"], Pascal: ["pas|p"], @@ -396,9 +413,9 @@ exports.themes = themeData.map(function(data) { define("ace/ext/options",["require","exports","module","ace/ext/menu_tools/overlay_page","ace/lib/dom","ace/lib/oop","ace/config","ace/lib/event_emitter","ace/ext/modelist","ace/ext/themelist"], function(require, exports, module) { "use strict"; -var overlayPage = require('./menu_tools/overlay_page').overlayPage; - +require("./menu_tools/overlay_page"); + var dom = require("../lib/dom"); var oop = require("../lib/oop"); var config = require("../config"); @@ -437,7 +454,8 @@ var optionGroups = { { caption : "Ace", value : null }, { caption : "Vim", value : "ace/keyboard/vim" }, { caption : "Emacs", value : "ace/keyboard/emacs" }, - { caption : "Sublime", value : "ace/keyboard/sublime" } + { caption : "Sublime", value : "ace/keyboard/sublime" }, + { caption : "VSCode", value : "ace/keyboard/vscode" } ] }, "Font Size": { diff --git a/htdocs/includes/ace/src/ext-spellcheck.js b/htdocs/includes/ace/src/ext-spellcheck.js index 6f5af5049d7..10d3901f49f 100644 --- a/htdocs/includes/ace/src/ext-spellcheck.js +++ b/htdocs/includes/ace/src/ext-spellcheck.js @@ -28,7 +28,6 @@ exports.contextMenuHandler = function(e){ }); host.textInput.setInputHandler(function(newVal) { - console.log(newVal , value, text.selectionStart, text.selectionEnd); if (newVal == value) return ''; if (newVal.lastIndexOf(value, 0) === 0) diff --git a/htdocs/includes/ace/src/keybinding-emacs.js b/htdocs/includes/ace/src/keybinding-emacs.js index 960ff734b3d..58e79cd44fc 100644 --- a/htdocs/includes/ace/src/keybinding-emacs.js +++ b/htdocs/includes/ace/src/keybinding-emacs.js @@ -548,8 +548,6 @@ function objectToRegExp(obj) { if (this.$editor.showCommandLine) { this.$editor.showCommandLine(msg); this.$editor.focus(); - } else { - console.log(msg); } }; diff --git a/htdocs/includes/ace/src/keybinding-sublime.js b/htdocs/includes/ace/src/keybinding-sublime.js index e34735b2ae0..21fcb3803c6 100644 --- a/htdocs/includes/ace/src/keybinding-sublime.js +++ b/htdocs/includes/ace/src/keybinding-sublime.js @@ -1,9 +1,6 @@ -define("ace/keyboard/sublime",["require","exports","module","ace/lib/keys","ace/lib/oop","ace/lib/useragent","ace/keyboard/hash_handler"], function(require, exports, module) { +define("ace/keyboard/sublime",["require","exports","module","ace/keyboard/hash_handler"], function(require, exports, module) { "use strict"; -var keyUtil = require("../lib/keys"); -var oop = require("../lib/oop"); -var useragent = require("../lib/useragent"); var HashHandler = require("../keyboard/hash_handler").HashHandler; function moveBySubWords(editor, direction, extend) { @@ -373,7 +370,7 @@ exports.handler.addCommands([{ }, { bindKey: { mac: "cmd-shift-l", win: "ctrl-shift-l" }, - name: "splitIntoLines" + name: "splitSelectionIntoLines" }, { bindKey: { mac: "ctrl-cmd-down", win: "ctrl-shift-down" }, name: "movelinesdown" diff --git a/htdocs/includes/ace/src/keybinding-vim.js b/htdocs/includes/ace/src/keybinding-vim.js index 889c2269ac7..79761280e93 100644 --- a/htdocs/includes/ace/src/keybinding-vim.js +++ b/htdocs/includes/ace/src/keybinding-vim.js @@ -435,6 +435,7 @@ define("ace/keyboard/vim",["require","exports","module","ace/range","ace/lib/eve if (!e) e = s; return this.ace.session.replace(new Range(s.line, s.ch, e.line, e.ch), text); }; + this.replaceSelection = this.replaceSelections = function(p) { var sel = this.ace.selection; if (this.ace.inVirtualSelectionMode) { @@ -846,6 +847,8 @@ dom.importCssString(".normal-mode .ace_cursor{\ { keys: '', type: 'keyToKey', toKeys: '' }, { keys: '', type: 'keyToKey', toKeys: '', context: 'insert' }, { keys: '', type: 'keyToKey', toKeys: '', context: 'insert' }, + { keys: '', type: 'keyToKey', toKeys: '' }, // ace_patch ipad keyboard sends C-Esc instead of C-[ + { keys: '', type: 'keyToKey', toKeys: '', context: 'insert' }, { keys: 's', type: 'keyToKey', toKeys: 'cl', context: 'normal' }, { keys: 's', type: 'keyToKey', toKeys: 'c', context: 'visual'}, { keys: 'S', type: 'keyToKey', toKeys: 'cc', context: 'normal' }, @@ -940,7 +943,9 @@ dom.importCssString(".normal-mode .ace_cursor{\ { keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'eol' }, context: 'normal' }, { keys: 'A', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'endOfSelectedArea' }, context: 'visual' }, { keys: 'i', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'inplace' }, context: 'normal' }, + { keys: 'gi', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'lastEdit' }, context: 'normal' }, { keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'firstNonBlank'}, context: 'normal' }, + { keys: 'gI', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'bol'}, context: 'normal' }, { keys: 'I', type: 'action', action: 'enterInsertMode', isEdit: true, actionArgs: { insertAt: 'startOfSelectedArea' }, context: 'visual' }, { keys: 'o', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: true }, context: 'normal' }, { keys: 'O', type: 'action', action: 'newLineAndEnterInsertMode', isEdit: true, interlaceInsertRepeat: true, actionArgs: { after: false }, context: 'normal' }, @@ -950,6 +955,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ { keys: '', type: 'action', action: 'toggleVisualMode', actionArgs: { blockwise: true }}, { keys: 'gv', type: 'action', action: 'reselectLastSelection' }, { keys: 'J', type: 'action', action: 'joinLines', isEdit: true }, + { keys: 'gJ', type: 'action', action: 'joinLines', actionArgs: { keepSpaces: true }, isEdit: true }, { keys: 'p', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: true, isEdit: true }}, { keys: 'P', type: 'action', action: 'paste', isEdit: true, actionArgs: { after: false, isEdit: true }}, { keys: 'r', type: 'action', action: 'replace', isEdit: true }, @@ -1026,7 +1032,6 @@ dom.importCssString(".normal-mode .ace_cursor{\ CodeMirror.off(cm.getInputField(), 'paste', getOnPasteFn(cm)); cm.state.vim = null; } - function detachVimMap(cm, next) { if (this == CodeMirror.keyMap.vim) CodeMirror.rmClass(cm.getWrapperElement(), "cm-fat-cursor"); @@ -1296,9 +1301,16 @@ dom.importCssString(".normal-mode .ace_cursor{\ } return mark; } + function find(cm, offset) { + var oldPointer = pointer; + var mark = move(cm, offset); + pointer = oldPointer; + return mark && mark.find(); + } return { cachedCursor: undefined, //used for # and * jumps add: add, + find: find, move: move }; }; @@ -1943,6 +1955,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ }); } function onPromptClose(query) { + cm.scrollTo(originalScrollPos.left, originalScrollPos.top); handleQuery(query, true /** ignoreCase */, true /** smartCase */); var macroModeState = vimGlobalState.macroModeState; if (macroModeState.isRecording) { @@ -2514,7 +2527,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ } } if (ch < lineText.length) { - var re = /[<>]/.test(lineText[ch]) ? /[(){}[\]<>]/ : /[(){}[\]]/; + var re = /[<>]/.test(lineText[ch]) ? /[(){}[\]<>]/ : /[(){}[\]]/; //ace_patch? var matched = cm.findMatchingBracket(Pos(line, ch+1), {bracketRegex: re}); return matched.to; } else { @@ -2643,8 +2656,8 @@ dom.importCssString(".normal-mode .ace_cursor{\ head.line--; cm.setSelection(anchor, head) text = cm.getSelection(); - cm.replaceSelections(""); - finalHead = anchor + cm.replaceSelection(""); + finalHead = anchor; } else { text = cm.getSelection(); var replacement = fillArray('', ranges.length); @@ -2864,6 +2877,8 @@ dom.importCssString(".normal-mode .ace_cursor{\ var height = cm.listSelections().length; if (insertAt == 'eol') { head = Pos(head.line, lineLength(cm, head.line)); + } else if (insertAt == 'bol') { + head = Pos(head.line, 0); } else if (insertAt == 'charAfter') { head = offsetCursor(head, 0, 1); } else if (insertAt == 'firstNonBlank') { @@ -2902,6 +2917,8 @@ dom.importCssString(".normal-mode .ace_cursor{\ if (vim.visualMode){ return; } + } else if (insertAt == 'lastEdit') { + head = getLastEditPos(cm) || head; } cm.setOption('disableInput', false); if (actionArgs && actionArgs.replace) { @@ -3001,7 +3018,9 @@ dom.importCssString(".normal-mode .ace_cursor{\ var tmp = Pos(curStart.line + 1, lineLength(cm, curStart.line + 1)); var text = cm.getRange(curStart, tmp); - text = text.replace(/\n\s*/g, ' '); + text = actionArgs.keepSpaces + ? text.replace(/\n\r?/g, '') + : text.replace(/\n\s*/g, ' '); cm.replaceRange(text, curStart, tmp); } var curFinalPos = Pos(curStart.line, finalCh); @@ -4583,11 +4602,22 @@ dom.importCssString(".normal-mode .ace_cursor{\ } function getMarkPos(cm, vim, markName) { + if (markName == '\'' || markName == '`') { + return vimGlobalState.jumpList.find(cm, -1) || Pos(0, 0); + } else if (markName == '.') { + return getLastEditPos(cm); + } var mark = vim.marks[markName]; return mark && mark.find(); } + function getLastEditPos(cm) { + var undoManager = cm.ace.session.$undoManager; + if (undoManager && undoManager.$lastDelta) + return toCmPos(undoManager.$lastDelta.end); + } + var ExCommandDispatcher = function() { this.buildCommandMap_(); }; @@ -5068,6 +5098,9 @@ dom.importCssString(".normal-mode .ace_cursor{\ var global = false; // True to replace all instances on a line, false to replace only 1. if (tokens.length) { regexPart = tokens[0]; + if (getOption('pcre') && regexPart !== '') { + regexPart = new RegExp(regexPart).source; //normalize not escaped characters + } replacePart = tokens[1]; if (regexPart && regexPart[regexPart.length - 1] === '$') { regexPart = regexPart.slice(0, regexPart.length - 1) + '\\n'; @@ -5075,7 +5108,7 @@ dom.importCssString(".normal-mode .ace_cursor{\ } if (replacePart !== undefined) { if (getOption('pcre')) { - replacePart = unescapeRegexReplace(replacePart); + replacePart = unescapeRegexReplace(replacePart.replace(/([^\\])&/g,"$1$$&")); } else { replacePart = translateRegexReplace(replacePart); } @@ -5101,7 +5134,11 @@ dom.importCssString(".normal-mode .ace_cursor{\ global = true; flagsPart.replace('g', ''); } - regexPart = regexPart.replace(/\//g, "\\/") + '/' + flagsPart; + if (getOption('pcre')) { + regexPart = regexPart + '/' + flagsPart; + } else { + regexPart = regexPart.replace(/\//g, "\\/") + '/' + flagsPart; + } } } if (regexPart) { diff --git a/htdocs/includes/ace/src/keybinding-vscode.js b/htdocs/includes/ace/src/keybinding-vscode.js new file mode 100644 index 00000000000..45ac5cf03ff --- /dev/null +++ b/htdocs/includes/ace/src/keybinding-vscode.js @@ -0,0 +1,262 @@ +define("ace/keyboard/vscode",["require","exports","module","ace/keyboard/hash_handler","ace/config"], function(require, exports, module) { +"use strict"; + +var HashHandler = require("../keyboard/hash_handler").HashHandler; +var config = require("../config"); + +exports.handler = new HashHandler(); +exports.handler.$id = "ace/keyboard/vscode"; + +exports.handler.addCommands([{ + name: "toggleWordWrap", + exec: function(editor) { + var wrapUsed = editor.session.getUseWrapMode(); + editor.session.setUseWrapMode(!wrapUsed); + }, + readOnly: true +}, { + name: "navigateToLastEditLocation", + exec: function(editor) { + var lastDelta = editor.session.getUndoManager().$lastDelta; + var range = (lastDelta.action == "remove")? lastDelta.start: lastDelta.end; + editor.moveCursorTo(range.row, range.column); + editor.clearSelection(); + } +}, { + name: "replaceAll", + exec: function (editor) { + if (!editor.searchBox) { + config.loadModule("ace/ext/searchbox", function(e) { + e.Search(editor, true); + }); + } else { + if (editor.searchBox.active === true && editor.searchBox.replaceOption.checked === true) { + editor.searchBox.replaceAll(); + } + } + } +}, { + name: "replaceOne", + exec: function (editor) { + if (!editor.searchBox) { + config.loadModule("ace/ext/searchbox", function(e) { + e.Search(editor, true); + }); + } else { + if (editor.searchBox.active === true && editor.searchBox.replaceOption.checked === true) { + editor.searchBox.replace(); + } + } + } +}, { + name: "selectAllMatches", + exec: function (editor) { + if (!editor.searchBox) { + config.loadModule("ace/ext/searchbox", function(e) { + e.Search(editor, false); + }); + } else { + if (editor.searchBox.active === true) { + editor.searchBox.findAll(); + } + } + } +}, { + name: "toggleFindCaseSensitive", + exec: function (editor) { + config.loadModule("ace/ext/searchbox", function(e) { + e.Search(editor, false); + var sb = editor.searchBox; + sb.caseSensitiveOption.checked = !sb.caseSensitiveOption.checked; + sb.$syncOptions(); + }); + + } +}, { + name: "toggleFindInSelection", + exec: function (editor) { + config.loadModule("ace/ext/searchbox", function(e) { + e.Search(editor, false); + var sb = editor.searchBox; + sb.searchOption.checked = !sb.searchRange; + sb.setSearchRange(sb.searchOption.checked && sb.editor.getSelectionRange()); + sb.$syncOptions(); + }); + } +}, { + name: "toggleFindRegex", + exec: function (editor) { + config.loadModule("ace/ext/searchbox", function(e) { + e.Search(editor, false); + var sb = editor.searchBox; + sb.regExpOption.checked = !sb.regExpOption.checked; + sb.$syncOptions(); + }); + } +}, { + name: "toggleFindWholeWord", + exec: function (editor) { + config.loadModule("ace/ext/searchbox", function(e) { + e.Search(editor, false); + var sb = editor.searchBox; + sb.wholeWordOption.checked = !sb.wholeWordOption.checked; + sb.$syncOptions(); + }); + } +}, { + name: "removeSecondaryCursors", + exec: function (editor) { + var ranges = editor.selection.ranges; + if (ranges && ranges.length > 1) + editor.selection.toSingleRange(ranges[ranges.length - 1]); + else + editor.selection.clearSelection(); + } +}]); + + +[{ + bindKey: {mac: "Control-G", win: "Ctrl-G"}, + name: "gotoline" +}, { + bindKey: {mac: "Command-Shift-L|Command-F2", win: "Ctrl-Shift-L|Ctrl-F2"}, + name: "findAll" +}, { + bindKey: {mac: "Shift-F8|Shift-Option-F8", win: "Shift-F8|Shift-Alt-F8"}, + name: "goToPreviousError" +}, { + bindKey: {mac: "F8|Option-F8", win: "F8|Alt-F8"}, + name: "goToNextError" +}, { + bindKey: {mac: "Command-Shift-P|F1", win: "Ctrl-Shift-P|F1"}, + name: "openCommandPallete" +}, { + bindKey: {mac: "Command-K|Command-S", win: "Ctrl-K|Ctrl-S"}, + name: "showKeyboardShortcuts" +}, { + bindKey: {mac: "Shift-Option-Up", win: "Alt-Shift-Up"}, + name: "copylinesup" +}, { + bindKey: {mac: "Shift-Option-Down", win: "Alt-Shift-Down"}, + name: "copylinesdown" +}, { + bindKey: {mac: "Command-Shift-K", win: "Ctrl-Shift-K"}, + name: "removeline" +}, { + bindKey: {mac: "Command-Enter", win: "Ctrl-Enter"}, + name: "addLineAfter" +}, { + bindKey: {mac: "Command-Shift-Enter", win: "Ctrl-Shift-Enter"}, + name: "addLineBefore" +}, { + bindKey: {mac: "Command-Shift-\\", win: "Ctrl-Shift-\\"}, + name: "jumptomatching" +}, { + bindKey: {mac: "Command-]", win: "Ctrl-]"}, + name: "blockindent" +}, { + bindKey: {mac: "Command-[", win: "Ctrl-["}, + name: "blockoutdent" +}, { + bindKey: {mac: "Control-PageDown", win: "Alt-PageDown"}, + name: "pagedown" +}, { + bindKey: {mac: "Control-PageUp", win: "Alt-PageUp"}, + name: "pageup" +}, { + bindKey: {mac: "Shift-Option-A", win: "Shift-Alt-A"}, + name: "toggleBlockComment" +}, { + bindKey: {mac: "Option-Z", win: "Alt-Z"}, + name: "toggleWordWrap" +}, { + bindKey: {mac: "Command-G", win: "F3|Ctrl-K Ctrl-D"}, + name: "findnext" +}, { + bindKey: {mac: "Command-Shift-G", win: "Shift-F3"}, + name: "findprevious" +}, { + bindKey: {mac: "Option-Enter", win: "Alt-Enter"}, + name: "selectAllMatches" +}, { + bindKey: {mac: "Command-D", win: "Ctrl-D"}, + name: "selectMoreAfter" +}, { + bindKey: {mac: "Command-K Command-D", win: "Ctrl-K Ctrl-D"}, + name: "selectOrFindNext" +}, { + bindKey: {mac: "Shift-Option-I", win: "Shift-Alt-I"}, + name: "splitSelectionIntoLines" +}, { + bindKey: {mac: "Command-K M", win: "Ctrl-K M"}, + name: "modeSelect" +}, { + bindKey: {mac: "Command-Option-[", win: "Ctrl-Shift-["}, + name: "toggleFoldWidget" +}, { + bindKey: {mac: "Command-Option-]", win: "Ctrl-Shift-]"}, + name: "toggleFoldWidget" +}, { + bindKey: {mac: "Command-K Command-0", win: "Ctrl-K Ctrl-0"}, + name: "foldall" +}, { + bindKey: {mac: "Command-K Command-J", win: "Ctrl-K Ctrl-J"}, + name: "unfoldall" +}, { + bindKey: { mac: "Command-K Command-1", win: "Ctrl-K Ctrl-1" }, + name: "foldOther" +}, { + bindKey: { mac: "Command-K Command-Q", win: "Ctrl-K Ctrl-Q" }, + name: "navigateToLastEditLocation" +}, { + bindKey: { mac: "Command-K Command-R|Command-K Command-S", win: "Ctrl-K Ctrl-R|Ctrl-K Ctrl-S" }, + name: "showKeyboardShortcuts" +}, { + bindKey: { mac: "Command-K Command-X", win: "Ctrl-K Ctrl-X" }, + name: "trimTrailingSpace" +}, { + bindKey: {mac: "Shift-Down|Command-Shift-Down", win: "Shift-Down|Ctrl-Shift-Down"}, + name: "selectdown" +}, { + bindKey: {mac: "Shift-Up|Command-Shift-Up", win: "Shift-Up|Ctrl-Shift-Up"}, + name: "selectup" +}, { + bindKey: {mac: "Command-Alt-Enter", win: "Ctrl-Alt-Enter"}, + name: "replaceAll" +}, { + bindKey: {mac: "Command-Shift-1", win: "Ctrl-Shift-1"}, + name: "replaceOne" +}, { + bindKey: {mac: "Option-C", win: "Alt-C"}, + name: "toggleFindCaseSensitive" +}, { + bindKey: {mac: "Option-L", win: "Alt-L"}, + name: "toggleFindInSelection" +}, { + bindKey: {mac: "Option-R", win: "Alt-R"}, + name: "toggleFindRegex" +}, { + bindKey: {mac: "Option-W", win: "Alt-W"}, + name: "toggleFindWholeWord" +}, { + bindKey: {mac: "Command-L", win: "Ctrl-L"}, + name: "expandtoline" +}, { + bindKey: {mac: "Shift-Esc", win: "Shift-Esc"}, + name: "removeSecondaryCursors" +} +].forEach(function(binding) { + var command = exports.handler.commands[binding.name]; + if (command) + command.bindKey = binding.bindKey; + exports.handler.bindKey(binding.bindKey, command || binding.name); +}); + +}); (function() { + window.require(["ace/keyboard/vscode"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/mode-csound_document.js b/htdocs/includes/ace/src/mode-csound_document.js index b4495c6892f..ae92fce17e1 100644 --- a/htdocs/includes/ace/src/mode-csound_document.js +++ b/htdocs/includes/ace/src/mode-csound_document.js @@ -1146,6 +1146,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ampdb", "ampdbfs", "ampmidi", + "ampmidicurve", "ampmidid", "areson", "aresonk", @@ -1194,7 +1195,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ceps", "cepsinv", "chanctrl", - "changed", "changed2", "chani", "chano", @@ -1363,6 +1363,17 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "flooper", "flooper2", "floor", + "fluidAllOut", + "fluidCCi", + "fluidCCk", + "fluidControl", + "fluidEngine", + "fluidInfo", + "fluidLoad", + "fluidNote", + "fluidOut", + "fluidProgramSelect", + "fluidSetInterpMethod", "fmanal", "fmax", "fmb3", @@ -1437,6 +1448,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "grain2", "grain3", "granule", + "gtf", "guiro", "harmon", "harmon2", @@ -1845,6 +1857,8 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "nsamp", "nstance", "nstrnum", + "nstrstr", + "ntof", "ntom", "ntrpol", "nxtpow2", @@ -1975,7 +1989,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ptable", "ptable3", "ptablei", - "ptableiw", "ptablew", "ptrack", "puts", @@ -2282,6 +2295,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "strget", "strindex", "strindexk", + "string2array", "strlen", "strlenk", "strlower", @@ -2325,7 +2339,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "tableigpw", "tableikt", "tableimix", - "tableiw", "tablekt", "tablemix", "tableng", @@ -2533,6 +2546,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "array", "bformdec", "bformenc", + "changed", "copy2ftab", "copy2ttab", "hrtfer", @@ -2542,6 +2556,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "mintab", "pop", "pop_f", + "ptableiw", "push", "push_f", "scalet", @@ -2560,6 +2575,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "stack", "sumtab", "tabgen", + "tableiw", "tabmap", "tabmap_i", "tabslice", diff --git a/htdocs/includes/ace/src/mode-csound_orchestra.js b/htdocs/includes/ace/src/mode-csound_orchestra.js index 7f1a60442aa..7cb3917c9f4 100644 --- a/htdocs/includes/ace/src/mode-csound_orchestra.js +++ b/htdocs/includes/ace/src/mode-csound_orchestra.js @@ -1146,6 +1146,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ampdb", "ampdbfs", "ampmidi", + "ampmidicurve", "ampmidid", "areson", "aresonk", @@ -1194,7 +1195,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ceps", "cepsinv", "chanctrl", - "changed", "changed2", "chani", "chano", @@ -1363,6 +1363,17 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "flooper", "flooper2", "floor", + "fluidAllOut", + "fluidCCi", + "fluidCCk", + "fluidControl", + "fluidEngine", + "fluidInfo", + "fluidLoad", + "fluidNote", + "fluidOut", + "fluidProgramSelect", + "fluidSetInterpMethod", "fmanal", "fmax", "fmb3", @@ -1437,6 +1448,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "grain2", "grain3", "granule", + "gtf", "guiro", "harmon", "harmon2", @@ -1845,6 +1857,8 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "nsamp", "nstance", "nstrnum", + "nstrstr", + "ntof", "ntom", "ntrpol", "nxtpow2", @@ -1975,7 +1989,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "ptable", "ptable3", "ptablei", - "ptableiw", "ptablew", "ptrack", "puts", @@ -2282,6 +2295,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "strget", "strindex", "strindexk", + "string2array", "strlen", "strlenk", "strlower", @@ -2325,7 +2339,6 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "tableigpw", "tableikt", "tableimix", - "tableiw", "tablekt", "tablemix", "tableng", @@ -2533,6 +2546,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "array", "bformdec", "bformenc", + "changed", "copy2ftab", "copy2ttab", "hrtfer", @@ -2542,6 +2556,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "mintab", "pop", "pop_f", + "ptableiw", "push", "push_f", "scalet", @@ -2560,6 +2575,7 @@ var CsoundOrchestraHighlightRules = function(embeddedRulePrefix) { "stack", "sumtab", "tabgen", + "tableiw", "tabmap", "tabmap_i", "tabslice", diff --git a/htdocs/includes/ace/src/mode-jade.js b/htdocs/includes/ace/src/mode-jade.js index 51c796d73f2..5c3488944ce 100644 --- a/htdocs/includes/ace/src/mode-jade.js +++ b/htdocs/includes/ace/src/mode-jade.js @@ -1083,7 +1083,7 @@ var MarkdownHighlightRules = function() { next : "blockquote" }, { // HR * - _ token : "constant", - regex : "^ {0,2}(?:(?: ?\\* ?){3,}|(?: ?\\- ?){3,}|(?: ?\\_ ?){3,})\\s*$", + regex : "^ {0,3}(?:(?:\\* ?){3,}|(?:\\- ?){3,}|(?:\\_ ?){3,})\\s*$", next: "allowBlock" }, { // list token : "markup.list", diff --git a/htdocs/includes/ace/src/mode-json5.js b/htdocs/includes/ace/src/mode-json5.js new file mode 100644 index 00000000000..539fd2f2160 --- /dev/null +++ b/htdocs/includes/ace/src/mode-json5.js @@ -0,0 +1,360 @@ +define("ace/mode/json_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var JsonHighlightRules = function() { + this.$rules = { + "start" : [ + { + token : "variable", // single line + regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]\\s*(?=:)' + }, { + token : "string", // single line + regex : '"', + next : "string" + }, { + token : "constant.numeric", // hex + regex : "0[xX][0-9a-fA-F]+\\b" + }, { + token : "constant.numeric", // float + regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" + }, { + token : "constant.language.boolean", + regex : "(?:true|false)\\b" + }, { + token : "text", // single quoted strings are not allowed + regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" + }, { + token : "comment", // comments are not allowed, but who cares? + regex : "\\/\\/.*$" + }, { + token : "comment.start", // comments are not allowed, but who cares? + regex : "\\/\\*", + next : "comment" + }, { + token : "paren.lparen", + regex : "[[({]" + }, { + token : "paren.rparen", + regex : "[\\])}]" + }, { + token : "text", + regex : "\\s+" + } + ], + "string" : [ + { + token : "constant.language.escape", + regex : /\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|["\\\/bfnrt])/ + }, { + token : "string", + regex : '"|$', + next : "start" + }, { + defaultToken : "string" + } + ], + "comment" : [ + { + token : "comment.end", // comments are not allowed, but who cares? + regex : "\\*\\/", + next : "start" + }, { + defaultToken: "comment" + } + ] + }; + +}; + +oop.inherits(JsonHighlightRules, TextHighlightRules); + +exports.JsonHighlightRules = JsonHighlightRules; +}); + +define("ace/mode/json5_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/json_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var JsonHighlightRules = require("./json_highlight_rules").JsonHighlightRules; + +var Json5HighlightRules = function() { + JsonHighlightRules.call(this); + + var startRules = [{ + token : "variable", + regex : /[a-zA-Z$_\u00a1-\uffff][\w$\u00a1-\uffff]*\s*(?=:)/ + }, { + token : "variable", + regex : /['](?:(?:\\.)|(?:[^'\\]))*?[']\s*(?=:)/ + }, { + token : "constant.language.boolean", + regex : /(?:null)\b/ + }, { + token : "string", + regex : /'/, + next : [{ + token : "constant.language.escape", + regex : /\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|["\/bfnrt]|$)/, + consumeLineEnd : true + }, { + token : "string", + regex : /'|$/, + next : "start" + }, { + defaultToken : "string" + }] + }, { + token : "string", + regex : /"(?![^"]*":)/, + next : [{ + token : "constant.language.escape", + regex : /\\(?:x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|["\/bfnrt]|$)/, + consumeLineEnd : true + }, { + token : "string", + regex : /"|$/, + next : "start" + }, { + defaultToken : "string" + }] + }, { + token : "constant.numeric", + regex : /[+-]?(?:Infinity|NaN)\b/ + }]; + + for (var key in this.$rules) + this.$rules[key].unshift.apply(this.$rules[key], startRules); + + this.normalizeRules(); +}; + +oop.inherits(Json5HighlightRules, JsonHighlightRules); + +exports.Json5HighlightRules = Json5HighlightRules; +}); + +define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) { +"use strict"; + +var Range = require("../range").Range; + +var MatchingBraceOutdent = function() {}; + +(function() { + + this.checkOutdent = function(line, input) { + if (! /^\s+$/.test(line)) + return false; + + return /^\s*\}/.test(input); + }; + + this.autoOutdent = function(doc, row) { + var line = doc.getLine(row); + var match = line.match(/^(\s*\})/); + + if (!match) return 0; + + var column = match[1].length; + var openBracePos = doc.findMatchingBracket({row: row, column: column}); + + if (!openBracePos || openBracePos.row == row) return 0; + + var indent = this.$getIndent(doc.getLine(openBracePos.row)); + doc.replace(new Range(row, 0, row, column-1), indent); + }; + + this.$getIndent = function(line) { + return line.match(/^\s*/)[0]; + }; + +}).call(MatchingBraceOutdent.prototype); + +exports.MatchingBraceOutdent = MatchingBraceOutdent; +}); + +define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Range = require("../../range").Range; +var BaseFoldMode = require("./fold_mode").FoldMode; + +var FoldMode = exports.FoldMode = function(commentRegex) { + if (commentRegex) { + this.foldingStartMarker = new RegExp( + this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) + ); + this.foldingStopMarker = new RegExp( + this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) + ); + } +}; +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + + this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/; + this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/; + this.singleLineBlockCommentRe= /^\s*(\/\*).*\*\/\s*$/; + this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/; + this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/; + this._getFoldWidgetBase = this.getFoldWidget; + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + + if (this.singleLineBlockCommentRe.test(line)) { + if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line)) + return ""; + } + + var fw = this._getFoldWidgetBase(session, foldStyle, row); + + if (!fw && this.startRegionRe.test(line)) + return "start"; // lineCommentRegionStart + + return fw; + }; + + this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { + var line = session.getLine(row); + + if (this.startRegionRe.test(line)) + return this.getCommentRegionBlock(session, line, row); + + var match = line.match(this.foldingStartMarker); + if (match) { + var i = match.index; + + if (match[1]) + return this.openingBracketBlock(session, match[1], row, i); + + var range = session.getCommentFoldRange(row, i + match[0].length, 1); + + if (range && !range.isMultiLine()) { + if (forceMultiline) { + range = this.getSectionRange(session, row); + } else if (foldStyle != "all") + range = null; + } + + return range; + } + + if (foldStyle === "markbegin") + return; + + var match = line.match(this.foldingStopMarker); + if (match) { + var i = match.index + match[0].length; + + if (match[1]) + return this.closingBracketBlock(session, match[1], row, i); + + return session.getCommentFoldRange(row, i, -1); + } + }; + + this.getSectionRange = function(session, row) { + var line = session.getLine(row); + var startIndent = line.search(/\S/); + var startRow = row; + var startColumn = line.length; + row = row + 1; + var endRow = row; + var maxRow = session.getLength(); + while (++row < maxRow) { + line = session.getLine(row); + var indent = line.search(/\S/); + if (indent === -1) + continue; + if (startIndent > indent) + break; + var subRange = this.getFoldWidgetRange(session, "all", row); + + if (subRange) { + if (subRange.start.row <= startRow) { + break; + } else if (subRange.isMultiLine()) { + row = subRange.end.row; + } else if (startIndent == indent) { + break; + } + } + endRow = row; + } + + return new Range(startRow, startColumn, endRow, session.getLine(endRow).length); + }; + this.getCommentRegionBlock = function(session, line, row) { + var startColumn = line.search(/\s*$/); + var maxRow = session.getLength(); + var startRow = row; + + var re = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/; + var depth = 1; + while (++row < maxRow) { + line = session.getLine(row); + var m = re.exec(line); + if (!m) continue; + if (m[1]) depth--; + else depth++; + + if (!depth) break; + } + + var endRow = row; + if (endRow > startRow) { + return new Range(startRow, startColumn, endRow, line.length); + } + }; + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/json5",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/json5_highlight_rules","ace/mode/matching_brace_outdent","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var HighlightRules = require("./json5_highlight_rules").Json5HighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; +var CStyleFoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = HighlightRules; + this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CstyleBehaviour(); + this.foldingRules = new CStyleFoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + this.lineCommentStart = "//"; + this.blockComment = {start: "/*", end: "*/"}; + + this.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); + }; + + this.autoOutdent = function(state, doc, row) { + this.$outdent.autoOutdent(doc, row); + }; + + this.$id = "ace/mode/json5"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); (function() { + window.require(["ace/mode/json5"], function(m) { + if (typeof module == "object" && typeof exports == "object" && module) { + module.exports = m; + } + }); + })(); + \ No newline at end of file diff --git a/htdocs/includes/ace/src/mode-markdown.js b/htdocs/includes/ace/src/mode-markdown.js index 380fab69915..ac4072175ec 100644 --- a/htdocs/includes/ace/src/mode-markdown.js +++ b/htdocs/includes/ace/src/mode-markdown.js @@ -2625,7 +2625,7 @@ var MarkdownHighlightRules = function() { next : "blockquote" }, { // HR * - _ token : "constant", - regex : "^ {0,2}(?:(?: ?\\* ?){3,}|(?: ?\\- ?){3,}|(?: ?\\_ ?){3,})\\s*$", + regex : "^ {0,3}(?:(?:\\* ?){3,}|(?:\\- ?){3,}|(?:\\_ ?){3,})\\s*$", next: "allowBlock" }, { // list token : "markup.list", diff --git a/htdocs/includes/ace/src/mode-mask.js b/htdocs/includes/ace/src/mode-mask.js index 83cc5fe70b3..7a60ff04e9a 100644 --- a/htdocs/includes/ace/src/mode-mask.js +++ b/htdocs/includes/ace/src/mode-mask.js @@ -1083,7 +1083,7 @@ var MarkdownHighlightRules = function() { next : "blockquote" }, { // HR * - _ token : "constant", - regex : "^ {0,2}(?:(?: ?\\* ?){3,}|(?: ?\\- ?){3,}|(?: ?\\_ ?){3,})\\s*$", + regex : "^ {0,3}(?:(?:\\* ?){3,}|(?:\\- ?){3,}|(?:\\_ ?){3,})\\s*$", next: "allowBlock" }, { // list token : "markup.list", diff --git a/htdocs/includes/ace/src/mode-nsis.js b/htdocs/includes/ace/src/mode-nsis.js index 2b8b5061a6d..67c2abec063 100644 --- a/htdocs/includes/ace/src/mode-nsis.js +++ b/htdocs/includes/ace/src/mode-nsis.js @@ -13,7 +13,7 @@ var NSISHighlightRules = function() { caseInsensitive: true }, { token: "keyword.command.nsis", - regex: /^\s*(?:Abort|AddBrandingImage|AddSize|AllowRootDirInstall|AllowSkipFiles|AutoCloseWindow|BGFont|BGGradient|BrandingText|BringToFront|Call|CallInstDLL|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|CreateDirectory|CreateFont|CreateShortCut|Delete|DeleteINISec|DeleteINIStr|DeleteRegKey|DeleteRegValue|DetailPrint|DetailsButtonText|DirText|DirVar|DirVerify|EnableWindow|EnumRegKey|EnumRegValue|Exch|Exec|ExecShell|ExecShellWait|ExecWait|ExpandEnvStrings|File|FileBufSize|FileClose|FileErrorText|FileOpen|FileRead|FileReadByte|FileReadUTF16LE|FileReadWord|FileWriteUTF16LE|FileSeek|FileWrite|FileWriteByte|FileWriteWord|FindClose|FindFirst|FindNext|FindWindow|FlushINI|GetCurInstType|GetCurrentAddress|GetDlgItem|GetDLLVersion|GetDLLVersionLocal|GetErrorLevel|GetFileTime|GetFileTimeLocal|GetFullPathName|GetFunctionAddress|GetInstDirError|GetLabelAddress|GetTempFileName|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|IfSilent|InitPluginsDir|InstallButtonText|InstallColors|InstallDir|InstallDirRegKey|InstProgressFlags|InstType|InstTypeGetText|InstTypeSetText|Int64Cmp|Int64CmpU|Int64Fmt|IntCmp|IntCmpU|IntFmt|IntOp|IntPtrCmp|IntPtrCmpU|IntPtrOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|PEDllCharacteristics|PESubsysVer|Pop|Push|Quit|ReadEnvStr|ReadINIStr|ReadRegDWORD|ReadRegStr|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|SectionGetFlags|SectionGetInstTypes|SectionGetSize|SectionGetText|SectionIn|SectionSetFlags|SectionSetInstTypes|SectionSetSize|SectionSetText|SendMessage|SetAutoClose|SetBrandingImage|SetCompress|SetCompressor|SetCompressorDictSize|SetCtlColors|SetCurInstType|SetDatablockOptimize|SetDateSave|SetDetailsPrint|SetDetailsView|SetErrorLevel|SetErrors|SetFileAttributes|SetFont|SetOutPath|SetOverwrite|SetRebootFlag|SetRegView|SetShellVarContext|SetSilent|ShowInstDetails|ShowUninstDetails|ShowWindow|SilentInstall|SilentUnInstall|Sleep|SpaceTexts|StrCmp|StrCmpS|StrCpy|StrLen|SubCaption|Unicode|UninstallButtonText|UninstallCaption|UninstallIcon|UninstallSubCaption|UninstallText|UninstPage|UnRegDLL|Var|VIAddVersionKey|VIFileVersion|VIProductVersion|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|WriteRegMultiStr|WriteRegNone|WriteRegStr|WriteUninstaller|XPStyle)\b/, + regex: /^\s*(?:Abort|AddBrandingImage|AddSize|AllowRootDirInstall|AllowSkipFiles|AutoCloseWindow|BGFont|BGGradient|BrandingText|BringToFront|Call|CallInstDLL|Caption|ChangeUI|CheckBitmap|ClearErrors|CompletedText|ComponentText|CopyFiles|CRCCheck|CreateDirectory|CreateFont|CreateShortCut|Delete|DeleteINISec|DeleteINIStr|DeleteRegKey|DeleteRegValue|DetailPrint|DetailsButtonText|DirText|DirVar|DirVerify|EnableWindow|EnumRegKey|EnumRegValue|Exch|Exec|ExecShell|ExecShellWait|ExecWait|ExpandEnvStrings|File|FileBufSize|FileClose|FileErrorText|FileOpen|FileRead|FileReadByte|FileReadUTF16LE|FileReadWord|FileWriteUTF16LE|FileSeek|FileWrite|FileWriteByte|FileWriteWord|FindClose|FindFirst|FindNext|FindWindow|FlushINI|GetCurInstType|GetCurrentAddress|GetDlgItem|GetDLLVersion|GetDLLVersionLocal|GetErrorLevel|GetFileTime|GetFileTimeLocal|GetFullPathName|GetFunctionAddress|GetInstDirError|GetLabelAddress|GetTempFileName|Goto|HideWindow|Icon|IfAbort|IfErrors|IfFileExists|IfRebootFlag|IfSilent|InitPluginsDir|InstallButtonText|InstallColors|InstallDir|InstallDirRegKey|InstProgressFlags|InstType|InstTypeGetText|InstTypeSetText|Int64Cmp|Int64CmpU|Int64Fmt|IntCmp|IntCmpU|IntFmt|IntOp|IntPtrCmp|IntPtrCmpU|IntPtrOp|IsWindow|LangString|LicenseBkColor|LicenseData|LicenseForceSelection|LicenseLangString|LicenseText|LoadAndSetImage|LoadLanguageFile|LockWindow|LogSet|LogText|ManifestDPIAware|ManifestLongPathAware|ManifestMaxVersionTested|ManifestSupportedOS|MessageBox|MiscButtonText|Name|Nop|OutFile|Page|PageCallbacks|PEAddResource|PEDllCharacteristics|PERemoveResource|PESubsysVer|Pop|Push|Quit|ReadEnvStr|ReadINIStr|ReadRegDWORD|ReadRegStr|Reboot|RegDLL|Rename|RequestExecutionLevel|ReserveFile|Return|RMDir|SearchPath|SectionGetFlags|SectionGetInstTypes|SectionGetSize|SectionGetText|SectionIn|SectionSetFlags|SectionSetInstTypes|SectionSetSize|SectionSetText|SendMessage|SetAutoClose|SetBrandingImage|SetCompress|SetCompressor|SetCompressorDictSize|SetCtlColors|SetCurInstType|SetDatablockOptimize|SetDateSave|SetDetailsPrint|SetDetailsView|SetErrorLevel|SetErrors|SetFileAttributes|SetFont|SetOutPath|SetOverwrite|SetRebootFlag|SetRegView|SetShellVarContext|SetSilent|ShowInstDetails|ShowUninstDetails|ShowWindow|SilentInstall|SilentUnInstall|Sleep|SpaceTexts|StrCmp|StrCmpS|StrCpy|StrLen|SubCaption|Unicode|UninstallButtonText|UninstallCaption|UninstallIcon|UninstallSubCaption|UninstallText|UninstPage|UnRegDLL|Var|VIAddVersionKey|VIFileVersion|VIProductVersion|WindowIcon|WriteINIStr|WriteRegBin|WriteRegDWORD|WriteRegExpandStr|WriteRegMultiStr|WriteRegNone|WriteRegStr|WriteUninstaller|XPStyle)\b/, caseInsensitive: true }, { token: "keyword.control.nsis", diff --git a/htdocs/includes/ace/src/mode-nunjucks.js b/htdocs/includes/ace/src/mode-nunjucks.js new file mode 100644 index 00000000000..57f1e9f32bb --- /dev/null +++ b/htdocs/includes/ace/src/mode-nunjucks.js @@ -0,0 +1,2695 @@ +define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var DocCommentHighlightRules = function() { + this.$rules = { + "start" : [ { + token : "comment.doc.tag", + regex : "@[\\w\\d_]+" // TODO: fix email addresses + }, + DocCommentHighlightRules.getTagRule(), + { + defaultToken : "comment.doc", + caseInsensitive: true + }] + }; +}; + +oop.inherits(DocCommentHighlightRules, TextHighlightRules); + +DocCommentHighlightRules.getTagRule = function(start) { + return { + token : "comment.doc.tag.storage.type", + regex : "\\b(?:TODO|FIXME|XXX|HACK)\\b" + }; +}; + +DocCommentHighlightRules.getStartRule = function(start) { + return { + token : "comment.doc", // doc comment + regex : "\\/\\*(?=\\*)", + next : start + }; +}; + +DocCommentHighlightRules.getEndRule = function (start) { + return { + token : "comment.doc", // closing comment + regex : "\\*\\/", + next : start + }; +}; + + +exports.DocCommentHighlightRules = DocCommentHighlightRules; + +}); + +define("ace/mode/javascript_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules; +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; +var identifierRe = "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*"; + +var JavaScriptHighlightRules = function(options) { + var keywordMapper = this.createKeywordMapper({ + "variable.language": + "Array|Boolean|Date|Function|Iterator|Number|Object|RegExp|String|Proxy|" + // Constructors + "Namespace|QName|XML|XMLList|" + // E4X + "ArrayBuffer|Float32Array|Float64Array|Int16Array|Int32Array|Int8Array|" + + "Uint16Array|Uint32Array|Uint8Array|Uint8ClampedArray|" + + "Error|EvalError|InternalError|RangeError|ReferenceError|StopIteration|" + // Errors + "SyntaxError|TypeError|URIError|" + + "decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|" + // Non-constructor functions + "isNaN|parseFloat|parseInt|" + + "JSON|Math|" + // Other + "this|arguments|prototype|window|document" , // Pseudo + "keyword": + "const|yield|import|get|set|async|await|" + + "break|case|catch|continue|default|delete|do|else|finally|for|function|" + + "if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|" + + "__parent__|__count__|escape|unescape|with|__proto__|" + + "class|enum|extends|super|export|implements|private|public|interface|package|protected|static", + "storage.type": + "const|let|var|function", + "constant.language": + "null|Infinity|NaN|undefined", + "support.function": + "alert", + "constant.language.boolean": "true|false" + }, "identifier"); + var kwBeforeRe = "case|do|else|finally|in|instanceof|return|throw|try|typeof|yield|void"; + + var escapedRe = "\\\\(?:x[0-9a-fA-F]{2}|" + // hex + "u[0-9a-fA-F]{4}|" + // unicode + "u{[0-9a-fA-F]{1,6}}|" + // es6 unicode + "[0-2][0-7]{0,2}|" + // oct + "3[0-7][0-7]?|" + // oct + "[4-7][0-7]?|" + //oct + ".)"; + + this.$rules = { + "no_regex" : [ + DocCommentHighlightRules.getStartRule("doc-start"), + comments("no_regex"), + { + token : "string", + regex : "'(?=.)", + next : "qstring" + }, { + token : "string", + regex : '"(?=.)', + next : "qqstring" + }, { + token : "constant.numeric", // hexadecimal, octal and binary + regex : /0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/ + }, { + token : "constant.numeric", // decimal integers and floats + regex : /(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/ + }, { + token : [ + "storage.type", "punctuation.operator", "support.function", + "punctuation.operator", "entity.name.function", "text","keyword.operator" + ], + regex : "(" + identifierRe + ")(\\.)(prototype)(\\.)(" + identifierRe +")(\\s*)(=)", + next: "function_arguments" + }, { + token : [ + "storage.type", "punctuation.operator", "entity.name.function", "text", + "keyword.operator", "text", "storage.type", "text", "paren.lparen" + ], + regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s*)(\\()", + next: "function_arguments" + }, { + token : [ + "entity.name.function", "text", "keyword.operator", "text", "storage.type", + "text", "paren.lparen" + ], + regex : "(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s*)(\\()", + next: "function_arguments" + }, { + token : [ + "storage.type", "punctuation.operator", "entity.name.function", "text", + "keyword.operator", "text", + "storage.type", "text", "entity.name.function", "text", "paren.lparen" + ], + regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(\\s+)(\\w+)(\\s*)(\\()", + next: "function_arguments" + }, { + token : [ + "storage.type", "text", "entity.name.function", "text", "paren.lparen" + ], + regex : "(function)(\\s+)(" + identifierRe + ")(\\s*)(\\()", + next: "function_arguments" + }, { + token : [ + "entity.name.function", "text", "punctuation.operator", + "text", "storage.type", "text", "paren.lparen" + ], + regex : "(" + identifierRe + ")(\\s*)(:)(\\s*)(function)(\\s*)(\\()", + next: "function_arguments" + }, { + token : [ + "text", "text", "storage.type", "text", "paren.lparen" + ], + regex : "(:)(\\s*)(function)(\\s*)(\\()", + next: "function_arguments" + }, { + token : "keyword", + regex : "from(?=\\s*('|\"))" + }, { + token : "keyword", + regex : "(?:" + kwBeforeRe + ")\\b", + next : "start" + }, { + token : ["support.constant"], + regex : /that\b/ + }, { + token : ["storage.type", "punctuation.operator", "support.function.firebug"], + regex : /(console)(\.)(warn|info|log|error|time|trace|timeEnd|assert)\b/ + }, { + token : keywordMapper, + regex : identifierRe + }, { + token : "punctuation.operator", + regex : /[.](?![.])/, + next : "property" + }, { + token : "storage.type", + regex : /=>/, + next : "start" + }, { + token : "keyword.operator", + regex : /--|\+\+|\.{3}|===|==|=|!=|!==|<+=?|>+=?|!|&&|\|\||\?:|[!$%&*+\-~\/^]=?/, + next : "start" + }, { + token : "punctuation.operator", + regex : /[?:,;.]/, + next : "start" + }, { + token : "paren.lparen", + regex : /[\[({]/, + next : "start" + }, { + token : "paren.rparen", + regex : /[\])}]/ + }, { + token: "comment", + regex: /^#!.*$/ + } + ], + property: [{ + token : "text", + regex : "\\s+" + }, { + token : [ + "storage.type", "punctuation.operator", "entity.name.function", "text", + "keyword.operator", "text", + "storage.type", "text", "entity.name.function", "text", "paren.lparen" + ], + regex : "(" + identifierRe + ")(\\.)(" + identifierRe +")(\\s*)(=)(\\s*)(function)(?:(\\s+)(\\w+))?(\\s*)(\\()", + next: "function_arguments" + }, { + token : "punctuation.operator", + regex : /[.](?![.])/ + }, { + token : "support.function", + regex : /(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/ + }, { + token : "support.function.dom", + regex : /(s(?:ub(?:stringData|mit)|plitText|e(?:t(?:NamedItem|Attribute(?:Node)?)|lect))|has(?:ChildNodes|Feature)|namedItem|c(?:l(?:ick|o(?:se|neNode))|reate(?:C(?:omment|DATASection|aption)|T(?:Head|extNode|Foot)|DocumentFragment|ProcessingInstruction|E(?:ntityReference|lement)|Attribute))|tabIndex|i(?:nsert(?:Row|Before|Cell|Data)|tem)|open|delete(?:Row|C(?:ell|aption)|T(?:Head|Foot)|Data)|focus|write(?:ln)?|a(?:dd|ppend(?:Child|Data))|re(?:set|place(?:Child|Data)|move(?:NamedItem|Child|Attribute(?:Node)?)?)|get(?:NamedItem|Element(?:sBy(?:Name|TagName|ClassName)|ById)|Attribute(?:Node)?)|blur)\b(?=\()/ + }, { + token : "support.constant", + regex : /(s(?:ystemLanguage|cr(?:ipts|ollbars|een(?:X|Y|Top|Left))|t(?:yle(?:Sheets)?|atus(?:Text|bar)?)|ibling(?:Below|Above)|ource|uffixes|e(?:curity(?:Policy)?|l(?:ection|f)))|h(?:istory|ost(?:name)?|as(?:h|Focus))|y|X(?:MLDocument|SLDocument)|n(?:ext|ame(?:space(?:s|URI)|Prop))|M(?:IN_VALUE|AX_VALUE)|c(?:haracterSet|o(?:n(?:structor|trollers)|okieEnabled|lorDepth|mp(?:onents|lete))|urrent|puClass|l(?:i(?:p(?:boardData)?|entInformation)|osed|asses)|alle(?:e|r)|rypto)|t(?:o(?:olbar|p)|ext(?:Transform|Indent|Decoration|Align)|ags)|SQRT(?:1_2|2)|i(?:n(?:ner(?:Height|Width)|put)|ds|gnoreCase)|zIndex|o(?:scpu|n(?:readystatechange|Line)|uter(?:Height|Width)|p(?:sProfile|ener)|ffscreenBuffering)|NEGATIVE_INFINITY|d(?:i(?:splay|alog(?:Height|Top|Width|Left|Arguments)|rectories)|e(?:scription|fault(?:Status|Ch(?:ecked|arset)|View)))|u(?:ser(?:Profile|Language|Agent)|n(?:iqueID|defined)|pdateInterval)|_content|p(?:ixelDepth|ort|ersonalbar|kcs11|l(?:ugins|atform)|a(?:thname|dding(?:Right|Bottom|Top|Left)|rent(?:Window|Layer)?|ge(?:X(?:Offset)?|Y(?:Offset)?))|r(?:o(?:to(?:col|type)|duct(?:Sub)?|mpter)|e(?:vious|fix)))|e(?:n(?:coding|abledPlugin)|x(?:ternal|pando)|mbeds)|v(?:isibility|endor(?:Sub)?|Linkcolor)|URLUnencoded|P(?:I|OSITIVE_INFINITY)|f(?:ilename|o(?:nt(?:Size|Family|Weight)|rmName)|rame(?:s|Element)|gColor)|E|whiteSpace|l(?:i(?:stStyleType|n(?:eHeight|kColor))|o(?:ca(?:tion(?:bar)?|lName)|wsrc)|e(?:ngth|ft(?:Context)?)|a(?:st(?:M(?:odified|atch)|Index|Paren)|yer(?:s|X)|nguage))|a(?:pp(?:MinorVersion|Name|Co(?:deName|re)|Version)|vail(?:Height|Top|Width|Left)|ll|r(?:ity|guments)|Linkcolor|bove)|r(?:ight(?:Context)?|e(?:sponse(?:XML|Text)|adyState))|global|x|m(?:imeTypes|ultiline|enubar|argin(?:Right|Bottom|Top|Left))|L(?:N(?:10|2)|OG(?:10E|2E))|b(?:o(?:ttom|rder(?:Width|RightWidth|BottomWidth|Style|Color|TopWidth|LeftWidth))|ufferDepth|elow|ackground(?:Color|Image)))\b/ + }, { + token : "identifier", + regex : identifierRe + }, { + regex: "", + token: "empty", + next: "no_regex" + } + ], + "start": [ + DocCommentHighlightRules.getStartRule("doc-start"), + comments("start"), + { + token: "string.regexp", + regex: "\\/", + next: "regex" + }, { + token : "text", + regex : "\\s+|^$", + next : "start" + }, { + token: "empty", + regex: "", + next: "no_regex" + } + ], + "regex": [ + { + token: "regexp.keyword.operator", + regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" + }, { + token: "string.regexp", + regex: "/[sxngimy]*", + next: "no_regex" + }, { + token : "invalid", + regex: /\{\d+\b,?\d*\}[+*]|[+*$^?][+*]|[$^][?]|\?{3,}/ + }, { + token : "constant.language.escape", + regex: /\(\?[:=!]|\)|\{\d+\b,?\d*\}|[+*]\?|[()$^+*?.]/ + }, { + token : "constant.language.delimiter", + regex: /\|/ + }, { + token: "constant.language.escape", + regex: /\[\^?/, + next: "regex_character_class" + }, { + token: "empty", + regex: "$", + next: "no_regex" + }, { + defaultToken: "string.regexp" + } + ], + "regex_character_class": [ + { + token: "regexp.charclass.keyword.operator", + regex: "\\\\(?:u[\\da-fA-F]{4}|x[\\da-fA-F]{2}|.)" + }, { + token: "constant.language.escape", + regex: "]", + next: "regex" + }, { + token: "constant.language.escape", + regex: "-" + }, { + token: "empty", + regex: "$", + next: "no_regex" + }, { + defaultToken: "string.regexp.charachterclass" + } + ], + "function_arguments": [ + { + token: "variable.parameter", + regex: identifierRe + }, { + token: "punctuation.operator", + regex: "[, ]+" + }, { + token: "punctuation.operator", + regex: "$" + }, { + token: "empty", + regex: "", + next: "no_regex" + } + ], + "qqstring" : [ + { + token : "constant.language.escape", + regex : escapedRe + }, { + token : "string", + regex : "\\\\$", + consumeLineEnd : true + }, { + token : "string", + regex : '"|$', + next : "no_regex" + }, { + defaultToken: "string" + } + ], + "qstring" : [ + { + token : "constant.language.escape", + regex : escapedRe + }, { + token : "string", + regex : "\\\\$", + consumeLineEnd : true + }, { + token : "string", + regex : "'|$", + next : "no_regex" + }, { + defaultToken: "string" + } + ] + }; + + + if (!options || !options.noES6) { + this.$rules.no_regex.unshift({ + regex: "[{}]", onMatch: function(val, state, stack) { + this.next = val == "{" ? this.nextState : ""; + if (val == "{" && stack.length) { + stack.unshift("start", state); + } + else if (val == "}" && stack.length) { + stack.shift(); + this.next = stack.shift(); + if (this.next.indexOf("string") != -1 || this.next.indexOf("jsx") != -1) + return "paren.quasi.end"; + } + return val == "{" ? "paren.lparen" : "paren.rparen"; + }, + nextState: "start" + }, { + token : "string.quasi.start", + regex : /`/, + push : [{ + token : "constant.language.escape", + regex : escapedRe + }, { + token : "paren.quasi.start", + regex : /\${/, + push : "start" + }, { + token : "string.quasi.end", + regex : /`/, + next : "pop" + }, { + defaultToken: "string.quasi" + }] + }); + + if (!options || options.jsx != false) + JSX.call(this); + } + + this.embedRules(DocCommentHighlightRules, "doc-", + [ DocCommentHighlightRules.getEndRule("no_regex") ]); + + this.normalizeRules(); +}; + +oop.inherits(JavaScriptHighlightRules, TextHighlightRules); + +function JSX() { + var tagRegex = identifierRe.replace("\\d", "\\d\\-"); + var jsxTag = { + onMatch : function(val, state, stack) { + var offset = val.charAt(1) == "/" ? 2 : 1; + if (offset == 1) { + if (state != this.nextState) + stack.unshift(this.next, this.nextState, 0); + else + stack.unshift(this.next); + stack[2]++; + } else if (offset == 2) { + if (state == this.nextState) { + stack[1]--; + if (!stack[1] || stack[1] < 0) { + stack.shift(); + stack.shift(); + } + } + } + return [{ + type: "meta.tag.punctuation." + (offset == 1 ? "" : "end-") + "tag-open.xml", + value: val.slice(0, offset) + }, { + type: "meta.tag.tag-name.xml", + value: val.substr(offset) + }]; + }, + regex : "", + onMatch : function(value, currentState, stack) { + if (currentState == stack[0]) + stack.shift(); + if (value.length == 2) { + if (stack[0] == this.nextState) + stack[1]--; + if (!stack[1] || stack[1] < 0) { + stack.splice(0, 2); + } + } + this.next = stack[0] || "start"; + return [{type: this.token, value: value}]; + }, + nextState: "jsx" + }, + jsxJsRule, + comments("jsxAttributes"), + { + token : "entity.other.attribute-name.xml", + regex : tagRegex + }, { + token : "keyword.operator.attribute-equals.xml", + regex : "=" + }, { + token : "text.tag-whitespace.xml", + regex : "\\s+" + }, { + token : "string.attribute-value.xml", + regex : "'", + stateName : "jsx_attr_q", + push : [ + {token : "string.attribute-value.xml", regex: "'", next: "pop"}, + {include : "reference"}, + {defaultToken : "string.attribute-value.xml"} + ] + }, { + token : "string.attribute-value.xml", + regex : '"', + stateName : "jsx_attr_qq", + push : [ + {token : "string.attribute-value.xml", regex: '"', next: "pop"}, + {include : "reference"}, + {defaultToken : "string.attribute-value.xml"} + ] + }, + jsxTag + ]; + this.$rules.reference = [{ + token : "constant.language.escape.reference.xml", + regex : "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)" + }]; +} + +function comments(next) { + return [ + { + token : "comment", // multi line comment + regex : /\/\*/, + next: [ + DocCommentHighlightRules.getTagRule(), + {token : "comment", regex : "\\*\\/", next : next || "pop"}, + {defaultToken : "comment", caseInsensitive: true} + ] + }, { + token : "comment", + regex : "\\/\\/", + next: [ + DocCommentHighlightRules.getTagRule(), + {token : "comment", regex : "$|^", next : next || "pop"}, + {defaultToken : "comment", caseInsensitive: true} + ] + } + ]; +} +exports.JavaScriptHighlightRules = JavaScriptHighlightRules; +}); + +define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) { +"use strict"; + +var Range = require("../range").Range; + +var MatchingBraceOutdent = function() {}; + +(function() { + + this.checkOutdent = function(line, input) { + if (! /^\s+$/.test(line)) + return false; + + return /^\s*\}/.test(input); + }; + + this.autoOutdent = function(doc, row) { + var line = doc.getLine(row); + var match = line.match(/^(\s*\})/); + + if (!match) return 0; + + var column = match[1].length; + var openBracePos = doc.findMatchingBracket({row: row, column: column}); + + if (!openBracePos || openBracePos.row == row) return 0; + + var indent = this.$getIndent(doc.getLine(openBracePos.row)); + doc.replace(new Range(row, 0, row, column-1), indent); + }; + + this.$getIndent = function(line) { + return line.match(/^\s*/)[0]; + }; + +}).call(MatchingBraceOutdent.prototype); + +exports.MatchingBraceOutdent = MatchingBraceOutdent; +}); + +define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Range = require("../../range").Range; +var BaseFoldMode = require("./fold_mode").FoldMode; + +var FoldMode = exports.FoldMode = function(commentRegex) { + if (commentRegex) { + this.foldingStartMarker = new RegExp( + this.foldingStartMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.start) + ); + this.foldingStopMarker = new RegExp( + this.foldingStopMarker.source.replace(/\|[^|]*?$/, "|" + commentRegex.end) + ); + } +}; +oop.inherits(FoldMode, BaseFoldMode); + +(function() { + + this.foldingStartMarker = /([\{\[\(])[^\}\]\)]*$|^\s*(\/\*)/; + this.foldingStopMarker = /^[^\[\{\(]*([\}\]\)])|^[\s\*]*(\*\/)/; + this.singleLineBlockCommentRe= /^\s*(\/\*).*\*\/\s*$/; + this.tripleStarBlockCommentRe = /^\s*(\/\*\*\*).*\*\/\s*$/; + this.startRegionRe = /^\s*(\/\*|\/\/)#?region\b/; + this._getFoldWidgetBase = this.getFoldWidget; + this.getFoldWidget = function(session, foldStyle, row) { + var line = session.getLine(row); + + if (this.singleLineBlockCommentRe.test(line)) { + if (!this.startRegionRe.test(line) && !this.tripleStarBlockCommentRe.test(line)) + return ""; + } + + var fw = this._getFoldWidgetBase(session, foldStyle, row); + + if (!fw && this.startRegionRe.test(line)) + return "start"; // lineCommentRegionStart + + return fw; + }; + + this.getFoldWidgetRange = function(session, foldStyle, row, forceMultiline) { + var line = session.getLine(row); + + if (this.startRegionRe.test(line)) + return this.getCommentRegionBlock(session, line, row); + + var match = line.match(this.foldingStartMarker); + if (match) { + var i = match.index; + + if (match[1]) + return this.openingBracketBlock(session, match[1], row, i); + + var range = session.getCommentFoldRange(row, i + match[0].length, 1); + + if (range && !range.isMultiLine()) { + if (forceMultiline) { + range = this.getSectionRange(session, row); + } else if (foldStyle != "all") + range = null; + } + + return range; + } + + if (foldStyle === "markbegin") + return; + + var match = line.match(this.foldingStopMarker); + if (match) { + var i = match.index + match[0].length; + + if (match[1]) + return this.closingBracketBlock(session, match[1], row, i); + + return session.getCommentFoldRange(row, i, -1); + } + }; + + this.getSectionRange = function(session, row) { + var line = session.getLine(row); + var startIndent = line.search(/\S/); + var startRow = row; + var startColumn = line.length; + row = row + 1; + var endRow = row; + var maxRow = session.getLength(); + while (++row < maxRow) { + line = session.getLine(row); + var indent = line.search(/\S/); + if (indent === -1) + continue; + if (startIndent > indent) + break; + var subRange = this.getFoldWidgetRange(session, "all", row); + + if (subRange) { + if (subRange.start.row <= startRow) { + break; + } else if (subRange.isMultiLine()) { + row = subRange.end.row; + } else if (startIndent == indent) { + break; + } + } + endRow = row; + } + + return new Range(startRow, startColumn, endRow, session.getLine(endRow).length); + }; + this.getCommentRegionBlock = function(session, line, row) { + var startColumn = line.search(/\s*$/); + var maxRow = session.getLength(); + var startRow = row; + + var re = /^\s*(?:\/\*|\/\/|--)#?(end)?region\b/; + var depth = 1; + while (++row < maxRow) { + line = session.getLine(row); + var m = re.exec(line); + if (!m) continue; + if (m[1]) depth--; + else depth++; + + if (!depth) break; + } + + var endRow = row; + if (endRow > startRow) { + return new Range(startRow, startColumn, endRow, line.length); + } + }; + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/javascript",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/javascript_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/behaviour/cstyle","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var WorkerClient = require("../worker/worker_client").WorkerClient; +var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour; +var CStyleFoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = JavaScriptHighlightRules; + + this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CstyleBehaviour(); + this.foldingRules = new CStyleFoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + + this.lineCommentStart = "//"; + this.blockComment = {start: "/*", end: "*/"}; + this.$quotes = {'"': '"', "'": "'", "`": "`"}; + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + + var tokenizedLine = this.getTokenizer().getLineTokens(line, state); + var tokens = tokenizedLine.tokens; + var endState = tokenizedLine.state; + + if (tokens.length && tokens[tokens.length-1].type == "comment") { + return indent; + } + + if (state == "start" || state == "no_regex") { + var match = line.match(/^.*(?:\bcase\b.*:|[\{\(\[])\s*$/); + if (match) { + indent += tab; + } + } else if (state == "doc-start") { + if (endState == "start" || endState == "no_regex") { + return ""; + } + var match = line.match(/^\s*(\/?)\*/); + if (match) { + if (match[1]) { + indent += " "; + } + indent += "* "; + } + } + + return indent; + }; + + this.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); + }; + + this.autoOutdent = function(state, doc, row) { + this.$outdent.autoOutdent(doc, row); + }; + + this.createWorker = function(session) { + var worker = new WorkerClient(["ace"], "ace/mode/javascript_worker", "JavaScriptWorker"); + worker.attachToDocument(session.getDocument()); + + worker.on("annotate", function(results) { + session.setAnnotations(results.data); + }); + + worker.on("terminate", function() { + session.clearAnnotations(); + }); + + return worker; + }; + + this.$id = "ace/mode/javascript"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); + +define("ace/mode/css_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var lang = require("../lib/lang"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; +var supportType = exports.supportType = "align-content|align-items|align-self|all|animation|animation-delay|animation-direction|animation-duration|animation-fill-mode|animation-iteration-count|animation-name|animation-play-state|animation-timing-function|backface-visibility|background|background-attachment|background-blend-mode|background-clip|background-color|background-image|background-origin|background-position|background-repeat|background-size|border|border-bottom|border-bottom-color|border-bottom-left-radius|border-bottom-right-radius|border-bottom-style|border-bottom-width|border-collapse|border-color|border-image|border-image-outset|border-image-repeat|border-image-slice|border-image-source|border-image-width|border-left|border-left-color|border-left-style|border-left-width|border-radius|border-right|border-right-color|border-right-style|border-right-width|border-spacing|border-style|border-top|border-top-color|border-top-left-radius|border-top-right-radius|border-top-style|border-top-width|border-width|bottom|box-shadow|box-sizing|caption-side|clear|clip|color|column-count|column-fill|column-gap|column-rule|column-rule-color|column-rule-style|column-rule-width|column-span|column-width|columns|content|counter-increment|counter-reset|cursor|direction|display|empty-cells|filter|flex|flex-basis|flex-direction|flex-flow|flex-grow|flex-shrink|flex-wrap|float|font|font-family|font-size|font-size-adjust|font-stretch|font-style|font-variant|font-weight|hanging-punctuation|height|justify-content|left|letter-spacing|line-height|list-style|list-style-image|list-style-position|list-style-type|margin|margin-bottom|margin-left|margin-right|margin-top|max-height|max-width|max-zoom|min-height|min-width|min-zoom|nav-down|nav-index|nav-left|nav-right|nav-up|opacity|order|outline|outline-color|outline-offset|outline-style|outline-width|overflow|overflow-x|overflow-y|padding|padding-bottom|padding-left|padding-right|padding-top|page-break-after|page-break-before|page-break-inside|perspective|perspective-origin|position|quotes|resize|right|tab-size|table-layout|text-align|text-align-last|text-decoration|text-decoration-color|text-decoration-line|text-decoration-style|text-indent|text-justify|text-overflow|text-shadow|text-transform|top|transform|transform-origin|transform-style|transition|transition-delay|transition-duration|transition-property|transition-timing-function|unicode-bidi|user-select|user-zoom|vertical-align|visibility|white-space|width|word-break|word-spacing|word-wrap|z-index"; +var supportFunction = exports.supportFunction = "rgb|rgba|url|attr|counter|counters"; +var supportConstant = exports.supportConstant = "absolute|after-edge|after|all-scroll|all|alphabetic|always|antialiased|armenian|auto|avoid-column|avoid-page|avoid|balance|baseline|before-edge|before|below|bidi-override|block-line-height|block|bold|bolder|border-box|both|bottom|box|break-all|break-word|capitalize|caps-height|caption|center|central|char|circle|cjk-ideographic|clone|close-quote|col-resize|collapse|column|consider-shifts|contain|content-box|cover|crosshair|cubic-bezier|dashed|decimal-leading-zero|decimal|default|disabled|disc|disregard-shifts|distribute-all-lines|distribute-letter|distribute-space|distribute|dotted|double|e-resize|ease-in|ease-in-out|ease-out|ease|ellipsis|end|exclude-ruby|fill|fixed|georgian|glyphs|grid-height|groove|hand|hanging|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|icon|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space|ideographic|inactive|include-ruby|inherit|initial|inline-block|inline-box|inline-line-height|inline-table|inline|inset|inside|inter-ideograph|inter-word|invert|italic|justify|katakana-iroha|katakana|keep-all|last|left|lighter|line-edge|line-through|line|linear|list-item|local|loose|lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|mathematical|max-height|max-size|medium|menu|message-box|middle|move|n-resize|ne-resize|newspaper|no-change|no-close-quote|no-drop|no-open-quote|no-repeat|none|normal|not-allowed|nowrap|nw-resize|oblique|open-quote|outset|outside|overline|padding-box|page|pointer|pre-line|pre-wrap|pre|preserve-3d|progress|relative|repeat-x|repeat-y|repeat|replaced|reset-size|ridge|right|round|row-resize|rtl|s-resize|scroll|se-resize|separate|slice|small-caps|small-caption|solid|space|square|start|static|status-bar|step-end|step-start|steps|stretch|strict|sub|super|sw-resize|table-caption|table-cell|table-column-group|table-column|table-footer-group|table-header-group|table-row-group|table-row|table|tb-rl|text-after-edge|text-before-edge|text-bottom|text-size|text-top|text|thick|thin|transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|use-script|vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|z-index|zero|zoom"; +var supportConstantColor = exports.supportConstantColor = "aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen"; +var supportConstantFonts = exports.supportConstantFonts = "arial|century|comic|courier|cursive|fantasy|garamond|georgia|helvetica|impact|lucida|symbol|system|tahoma|times|trebuchet|utopia|verdana|webdings|sans-serif|serif|monospace"; + +var numRe = exports.numRe = "\\-?(?:(?:[0-9]+(?:\\.[0-9]+)?)|(?:\\.[0-9]+))"; +var pseudoElements = exports.pseudoElements = "(\\:+)\\b(after|before|first-letter|first-line|moz-selection|selection)\\b"; +var pseudoClasses = exports.pseudoClasses = "(:)\\b(active|checked|disabled|empty|enabled|first-child|first-of-type|focus|hover|indeterminate|invalid|last-child|last-of-type|link|not|nth-child|nth-last-child|nth-last-of-type|nth-of-type|only-child|only-of-type|required|root|target|valid|visited)\\b"; + +var CssHighlightRules = function() { + + var keywordMapper = this.createKeywordMapper({ + "support.function": supportFunction, + "support.constant": supportConstant, + "support.type": supportType, + "support.constant.color": supportConstantColor, + "support.constant.fonts": supportConstantFonts + }, "text", true); + + this.$rules = { + "start" : [{ + include : ["strings", "url", "comments"] + }, { + token: "paren.lparen", + regex: "\\{", + next: "ruleset" + }, { + token: "paren.rparen", + regex: "\\}" + }, { + token: "string", + regex: "@(?!viewport)", + next: "media" + }, { + token: "keyword", + regex: "#[a-z0-9-_]+" + }, { + token: "keyword", + regex: "%" + }, { + token: "variable", + regex: "\\.[a-z0-9-_]+" + }, { + token: "string", + regex: ":[a-z0-9-_]+" + }, { + token : "constant.numeric", + regex : numRe + }, { + token: "constant", + regex: "[a-z0-9-_]+" + }, { + caseInsensitive: true + }], + + "media": [{ + include : ["strings", "url", "comments"] + }, { + token: "paren.lparen", + regex: "\\{", + next: "start" + }, { + token: "paren.rparen", + regex: "\\}", + next: "start" + }, { + token: "string", + regex: ";", + next: "start" + }, { + token: "keyword", + regex: "(?:media|supports|document|charset|import|namespace|media|supports|document" + + "|page|font|keyframes|viewport|counter-style|font-feature-values" + + "|swash|ornaments|annotation|stylistic|styleset|character-variant)" + }], + + "comments" : [{ + token: "comment", // multi line comment + regex: "\\/\\*", + push: [{ + token : "comment", + regex : "\\*\\/", + next : "pop" + }, { + defaultToken : "comment" + }] + }], + + "ruleset" : [{ + regex : "-(webkit|ms|moz|o)-", + token : "text" + }, { + token : "punctuation.operator", + regex : "[:;]" + }, { + token : "paren.rparen", + regex : "\\}", + next : "start" + }, { + include : ["strings", "url", "comments"] + }, { + token : ["constant.numeric", "keyword"], + regex : "(" + numRe + ")(ch|cm|deg|em|ex|fr|gd|grad|Hz|in|kHz|mm|ms|pc|pt|px|rad|rem|s|turn|vh|vmax|vmin|vm|vw|%)" + }, { + token : "constant.numeric", + regex : numRe + }, { + token : "constant.numeric", // hex6 color + regex : "#[a-f0-9]{6}" + }, { + token : "constant.numeric", // hex3 color + regex : "#[a-f0-9]{3}" + }, { + token : ["punctuation", "entity.other.attribute-name.pseudo-element.css"], + regex : pseudoElements + }, { + token : ["punctuation", "entity.other.attribute-name.pseudo-class.css"], + regex : pseudoClasses + }, { + include: "url" + }, { + token : keywordMapper, + regex : "\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*" + }, { + caseInsensitive: true + }], + + url: [{ + token : "support.function", + regex : "(?:url(:?-prefix)?|domain|regexp)\\(", + push: [{ + token : "support.function", + regex : "\\)", + next : "pop" + }, { + defaultToken: "string" + }] + }], + + strings: [{ + token : "string.start", + regex : "'", + push : [{ + token : "string.end", + regex : "'|$", + next: "pop" + }, { + include : "escapes" + }, { + token : "constant.language.escape", + regex : /\\$/, + consumeLineEnd: true + }, { + defaultToken: "string" + }] + }, { + token : "string.start", + regex : '"', + push : [{ + token : "string.end", + regex : '"|$', + next: "pop" + }, { + include : "escapes" + }, { + token : "constant.language.escape", + regex : /\\$/, + consumeLineEnd: true + }, { + defaultToken: "string" + }] + }], + escapes: [{ + token : "constant.language.escape", + regex : /\\([a-fA-F\d]{1,6}|[^a-fA-F\d])/ + }] + + }; + + this.normalizeRules(); +}; + +oop.inherits(CssHighlightRules, TextHighlightRules); + +exports.CssHighlightRules = CssHighlightRules; + +}); + +define("ace/mode/css_completions",["require","exports","module"], function(require, exports, module) { +"use strict"; + +var propertyMap = { + "background": {"#$0": 1}, + "background-color": {"#$0": 1, "transparent": 1, "fixed": 1}, + "background-image": {"url('/$0')": 1}, + "background-repeat": {"repeat": 1, "repeat-x": 1, "repeat-y": 1, "no-repeat": 1, "inherit": 1}, + "background-position": {"bottom":2, "center":2, "left":2, "right":2, "top":2, "inherit":2}, + "background-attachment": {"scroll": 1, "fixed": 1}, + "background-size": {"cover": 1, "contain": 1}, + "background-clip": {"border-box": 1, "padding-box": 1, "content-box": 1}, + "background-origin": {"border-box": 1, "padding-box": 1, "content-box": 1}, + "border": {"solid $0": 1, "dashed $0": 1, "dotted $0": 1, "#$0": 1}, + "border-color": {"#$0": 1}, + "border-style": {"solid":2, "dashed":2, "dotted":2, "double":2, "groove":2, "hidden":2, "inherit":2, "inset":2, "none":2, "outset":2, "ridged":2}, + "border-collapse": {"collapse": 1, "separate": 1}, + "bottom": {"px": 1, "em": 1, "%": 1}, + "clear": {"left": 1, "right": 1, "both": 1, "none": 1}, + "color": {"#$0": 1, "rgb(#$00,0,0)": 1}, + "cursor": {"default": 1, "pointer": 1, "move": 1, "text": 1, "wait": 1, "help": 1, "progress": 1, "n-resize": 1, "ne-resize": 1, "e-resize": 1, "se-resize": 1, "s-resize": 1, "sw-resize": 1, "w-resize": 1, "nw-resize": 1}, + "display": {"none": 1, "block": 1, "inline": 1, "inline-block": 1, "table-cell": 1}, + "empty-cells": {"show": 1, "hide": 1}, + "float": {"left": 1, "right": 1, "none": 1}, + "font-family": {"Arial":2,"Comic Sans MS":2,"Consolas":2,"Courier New":2,"Courier":2,"Georgia":2,"Monospace":2,"Sans-Serif":2, "Segoe UI":2,"Tahoma":2,"Times New Roman":2,"Trebuchet MS":2,"Verdana": 1}, + "font-size": {"px": 1, "em": 1, "%": 1}, + "font-weight": {"bold": 1, "normal": 1}, + "font-style": {"italic": 1, "normal": 1}, + "font-variant": {"normal": 1, "small-caps": 1}, + "height": {"px": 1, "em": 1, "%": 1}, + "left": {"px": 1, "em": 1, "%": 1}, + "letter-spacing": {"normal": 1}, + "line-height": {"normal": 1}, + "list-style-type": {"none": 1, "disc": 1, "circle": 1, "square": 1, "decimal": 1, "decimal-leading-zero": 1, "lower-roman": 1, "upper-roman": 1, "lower-greek": 1, "lower-latin": 1, "upper-latin": 1, "georgian": 1, "lower-alpha": 1, "upper-alpha": 1}, + "margin": {"px": 1, "em": 1, "%": 1}, + "margin-right": {"px": 1, "em": 1, "%": 1}, + "margin-left": {"px": 1, "em": 1, "%": 1}, + "margin-top": {"px": 1, "em": 1, "%": 1}, + "margin-bottom": {"px": 1, "em": 1, "%": 1}, + "max-height": {"px": 1, "em": 1, "%": 1}, + "max-width": {"px": 1, "em": 1, "%": 1}, + "min-height": {"px": 1, "em": 1, "%": 1}, + "min-width": {"px": 1, "em": 1, "%": 1}, + "overflow": {"hidden": 1, "visible": 1, "auto": 1, "scroll": 1}, + "overflow-x": {"hidden": 1, "visible": 1, "auto": 1, "scroll": 1}, + "overflow-y": {"hidden": 1, "visible": 1, "auto": 1, "scroll": 1}, + "padding": {"px": 1, "em": 1, "%": 1}, + "padding-top": {"px": 1, "em": 1, "%": 1}, + "padding-right": {"px": 1, "em": 1, "%": 1}, + "padding-bottom": {"px": 1, "em": 1, "%": 1}, + "padding-left": {"px": 1, "em": 1, "%": 1}, + "page-break-after": {"auto": 1, "always": 1, "avoid": 1, "left": 1, "right": 1}, + "page-break-before": {"auto": 1, "always": 1, "avoid": 1, "left": 1, "right": 1}, + "position": {"absolute": 1, "relative": 1, "fixed": 1, "static": 1}, + "right": {"px": 1, "em": 1, "%": 1}, + "table-layout": {"fixed": 1, "auto": 1}, + "text-decoration": {"none": 1, "underline": 1, "line-through": 1, "blink": 1}, + "text-align": {"left": 1, "right": 1, "center": 1, "justify": 1}, + "text-transform": {"capitalize": 1, "uppercase": 1, "lowercase": 1, "none": 1}, + "top": {"px": 1, "em": 1, "%": 1}, + "vertical-align": {"top": 1, "bottom": 1}, + "visibility": {"hidden": 1, "visible": 1}, + "white-space": {"nowrap": 1, "normal": 1, "pre": 1, "pre-line": 1, "pre-wrap": 1}, + "width": {"px": 1, "em": 1, "%": 1}, + "word-spacing": {"normal": 1}, + "filter": {"alpha(opacity=$0100)": 1}, + + "text-shadow": {"$02px 2px 2px #777": 1}, + "text-overflow": {"ellipsis-word": 1, "clip": 1, "ellipsis": 1}, + "-moz-border-radius": 1, + "-moz-border-radius-topright": 1, + "-moz-border-radius-bottomright": 1, + "-moz-border-radius-topleft": 1, + "-moz-border-radius-bottomleft": 1, + "-webkit-border-radius": 1, + "-webkit-border-top-right-radius": 1, + "-webkit-border-top-left-radius": 1, + "-webkit-border-bottom-right-radius": 1, + "-webkit-border-bottom-left-radius": 1, + "-moz-box-shadow": 1, + "-webkit-box-shadow": 1, + "transform": {"rotate($00deg)": 1, "skew($00deg)": 1}, + "-moz-transform": {"rotate($00deg)": 1, "skew($00deg)": 1}, + "-webkit-transform": {"rotate($00deg)": 1, "skew($00deg)": 1 } +}; + +var CssCompletions = function() { + +}; + +(function() { + + this.completionsDefined = false; + + this.defineCompletions = function() { + if (document) { + var style = document.createElement('c').style; + + for (var i in style) { + if (typeof style[i] !== 'string') + continue; + + var name = i.replace(/[A-Z]/g, function(x) { + return '-' + x.toLowerCase(); + }); + + if (!propertyMap.hasOwnProperty(name)) + propertyMap[name] = 1; + } + } + + this.completionsDefined = true; + }; + + this.getCompletions = function(state, session, pos, prefix) { + if (!this.completionsDefined) { + this.defineCompletions(); + } + + if (state==='ruleset' || session.$mode.$id == "ace/mode/scss") { + var line = session.getLine(pos.row).substr(0, pos.column); + if (/:[^;]+$/.test(line)) { + /([\w\-]+):[^:]*$/.test(line); + + return this.getPropertyValueCompletions(state, session, pos, prefix); + } else { + return this.getPropertyCompletions(state, session, pos, prefix); + } + } + + return []; + }; + + this.getPropertyCompletions = function(state, session, pos, prefix) { + var properties = Object.keys(propertyMap); + return properties.map(function(property){ + return { + caption: property, + snippet: property + ': $0;', + meta: "property", + score: 1000000 + }; + }); + }; + + this.getPropertyValueCompletions = function(state, session, pos, prefix) { + var line = session.getLine(pos.row).substr(0, pos.column); + var property = (/([\w\-]+):[^:]*$/.exec(line) || {})[1]; + + if (!property) + return []; + var values = []; + if (property in propertyMap && typeof propertyMap[property] === "object") { + values = Object.keys(propertyMap[property]); + } + return values.map(function(value){ + return { + caption: value, + snippet: value, + meta: "property value", + score: 1000000 + }; + }); + }; + +}).call(CssCompletions.prototype); + +exports.CssCompletions = CssCompletions; +}); + +define("ace/mode/behaviour/css",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle","ace/token_iterator"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Behaviour = require("../behaviour").Behaviour; +var CstyleBehaviour = require("./cstyle").CstyleBehaviour; +var TokenIterator = require("../../token_iterator").TokenIterator; + +var CssBehaviour = function () { + + this.inherit(CstyleBehaviour); + + this.add("colon", "insertion", function (state, action, editor, session, text) { + if (text === ':' && editor.selection.isEmpty()) { + var cursor = editor.getCursorPosition(); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + var token = iterator.getCurrentToken(); + if (token && token.value.match(/\s+/)) { + token = iterator.stepBackward(); + } + if (token && token.type === 'support.type') { + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar === ':') { + return { + text: '', + selection: [1, 1] + }; + } + if (/^(\s+[^;]|\s*$)/.test(line.substring(cursor.column))) { + return { + text: ':;', + selection: [1, 1] + }; + } + } + } + }); + + this.add("colon", "deletion", function (state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && selected === ':') { + var cursor = editor.getCursorPosition(); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + var token = iterator.getCurrentToken(); + if (token && token.value.match(/\s+/)) { + token = iterator.stepBackward(); + } + if (token && token.type === 'support.type') { + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.end.column, range.end.column + 1); + if (rightChar === ';') { + range.end.column ++; + return range; + } + } + } + }); + + this.add("semicolon", "insertion", function (state, action, editor, session, text) { + if (text === ';' && editor.selection.isEmpty()) { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + if (rightChar === ';') { + return { + text: '', + selection: [1, 1] + }; + } + } + }); + + this.add("!important", "insertion", function (state, action, editor, session, text) { + if (text === '!' && editor.selection.isEmpty()) { + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + + if (/^\s*(;|}|$)/.test(line.substring(cursor.column))) { + return { + text: '!important', + selection: [10, 10] + }; + } + } + }); + +}; +oop.inherits(CssBehaviour, CstyleBehaviour); + +exports.CssBehaviour = CssBehaviour; +}); + +define("ace/mode/css",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/css_highlight_rules","ace/mode/matching_brace_outdent","ace/worker/worker_client","ace/mode/css_completions","ace/mode/behaviour/css","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextMode = require("./text").Mode; +var CssHighlightRules = require("./css_highlight_rules").CssHighlightRules; +var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent; +var WorkerClient = require("../worker/worker_client").WorkerClient; +var CssCompletions = require("./css_completions").CssCompletions; +var CssBehaviour = require("./behaviour/css").CssBehaviour; +var CStyleFoldMode = require("./folding/cstyle").FoldMode; + +var Mode = function() { + this.HighlightRules = CssHighlightRules; + this.$outdent = new MatchingBraceOutdent(); + this.$behaviour = new CssBehaviour(); + this.$completer = new CssCompletions(); + this.foldingRules = new CStyleFoldMode(); +}; +oop.inherits(Mode, TextMode); + +(function() { + + this.foldingRules = "cStyle"; + this.blockComment = {start: "/*", end: "*/"}; + + this.getNextLineIndent = function(state, line, tab) { + var indent = this.$getIndent(line); + var tokens = this.getTokenizer().getLineTokens(line, state).tokens; + if (tokens.length && tokens[tokens.length-1].type == "comment") { + return indent; + } + + var match = line.match(/^.*\{\s*$/); + if (match) { + indent += tab; + } + + return indent; + }; + + this.checkOutdent = function(state, line, input) { + return this.$outdent.checkOutdent(line, input); + }; + + this.autoOutdent = function(state, doc, row) { + this.$outdent.autoOutdent(doc, row); + }; + + this.getCompletions = function(state, session, pos, prefix) { + return this.$completer.getCompletions(state, session, pos, prefix); + }; + + this.createWorker = function(session) { + var worker = new WorkerClient(["ace"], "ace/mode/css_worker", "Worker"); + worker.attachToDocument(session.getDocument()); + + worker.on("annotate", function(e) { + session.setAnnotations(e.data); + }); + + worker.on("terminate", function() { + session.clearAnnotations(); + }); + + return worker; + }; + + this.$id = "ace/mode/css"; +}).call(Mode.prototype); + +exports.Mode = Mode; + +}); + +define("ace/mode/xml_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; + +var XmlHighlightRules = function(normalize) { + var tagRegex = "[_:a-zA-Z\xc0-\uffff][-_:.a-zA-Z0-9\xc0-\uffff]*"; + + this.$rules = { + start : [ + {token : "string.cdata.xml", regex : "<\\!\\[CDATA\\[", next : "cdata"}, + { + token : ["punctuation.instruction.xml", "keyword.instruction.xml"], + regex : "(<\\?)(" + tagRegex + ")", next : "processing_instruction" + }, + {token : "comment.start.xml", regex : "<\\!--", next : "comment"}, + { + token : ["xml-pe.doctype.xml", "xml-pe.doctype.xml"], + regex : "(<\\!)(DOCTYPE)(?=[\\s])", next : "doctype", caseInsensitive: true + }, + {include : "tag"}, + {token : "text.end-tag-open.xml", regex: "", + next : "start" + }], + + doctype : [ + {include : "whitespace"}, + {include : "string"}, + {token : "xml-pe.doctype.xml", regex : ">", next : "start"}, + {token : "xml-pe.xml", regex : "[-_a-zA-Z0-9:]+"}, + {token : "punctuation.int-subset", regex : "\\[", push : "int_subset"} + ], + + int_subset : [{ + token : "text.xml", + regex : "\\s+" + }, { + token: "punctuation.int-subset.xml", + regex: "]", + next: "pop" + }, { + token : ["punctuation.markup-decl.xml", "keyword.markup-decl.xml"], + regex : "(<\\!)(" + tagRegex + ")", + push : [{ + token : "text", + regex : "\\s+" + }, + { + token : "punctuation.markup-decl.xml", + regex : ">", + next : "pop" + }, + {include : "string"}] + }], + + cdata : [ + {token : "string.cdata.xml", regex : "\\]\\]>", next : "start"}, + {token : "text.xml", regex : "\\s+"}, + {token : "text.xml", regex : "(?:[^\\]]|\\](?!\\]>))+"} + ], + + comment : [ + {token : "comment.end.xml", regex : "-->", next : "start"}, + {defaultToken : "comment.xml"} + ], + + reference : [{ + token : "constant.language.escape.reference.xml", + regex : "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)" + }], + + attr_reference : [{ + token : "constant.language.escape.reference.attribute-value.xml", + regex : "(?:&#[0-9]+;)|(?:&#x[0-9a-fA-F]+;)|(?:&[a-zA-Z0-9_:\\.-]+;)" + }], + + tag : [{ + token : ["meta.tag.punctuation.tag-open.xml", "meta.tag.punctuation.end-tag-open.xml", "meta.tag.tag-name.xml"], + regex : "(?:(<)|(", next : "start"} + ] + }], + + tag_whitespace : [ + {token : "text.tag-whitespace.xml", regex : "\\s+"} + ], + whitespace : [ + {token : "text.whitespace.xml", regex : "\\s+"} + ], + string: [{ + token : "string.xml", + regex : "'", + push : [ + {token : "string.xml", regex: "'", next: "pop"}, + {defaultToken : "string.xml"} + ] + }, { + token : "string.xml", + regex : '"', + push : [ + {token : "string.xml", regex: '"', next: "pop"}, + {defaultToken : "string.xml"} + ] + }], + + attributes: [{ + token : "entity.other.attribute-name.xml", + regex : tagRegex + }, { + token : "keyword.operator.attribute-equals.xml", + regex : "=" + }, { + include: "tag_whitespace" + }, { + include: "attribute_value" + }], + + attribute_value: [{ + token : "string.attribute-value.xml", + regex : "'", + push : [ + {token : "string.attribute-value.xml", regex: "'", next: "pop"}, + {include : "attr_reference"}, + {defaultToken : "string.attribute-value.xml"} + ] + }, { + token : "string.attribute-value.xml", + regex : '"', + push : [ + {token : "string.attribute-value.xml", regex: '"', next: "pop"}, + {include : "attr_reference"}, + {defaultToken : "string.attribute-value.xml"} + ] + }] + }; + + if (this.constructor === XmlHighlightRules) + this.normalizeRules(); +}; + + +(function() { + + this.embedTagRules = function(HighlightRules, prefix, tag){ + this.$rules.tag.unshift({ + token : ["meta.tag.punctuation.tag-open.xml", "meta.tag." + tag + ".tag-name.xml"], + regex : "(<)(" + tag + "(?=\\s|>|$))", + next: [ + {include : "attributes"}, + {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next : prefix + "start"} + ] + }); + + this.$rules[tag + "-end"] = [ + {include : "attributes"}, + {token : "meta.tag.punctuation.tag-close.xml", regex : "/?>", next: "start", + onMatch : function(value, currentState, stack) { + stack.splice(0); + return this.token; + }} + ]; + + this.embedRules(HighlightRules, prefix, [{ + token: ["meta.tag.punctuation.end-tag-open.xml", "meta.tag." + tag + ".tag-name.xml"], + regex : "(|$))", + next: tag + "-end" + }, { + token: "string.cdata.xml", + regex : "<\\!\\[CDATA\\[" + }, { + token: "string.cdata.xml", + regex : "\\]\\]>" + }]); + }; + +}).call(TextHighlightRules.prototype); + +oop.inherits(XmlHighlightRules, TextHighlightRules); + +exports.XmlHighlightRules = XmlHighlightRules; +}); + +define("ace/mode/html_highlight_rules",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/css_highlight_rules","ace/mode/javascript_highlight_rules","ace/mode/xml_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var lang = require("../lib/lang"); +var CssHighlightRules = require("./css_highlight_rules").CssHighlightRules; +var JavaScriptHighlightRules = require("./javascript_highlight_rules").JavaScriptHighlightRules; +var XmlHighlightRules = require("./xml_highlight_rules").XmlHighlightRules; + +var tagMap = lang.createMap({ + a : 'anchor', + button : 'form', + form : 'form', + img : 'image', + input : 'form', + label : 'form', + option : 'form', + script : 'script', + select : 'form', + textarea : 'form', + style : 'style', + table : 'table', + tbody : 'table', + td : 'table', + tfoot : 'table', + th : 'table', + tr : 'table' +}); + +var HtmlHighlightRules = function() { + XmlHighlightRules.call(this); + + this.addRules({ + attributes: [{ + include : "tag_whitespace" + }, { + token : "entity.other.attribute-name.xml", + regex : "[-_a-zA-Z0-9:.]+" + }, { + token : "keyword.operator.attribute-equals.xml", + regex : "=", + push : [{ + include: "tag_whitespace" + }, { + token : "string.unquoted.attribute-value.html", + regex : "[^<>='\"`\\s]+", + next : "pop" + }, { + token : "empty", + regex : "", + next : "pop" + }] + }, { + include : "attribute_value" + }], + tag: [{ + token : function(start, tag) { + var group = tagMap[tag]; + return ["meta.tag.punctuation." + (start == "<" ? "" : "end-") + "tag-open.xml", + "meta.tag" + (group ? "." + group : "") + ".tag-name.xml"]; + }, + regex : "(", next : "start"} + ] + }); + + this.embedTagRules(CssHighlightRules, "css-", "style"); + this.embedTagRules(new JavaScriptHighlightRules({jsx: false}).getRules(), "js-", "script"); + + if (this.constructor === HtmlHighlightRules) + this.normalizeRules(); +}; + +oop.inherits(HtmlHighlightRules, XmlHighlightRules); + +exports.HtmlHighlightRules = HtmlHighlightRules; +}); + +define("ace/mode/behaviour/xml",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/token_iterator","ace/lib/lang"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var Behaviour = require("../behaviour").Behaviour; +var TokenIterator = require("../../token_iterator").TokenIterator; +var lang = require("../../lib/lang"); + +function is(token, type) { + return token && token.type.lastIndexOf(type + ".xml") > -1; +} + +var XmlBehaviour = function () { + + this.add("string_dquotes", "insertion", function (state, action, editor, session, text) { + if (text == '"' || text == "'") { + var quote = text; + var selected = session.doc.getTextRange(editor.getSelectionRange()); + if (selected !== "" && selected !== "'" && selected != '"' && editor.getWrapBehavioursEnabled()) { + return { + text: quote + selected + quote, + selection: false + }; + } + + var cursor = editor.getCursorPosition(); + var line = session.doc.getLine(cursor.row); + var rightChar = line.substring(cursor.column, cursor.column + 1); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + var token = iterator.getCurrentToken(); + + if (rightChar == quote && (is(token, "attribute-value") || is(token, "string"))) { + return { + text: "", + selection: [1, 1] + }; + } + + if (!token) + token = iterator.stepBackward(); + + if (!token) + return; + + while (is(token, "tag-whitespace") || is(token, "whitespace")) { + token = iterator.stepBackward(); + } + var rightSpace = !rightChar || rightChar.match(/\s/); + if (is(token, "attribute-equals") && (rightSpace || rightChar == '>') || (is(token, "decl-attribute-equals") && (rightSpace || rightChar == '?'))) { + return { + text: quote + quote, + selection: [1, 1] + }; + } + } + }); + + this.add("string_dquotes", "deletion", function(state, action, editor, session, range) { + var selected = session.doc.getTextRange(range); + if (!range.isMultiLine() && (selected == '"' || selected == "'")) { + var line = session.doc.getLine(range.start.row); + var rightChar = line.substring(range.start.column + 1, range.start.column + 2); + if (rightChar == selected) { + range.end.column++; + return range; + } + } + }); + + this.add("autoclosing", "insertion", function (state, action, editor, session, text) { + if (text == '>') { + var position = editor.getSelectionRange().start; + var iterator = new TokenIterator(session, position.row, position.column); + var token = iterator.getCurrentToken() || iterator.stepBackward(); + if (!token || !(is(token, "tag-name") || is(token, "tag-whitespace") || is(token, "attribute-name") || is(token, "attribute-equals") || is(token, "attribute-value"))) + return; + if (is(token, "reference.attribute-value")) + return; + if (is(token, "attribute-value")) { + var tokenEndColumn = iterator.getCurrentTokenColumn() + token.value.length; + if (position.column < tokenEndColumn) + return; + if (position.column == tokenEndColumn) { + var nextToken = iterator.stepForward(); + if (nextToken && is(nextToken, "attribute-value")) + return; + iterator.stepBackward(); + } + } + + if (/^\s*>/.test(session.getLine(position.row).slice(position.column))) + return; + while (!is(token, "tag-name")) { + token = iterator.stepBackward(); + if (token.value == "<") { + token = iterator.stepForward(); + break; + } + } + + var tokenRow = iterator.getCurrentTokenRow(); + var tokenColumn = iterator.getCurrentTokenColumn(); + if (is(iterator.stepBackward(), "end-tag-open")) + return; + + var element = token.value; + if (tokenRow == position.row) + element = element.substring(0, position.column - tokenColumn); + + if (this.voidElements.hasOwnProperty(element.toLowerCase())) + return; + + return { + text: ">" + "", + selection: [1, 1] + }; + } + }); + + this.add("autoindent", "insertion", function (state, action, editor, session, text) { + if (text == "\n") { + var cursor = editor.getCursorPosition(); + var line = session.getLine(cursor.row); + var iterator = new TokenIterator(session, cursor.row, cursor.column); + var token = iterator.getCurrentToken(); + + if (token && token.type.indexOf("tag-close") !== -1) { + if (token.value == "/>") + return; + while (token && token.type.indexOf("tag-name") === -1) { + token = iterator.stepBackward(); + } + + if (!token) { + return; + } + + var tag = token.value; + var row = iterator.getCurrentTokenRow(); + token = iterator.stepBackward(); + if (!token || token.type.indexOf("end-tag") !== -1) { + return; + } + + if (this.voidElements && !this.voidElements[tag]) { + var nextToken = session.getTokenAt(cursor.row, cursor.column+1); + var line = session.getLine(row); + var nextIndent = this.$getIndent(line); + var indent = nextIndent + session.getTabString(); + + if (nextToken && nextToken.value === " -1; +} + +(function() { + + this.getFoldWidget = function(session, foldStyle, row) { + var tag = this._getFirstTagInLine(session, row); + + if (!tag) + return this.getCommentFoldWidget(session, row); + + if (tag.closing || (!tag.tagName && tag.selfClosing)) + return foldStyle == "markbeginend" ? "end" : ""; + + if (!tag.tagName || tag.selfClosing || this.voidElements.hasOwnProperty(tag.tagName.toLowerCase())) + return ""; + + if (this._findEndTagInLine(session, row, tag.tagName, tag.end.column)) + return ""; + + return "start"; + }; + + this.getCommentFoldWidget = function(session, row) { + if (/comment/.test(session.getState(row)) && /'; + break; + } + } + return tag; + } else if (is(token, "tag-close")) { + tag.selfClosing = token.value == '/>'; + return tag; + } + tag.start.column += token.value.length; + } + + return null; + }; + + this._findEndTagInLine = function(session, row, tagName, startColumn) { + var tokens = session.getTokens(row); + var column = 0; + for (var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + column += token.value.length; + if (column < startColumn) + continue; + if (is(token, "end-tag-open")) { + token = tokens[i + 1]; + if (token && token.value == tagName) + return true; + } + } + return false; + }; + this._readTagForward = function(iterator) { + var token = iterator.getCurrentToken(); + if (!token) + return null; + + var tag = new Tag(); + do { + if (is(token, "tag-open")) { + tag.closing = is(token, "end-tag-open"); + tag.start.row = iterator.getCurrentTokenRow(); + tag.start.column = iterator.getCurrentTokenColumn(); + } else if (is(token, "tag-name")) { + tag.tagName = token.value; + } else if (is(token, "tag-close")) { + tag.selfClosing = token.value == "/>"; + tag.end.row = iterator.getCurrentTokenRow(); + tag.end.column = iterator.getCurrentTokenColumn() + token.value.length; + iterator.stepForward(); + return tag; + } + } while(token = iterator.stepForward()); + + return null; + }; + + this._readTagBackward = function(iterator) { + var token = iterator.getCurrentToken(); + if (!token) + return null; + + var tag = new Tag(); + do { + if (is(token, "tag-open")) { + tag.closing = is(token, "end-tag-open"); + tag.start.row = iterator.getCurrentTokenRow(); + tag.start.column = iterator.getCurrentTokenColumn(); + iterator.stepBackward(); + return tag; + } else if (is(token, "tag-name")) { + tag.tagName = token.value; + } else if (is(token, "tag-close")) { + tag.selfClosing = token.value == "/>"; + tag.end.row = iterator.getCurrentTokenRow(); + tag.end.column = iterator.getCurrentTokenColumn() + token.value.length; + } + } while(token = iterator.stepBackward()); + + return null; + }; + + this._pop = function(stack, tag) { + while (stack.length) { + + var top = stack[stack.length-1]; + if (!tag || top.tagName == tag.tagName) { + return stack.pop(); + } + else if (this.optionalEndTags.hasOwnProperty(top.tagName)) { + stack.pop(); + continue; + } else { + return null; + } + } + }; + + this.getFoldWidgetRange = function(session, foldStyle, row) { + var firstTag = this._getFirstTagInLine(session, row); + + if (!firstTag) { + return this.getCommentFoldWidget(session, row) + && session.getCommentFoldRange(row, session.getLine(row).length); + } + + var isBackward = firstTag.closing || firstTag.selfClosing; + var stack = []; + var tag; + + if (!isBackward) { + var iterator = new TokenIterator(session, row, firstTag.start.column); + var start = { + row: row, + column: firstTag.start.column + firstTag.tagName.length + 2 + }; + if (firstTag.start.row == firstTag.end.row) + start.column = firstTag.end.column; + while (tag = this._readTagForward(iterator)) { + if (tag.selfClosing) { + if (!stack.length) { + tag.start.column += tag.tagName.length + 2; + tag.end.column -= 2; + return Range.fromPoints(tag.start, tag.end); + } else + continue; + } + + if (tag.closing) { + this._pop(stack, tag); + if (stack.length == 0) + return Range.fromPoints(start, tag.start); + } + else { + stack.push(tag); + } + } + } + else { + var iterator = new TokenIterator(session, row, firstTag.end.column); + var end = { + row: row, + column: firstTag.start.column + }; + + while (tag = this._readTagBackward(iterator)) { + if (tag.selfClosing) { + if (!stack.length) { + tag.start.column += tag.tagName.length + 2; + tag.end.column -= 2; + return Range.fromPoints(tag.start, tag.end); + } else + continue; + } + + if (!tag.closing) { + this._pop(stack, tag); + if (stack.length == 0) { + tag.start.column += tag.tagName.length + 2; + if (tag.start.row == tag.end.row && tag.start.column < tag.end.column) + tag.start.column = tag.end.column; + return Range.fromPoints(tag.start, end); + } + } + else { + stack.push(tag); + } + } + } + + }; + +}).call(FoldMode.prototype); + +}); + +define("ace/mode/folding/html",["require","exports","module","ace/lib/oop","ace/mode/folding/mixed","ace/mode/folding/xml","ace/mode/folding/cstyle"], function(require, exports, module) { +"use strict"; + +var oop = require("../../lib/oop"); +var MixedFoldMode = require("./mixed").FoldMode; +var XmlFoldMode = require("./xml").FoldMode; +var CStyleFoldMode = require("./cstyle").FoldMode; + +var FoldMode = exports.FoldMode = function(voidElements, optionalTags) { + MixedFoldMode.call(this, new XmlFoldMode(voidElements, optionalTags), { + "js-": new CStyleFoldMode(), + "css-": new CStyleFoldMode() + }); +}; + +oop.inherits(FoldMode, MixedFoldMode); + +}); + +define("ace/mode/html_completions",["require","exports","module","ace/token_iterator"], function(require, exports, module) { +"use strict"; + +var TokenIterator = require("../token_iterator").TokenIterator; + +var commonAttributes = [ + "accesskey", + "class", + "contenteditable", + "contextmenu", + "dir", + "draggable", + "dropzone", + "hidden", + "id", + "inert", + "itemid", + "itemprop", + "itemref", + "itemscope", + "itemtype", + "lang", + "spellcheck", + "style", + "tabindex", + "title", + "translate" +]; + +var eventAttributes = [ + "onabort", + "onblur", + "oncancel", + "oncanplay", + "oncanplaythrough", + "onchange", + "onclick", + "onclose", + "oncontextmenu", + "oncuechange", + "ondblclick", + "ondrag", + "ondragend", + "ondragenter", + "ondragleave", + "ondragover", + "ondragstart", + "ondrop", + "ondurationchange", + "onemptied", + "onended", + "onerror", + "onfocus", + "oninput", + "oninvalid", + "onkeydown", + "onkeypress", + "onkeyup", + "onload", + "onloadeddata", + "onloadedmetadata", + "onloadstart", + "onmousedown", + "onmousemove", + "onmouseout", + "onmouseover", + "onmouseup", + "onmousewheel", + "onpause", + "onplay", + "onplaying", + "onprogress", + "onratechange", + "onreset", + "onscroll", + "onseeked", + "onseeking", + "onselect", + "onshow", + "onstalled", + "onsubmit", + "onsuspend", + "ontimeupdate", + "onvolumechange", + "onwaiting" +]; + +var globalAttributes = commonAttributes.concat(eventAttributes); + +var attributeMap = { + "a": {"href": 1, "target": {"_blank": 1, "top": 1}, "ping": 1, "rel": {"nofollow": 1, "alternate": 1, "author": 1, "bookmark": 1, "help": 1, "license": 1, "next": 1, "noreferrer": 1, "prefetch": 1, "prev": 1, "search": 1, "tag": 1}, "media": 1, "hreflang": 1, "type": 1}, + "abbr": {}, + "address": {}, + "area": {"shape": 1, "coords": 1, "href": 1, "hreflang": 1, "alt": 1, "target": 1, "media": 1, "rel": 1, "ping": 1, "type": 1}, + "article": {"pubdate": 1}, + "aside": {}, + "audio": {"src": 1, "autobuffer": 1, "autoplay": {"autoplay": 1}, "loop": {"loop": 1}, "controls": {"controls": 1}, "muted": {"muted": 1}, "preload": {"auto": 1, "metadata": 1, "none": 1 }}, + "b": {}, + "base": {"href": 1, "target": 1}, + "bdi": {}, + "bdo": {}, + "blockquote": {"cite": 1}, + "body": {"onafterprint": 1, "onbeforeprint": 1, "onbeforeunload": 1, "onhashchange": 1, "onmessage": 1, "onoffline": 1, "onpopstate": 1, "onredo": 1, "onresize": 1, "onstorage": 1, "onundo": 1, "onunload": 1}, + "br": {}, + "button": {"autofocus": 1, "disabled": {"disabled": 1}, "form": 1, "formaction": 1, "formenctype": 1, "formmethod": 1, "formnovalidate": 1, "formtarget": 1, "name": 1, "value": 1, "type": {"button": 1, "submit": 1}}, + "canvas": {"width": 1, "height": 1}, + "caption": {}, + "cite": {}, + "code": {}, + "col": {"span": 1}, + "colgroup": {"span": 1}, + "command": {"type": 1, "label": 1, "icon": 1, "disabled": 1, "checked": 1, "radiogroup": 1, "command": 1}, + "data": {}, + "datalist": {}, + "dd": {}, + "del": {"cite": 1, "datetime": 1}, + "details": {"open": 1}, + "dfn": {}, + "dialog": {"open": 1}, + "div": {}, + "dl": {}, + "dt": {}, + "em": {}, + "embed": {"src": 1, "height": 1, "width": 1, "type": 1}, + "fieldset": {"disabled": 1, "form": 1, "name": 1}, + "figcaption": {}, + "figure": {}, + "footer": {}, + "form": {"accept-charset": 1, "action": 1, "autocomplete": 1, "enctype": {"multipart/form-data": 1, "application/x-www-form-urlencoded": 1}, "method": {"get": 1, "post": 1}, "name": 1, "novalidate": 1, "target": {"_blank": 1, "top": 1}}, + "h1": {}, + "h2": {}, + "h3": {}, + "h4": {}, + "h5": {}, + "h6": {}, + "head": {}, + "header": {}, + "hr": {}, + "html": {"manifest": 1}, + "i": {}, + "iframe": {"name": 1, "src": 1, "height": 1, "width": 1, "sandbox": {"allow-same-origin": 1, "allow-top-navigation": 1, "allow-forms": 1, "allow-scripts": 1}, "seamless": {"seamless": 1}}, + "img": {"alt": 1, "src": 1, "height": 1, "width": 1, "usemap": 1, "ismap": 1}, + "input": { + "type": {"text": 1, "password": 1, "hidden": 1, "checkbox": 1, "submit": 1, "radio": 1, "file": 1, "button": 1, "reset": 1, "image": 31, "color": 1, "date": 1, "datetime": 1, "datetime-local": 1, "email": 1, "month": 1, "number": 1, "range": 1, "search": 1, "tel": 1, "time": 1, "url": 1, "week": 1}, + "accept": 1, "alt": 1, "autocomplete": {"on": 1, "off": 1}, "autofocus": {"autofocus": 1}, "checked": {"checked": 1}, "disabled": {"disabled": 1}, "form": 1, "formaction": 1, "formenctype": {"application/x-www-form-urlencoded": 1, "multipart/form-data": 1, "text/plain": 1}, "formmethod": {"get": 1, "post": 1}, "formnovalidate": {"formnovalidate": 1}, "formtarget": {"_blank": 1, "_self": 1, "_parent": 1, "_top": 1}, "height": 1, "list": 1, "max": 1, "maxlength": 1, "min": 1, "multiple": {"multiple": 1}, "name": 1, "pattern": 1, "placeholder": 1, "readonly": {"readonly": 1}, "required": {"required": 1}, "size": 1, "src": 1, "step": 1, "width": 1, "files": 1, "value": 1}, + "ins": {"cite": 1, "datetime": 1}, + "kbd": {}, + "keygen": {"autofocus": 1, "challenge": {"challenge": 1}, "disabled": {"disabled": 1}, "form": 1, "keytype": {"rsa": 1, "dsa": 1, "ec": 1}, "name": 1}, + "label": {"form": 1, "for": 1}, + "legend": {}, + "li": {"value": 1}, + "link": {"href": 1, "hreflang": 1, "rel": {"stylesheet": 1, "icon": 1}, "media": {"all": 1, "screen": 1, "print": 1}, "type": {"text/css": 1, "image/png": 1, "image/jpeg": 1, "image/gif": 1}, "sizes": 1}, + "main": {}, + "map": {"name": 1}, + "mark": {}, + "math": {}, + "menu": {"type": 1, "label": 1}, + "meta": {"http-equiv": {"content-type": 1}, "name": {"description": 1, "keywords": 1}, "content": {"text/html; charset=UTF-8": 1}, "charset": 1}, + "meter": {"value": 1, "min": 1, "max": 1, "low": 1, "high": 1, "optimum": 1}, + "nav": {}, + "noscript": {"href": 1}, + "object": {"param": 1, "data": 1, "type": 1, "height" : 1, "width": 1, "usemap": 1, "name": 1, "form": 1, "classid": 1}, + "ol": {"start": 1, "reversed": 1}, + "optgroup": {"disabled": 1, "label": 1}, + "option": {"disabled": 1, "selected": 1, "label": 1, "value": 1}, + "output": {"for": 1, "form": 1, "name": 1}, + "p": {}, + "param": {"name": 1, "value": 1}, + "pre": {}, + "progress": {"value": 1, "max": 1}, + "q": {"cite": 1}, + "rp": {}, + "rt": {}, + "ruby": {}, + "s": {}, + "samp": {}, + "script": {"charset": 1, "type": {"text/javascript": 1}, "src": 1, "defer": 1, "async": 1}, + "select": {"autofocus": 1, "disabled": 1, "form": 1, "multiple": {"multiple": 1}, "name": 1, "size": 1, "readonly":{"readonly": 1}}, + "small": {}, + "source": {"src": 1, "type": 1, "media": 1}, + "span": {}, + "strong": {}, + "style": {"type": 1, "media": {"all": 1, "screen": 1, "print": 1}, "scoped": 1}, + "sub": {}, + "sup": {}, + "svg": {}, + "table": {"summary": 1}, + "tbody": {}, + "td": {"headers": 1, "rowspan": 1, "colspan": 1}, + "textarea": {"autofocus": {"autofocus": 1}, "disabled": {"disabled": 1}, "form": 1, "maxlength": 1, "name": 1, "placeholder": 1, "readonly": {"readonly": 1}, "required": {"required": 1}, "rows": 1, "cols": 1, "wrap": {"on": 1, "off": 1, "hard": 1, "soft": 1}}, + "tfoot": {}, + "th": {"headers": 1, "rowspan": 1, "colspan": 1, "scope": 1}, + "thead": {}, + "time": {"datetime": 1}, + "title": {}, + "tr": {}, + "track": {"kind": 1, "src": 1, "srclang": 1, "label": 1, "default": 1}, + "section": {}, + "summary": {}, + "u": {}, + "ul": {}, + "var": {}, + "video": {"src": 1, "autobuffer": 1, "autoplay": {"autoplay": 1}, "loop": {"loop": 1}, "controls": {"controls": 1}, "width": 1, "height": 1, "poster": 1, "muted": {"muted": 1}, "preload": {"auto": 1, "metadata": 1, "none": 1}}, + "wbr": {} +}; + +var elements = Object.keys(attributeMap); + +function is(token, type) { + return token.type.lastIndexOf(type + ".xml") > -1; +} + +function findTagName(session, pos) { + var iterator = new TokenIterator(session, pos.row, pos.column); + var token = iterator.getCurrentToken(); + while (token && !is(token, "tag-name")){ + token = iterator.stepBackward(); + } + if (token) + return token.value; +} + +function findAttributeName(session, pos) { + var iterator = new TokenIterator(session, pos.row, pos.column); + var token = iterator.getCurrentToken(); + while (token && !is(token, "attribute-name")){ + token = iterator.stepBackward(); + } + if (token) + return token.value; +} + +var HtmlCompletions = function() { + +}; + +(function() { + + this.getCompletions = function(state, session, pos, prefix) { + var token = session.getTokenAt(pos.row, pos.column); + + if (!token) + return []; + if (is(token, "tag-name") || is(token, "tag-open") || is(token, "end-tag-open")) + return this.getTagCompletions(state, session, pos, prefix); + if (is(token, "tag-whitespace") || is(token, "attribute-name")) + return this.getAttributeCompletions(state, session, pos, prefix); + if (is(token, "attribute-value")) + return this.getAttributeValueCompletions(state, session, pos, prefix); + var line = session.getLine(pos.row).substr(0, pos.column); + if (/&[a-z]*$/i.test(line)) + return this.getHTMLEntityCompletions(state, session, pos, prefix); + + return []; + }; + + this.getTagCompletions = function(state, session, pos, prefix) { + return elements.map(function(element){ + return { + value: element, + meta: "tag", + score: 1000000 + }; + }); + }; + + this.getAttributeCompletions = function(state, session, pos, prefix) { + var tagName = findTagName(session, pos); + if (!tagName) + return []; + var attributes = globalAttributes; + if (tagName in attributeMap) { + attributes = attributes.concat(Object.keys(attributeMap[tagName])); + } + return attributes.map(function(attribute){ + return { + caption: attribute, + snippet: attribute + '="$0"', + meta: "attribute", + score: 1000000 + }; + }); + }; + + this.getAttributeValueCompletions = function(state, session, pos, prefix) { + var tagName = findTagName(session, pos); + var attributeName = findAttributeName(session, pos); + + if (!tagName) + return []; + var values = []; + if (tagName in attributeMap && attributeName in attributeMap[tagName] && typeof attributeMap[tagName][attributeName] === "object") { + values = Object.keys(attributeMap[tagName][attributeName]); + } + return values.map(function(value){ + return { + caption: value, + snippet: value, + meta: "attribute value", + score: 1000000 + }; + }); + }; + + this.getHTMLEntityCompletions = function(state, session, pos, prefix) { + var values = ['Aacute;', 'aacute;', 'Acirc;', 'acirc;', 'acute;', 'AElig;', 'aelig;', 'Agrave;', 'agrave;', 'alefsym;', 'Alpha;', 'alpha;', 'amp;', 'and;', 'ang;', 'Aring;', 'aring;', 'asymp;', 'Atilde;', 'atilde;', 'Auml;', 'auml;', 'bdquo;', 'Beta;', 'beta;', 'brvbar;', 'bull;', 'cap;', 'Ccedil;', 'ccedil;', 'cedil;', 'cent;', 'Chi;', 'chi;', 'circ;', 'clubs;', 'cong;', 'copy;', 'crarr;', 'cup;', 'curren;', 'Dagger;', 'dagger;', 'dArr;', 'darr;', 'deg;', 'Delta;', 'delta;', 'diams;', 'divide;', 'Eacute;', 'eacute;', 'Ecirc;', 'ecirc;', 'Egrave;', 'egrave;', 'empty;', 'emsp;', 'ensp;', 'Epsilon;', 'epsilon;', 'equiv;', 'Eta;', 'eta;', 'ETH;', 'eth;', 'Euml;', 'euml;', 'euro;', 'exist;', 'fnof;', 'forall;', 'frac12;', 'frac14;', 'frac34;', 'frasl;', 'Gamma;', 'gamma;', 'ge;', 'gt;', 'hArr;', 'harr;', 'hearts;', 'hellip;', 'Iacute;', 'iacute;', 'Icirc;', 'icirc;', 'iexcl;', 'Igrave;', 'igrave;', 'image;', 'infin;', 'int;', 'Iota;', 'iota;', 'iquest;', 'isin;', 'Iuml;', 'iuml;', 'Kappa;', 'kappa;', 'Lambda;', 'lambda;', 'lang;', 'laquo;', 'lArr;', 'larr;', 'lceil;', 'ldquo;', 'le;', 'lfloor;', 'lowast;', 'loz;', 'lrm;', 'lsaquo;', 'lsquo;', 'lt;', 'macr;', 'mdash;', 'micro;', 'middot;', 'minus;', 'Mu;', 'mu;', 'nabla;', 'nbsp;', 'ndash;', 'ne;', 'ni;', 'not;', 'notin;', 'nsub;', 'Ntilde;', 'ntilde;', 'Nu;', 'nu;', 'Oacute;', 'oacute;', 'Ocirc;', 'ocirc;', 'OElig;', 'oelig;', 'Ograve;', 'ograve;', 'oline;', 'Omega;', 'omega;', 'Omicron;', 'omicron;', 'oplus;', 'or;', 'ordf;', 'ordm;', 'Oslash;', 'oslash;', 'Otilde;', 'otilde;', 'otimes;', 'Ouml;', 'ouml;', 'para;', 'part;', 'permil;', 'perp;', 'Phi;', 'phi;', 'Pi;', 'pi;', 'piv;', 'plusmn;', 'pound;', 'Prime;', 'prime;', 'prod;', 'prop;', 'Psi;', 'psi;', 'quot;', 'radic;', 'rang;', 'raquo;', 'rArr;', 'rarr;', 'rceil;', 'rdquo;', 'real;', 'reg;', 'rfloor;', 'Rho;', 'rho;', 'rlm;', 'rsaquo;', 'rsquo;', 'sbquo;', 'Scaron;', 'scaron;', 'sdot;', 'sect;', 'shy;', 'Sigma;', 'sigma;', 'sigmaf;', 'sim;', 'spades;', 'sub;', 'sube;', 'sum;', 'sup;', 'sup1;', 'sup2;', 'sup3;', 'supe;', 'szlig;', 'Tau;', 'tau;', 'there4;', 'Theta;', 'theta;', 'thetasym;', 'thinsp;', 'THORN;', 'thorn;', 'tilde;', 'times;', 'trade;', 'Uacute;', 'uacute;', 'uArr;', 'uarr;', 'Ucirc;', 'ucirc;', 'Ugrave;', 'ugrave;', 'uml;', 'upsih;', 'Upsilon;', 'upsilon;', 'Uuml;', 'uuml;', 'weierp;', 'Xi;', 'xi;', 'Yacute;', 'yacute;', 'yen;', 'Yuml;', 'yuml;', 'Zeta;', 'zeta;', 'zwj;', 'zwnj;']; + + return values.map(function(value){ + return { + caption: value, + snippet: value, + meta: "html entity", + score: 1000000 + }; + }); + }; + +}).call(HtmlCompletions.prototype); + +exports.HtmlCompletions = HtmlCompletions; +}); + +define("ace/mode/html",["require","exports","module","ace/lib/oop","ace/lib/lang","ace/mode/text","ace/mode/javascript","ace/mode/css","ace/mode/html_highlight_rules","ace/mode/behaviour/xml","ace/mode/folding/html","ace/mode/html_completions","ace/worker/worker_client"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var lang = require("../lib/lang"); +var TextMode = require("./text").Mode; +var JavaScriptMode = require("./javascript").Mode; +var CssMode = require("./css").Mode; +var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; +var XmlBehaviour = require("./behaviour/xml").XmlBehaviour; +var HtmlFoldMode = require("./folding/html").FoldMode; +var HtmlCompletions = require("./html_completions").HtmlCompletions; +var WorkerClient = require("../worker/worker_client").WorkerClient; +var voidElements = ["area", "base", "br", "col", "embed", "hr", "img", "input", "keygen", "link", "meta", "menuitem", "param", "source", "track", "wbr"]; +var optionalEndTags = ["li", "dt", "dd", "p", "rt", "rp", "optgroup", "option", "colgroup", "td", "th"]; + +var Mode = function(options) { + this.fragmentContext = options && options.fragmentContext; + this.HighlightRules = HtmlHighlightRules; + this.$behaviour = new XmlBehaviour(); + this.$completer = new HtmlCompletions(); + + this.createModeDelegates({ + "js-": JavaScriptMode, + "css-": CssMode + }); + + this.foldingRules = new HtmlFoldMode(this.voidElements, lang.arrayToMap(optionalEndTags)); +}; +oop.inherits(Mode, TextMode); + +(function() { + + this.blockComment = {start: ""}; + + this.voidElements = lang.arrayToMap(voidElements); + + this.getNextLineIndent = function(state, line, tab) { + return this.$getIndent(line); + }; + + this.checkOutdent = function(state, line, input) { + return false; + }; + + this.getCompletions = function(state, session, pos, prefix) { + return this.$completer.getCompletions(state, session, pos, prefix); + }; + + this.createWorker = function(session) { + if (this.constructor != Mode) + return; + var worker = new WorkerClient(["ace"], "ace/mode/html_worker", "Worker"); + worker.attachToDocument(session.getDocument()); + + if (this.fragmentContext) + worker.call("setOptions", [{context: this.fragmentContext}]); + + worker.on("error", function(e) { + session.setAnnotations(e.data); + }); + + worker.on("terminate", function() { + session.clearAnnotations(); + }); + + return worker; + }; + + this.$id = "ace/mode/html"; +}).call(Mode.prototype); + +exports.Mode = Mode; +}); + +define("ace/mode/nunjucks_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules","ace/mode/html_highlight_rules"], function(require, exports, module) { +"use strict"; + +var oop = require("../lib/oop"); +var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules; +var HtmlHighlightRules = require("./html_highlight_rules").HtmlHighlightRules; + +var NunjucksHighlightRules = function() { + HtmlHighlightRules.call(this); + this.$rules["start"].unshift({ + token: "punctuation.begin", + regex: /{{-?/, + push: [{ + token: "punctuation.end", + regex: /-?}}/, + next: "pop" + }, + {include: "expression"} + ] + }, { + token: "punctuation.begin", + regex: /{%-?/, + push: [{ + token: "punctuation.end", + regex: /-?%}/, + next: "pop" + }, { + token: "constant.language.escape", + regex: /\b(r\/.*\/[gimy]?)\b/ + }, + {include: "statement"} + ] + }, { + token: "comment.begin", + regex: /{#/, + push: [{ + token: "comment.end", + regex: /#}/, + next: "pop" + }, + {defaultToken: "comment"} + ] + }); + this.addRules({ + attribute_value: [{ + token: "string.attribute-value.xml", + regex: "'", + push: [ + {token: "string.attribute-value.xml", regex: "'", next: "pop"}, + { + token: "punctuation.begin", + regex: /{{-?/, + push: [{ + token: "punctuation.end", + regex: /-?}}/, + next: "pop" + }, + {include: "expression"} + ] + }, + {include: "attr_reference"}, + {defaultToken: "string.attribute-value.xml"} + ] + }, { + token: "string.attribute-value.xml", + regex: '"', + push: [ + {token: "string.attribute-value.xml", regex: '"', next: "pop"}, + { + token: "punctuation.begin", + regex: /{{-?/, + push: [{ + token: "punctuation.end", + regex: /-?}}/, + next: "pop" + }, + {include: "expression"} + ] + }, + {include: "attr_reference"}, + {defaultToken: "string.attribute-value.xml"} + ] + }], + "statement": [{ + token: "keyword.control", + regex: /\b(block|endblock|extends|endif|elif|for|endfor|asyncEach|endeach|include|asyncAll|endall|macro|endmacro|set|endset|ignore missing|as|from|raw|verbatim|filter|endfilter)\b/ + }, + {include: "expression"} + ], + "expression": [{ + token: "constant.language", + regex: /\b(true|false|none)\b/ + }, { + token: "string", + regex: /"/, + push: [{ + token: "string", + regex: /"/, + next: "pop" + }, + {include: "escapeStrings"}, + {defaultToken: "string"} + ] + }, { + token: "string", + regex: /'/, + push: [{ + token: "string", + regex: /'/, + next: "pop" + }, + {include: "escapeStrings"}, + {defaultToken: "string"} + ] + }, { + token: "constant.numeric", // hexadecimal, octal and binary + regex: /0(?:[xX][0-9a-fA-F]+|[oO][0-7]+|[bB][01]+)\b/ + }, { + token: "constant.numeric", // decimal integers and floats + regex: /(?:\d\d*(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+\b)?/ + }, { + token: "keyword.operator", + regex: /\+|-|\/\/|\/|%|\*\*|\*|===|==|!==|!=|>=|>|<=|',start+9); - domBuilder.startCDATA(); - domBuilder.characters(source,start+9,end-start-9); - domBuilder.endCDATA() - return end+3; + if (end > start) { + domBuilder.startCDATA(); + domBuilder.characters(source,start+9,end-start-9); + domBuilder.endCDATA() + return end+3; + } else { + errorHandler.error("Unclosed CDATA"); + return -1; + } } var matchs = split(source,start); var len = matchs.length; @@ -3825,10 +3830,10 @@ if (!Date.now) { return new Date().getTime(); }; } -var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" + +var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" + "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + "\u2029\uFEFF"; -if (!String.prototype.trim || ws.trim()) { +if (!String.prototype.trim) { ws = "[" + ws + "]"; var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), trimEndRegexp = new RegExp(ws + ws + "*$"); diff --git a/htdocs/includes/ace/src/worker-xquery.js b/htdocs/includes/ace/src/worker-xquery.js index a20b76c2c28..6f0f68123d2 100644 --- a/htdocs/includes/ace/src/worker-xquery.js +++ b/htdocs/includes/ace/src/worker-xquery.js @@ -58290,10 +58290,10 @@ if (!Date.now) { return new Date().getTime(); }; } -var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" + +var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003" + "\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028" + "\u2029\uFEFF"; -if (!String.prototype.trim || ws.trim()) { +if (!String.prototype.trim) { ws = "[" + ws + "]"; var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), trimEndRegexp = new RegExp(ws + ws + "*$"); diff --git a/htdocs/includes/ace/webpack-resolver.js b/htdocs/includes/ace/webpack-resolver.js index 1d5de60d98a..6205871f242 100644 --- a/htdocs/includes/ace/webpack-resolver.js +++ b/htdocs/includes/ace/webpack-resolver.js @@ -1,403 +1,403 @@ -ace.config.setModuleUrl('ace/ext/beautify', require('file-loader!./src-noconflict/ext-beautify.js')) -ace.config.setModuleUrl('ace/ext/elastic_tabstops_lite', require('file-loader!./src-noconflict/ext-elastic_tabstops_lite.js')) -ace.config.setModuleUrl('ace/ext/emmet', require('file-loader!./src-noconflict/ext-emmet.js')) -ace.config.setModuleUrl('ace/ext/error_marker', require('file-loader!./src-noconflict/ext-error_marker.js')) -ace.config.setModuleUrl('ace/ext/keyboard_menu', require('file-loader!./src-noconflict/ext-keybinding_menu.js')) -ace.config.setModuleUrl('ace/ext/language_tools', require('file-loader!./src-noconflict/ext-language_tools.js')) -ace.config.setModuleUrl('ace/ext/linking', require('file-loader!./src-noconflict/ext-linking.js')) -ace.config.setModuleUrl('ace/ext/modelist', require('file-loader!./src-noconflict/ext-modelist.js')) -ace.config.setModuleUrl('ace/ext/options', require('file-loader!./src-noconflict/ext-options.js')) -ace.config.setModuleUrl('ace/ext/prompt', require('file-loader!./src-noconflict/ext-prompt.js')) -ace.config.setModuleUrl('ace/ext/rtl', require('file-loader!./src-noconflict/ext-rtl.js')) -ace.config.setModuleUrl('ace/ext/searchbox', require('file-loader!./src-noconflict/ext-searchbox.js')) -ace.config.setModuleUrl('ace/ext/settings_menu', require('file-loader!./src-noconflict/ext-settings_menu.js')) -ace.config.setModuleUrl('ace/ext/spellcheck', require('file-loader!./src-noconflict/ext-spellcheck.js')) -ace.config.setModuleUrl('ace/ext/split', require('file-loader!./src-noconflict/ext-split.js')) -ace.config.setModuleUrl('ace/ext/static_highlight', require('file-loader!./src-noconflict/ext-static_highlight.js')) -ace.config.setModuleUrl('ace/ext/statusbar', require('file-loader!./src-noconflict/ext-statusbar.js')) -ace.config.setModuleUrl('ace/ext/textarea', require('file-loader!./src-noconflict/ext-textarea.js')) -ace.config.setModuleUrl('ace/ext/themelist', require('file-loader!./src-noconflict/ext-themelist.js')) -ace.config.setModuleUrl('ace/ext/whitespace', require('file-loader!./src-noconflict/ext-whitespace.js')) -ace.config.setModuleUrl('ace/keyboard/emacs', require('file-loader!./src-noconflict/keybinding-emacs.js')) -ace.config.setModuleUrl('ace/keyboard/sublime', require('file-loader!./src-noconflict/keybinding-sublime.js')) -ace.config.setModuleUrl('ace/keyboard/vim', require('file-loader!./src-noconflict/keybinding-vim.js')) -ace.config.setModuleUrl('ace/mode/abap', require('file-loader!./src-noconflict/mode-abap.js')) -ace.config.setModuleUrl('ace/mode/abc', require('file-loader!./src-noconflict/mode-abc.js')) -ace.config.setModuleUrl('ace/mode/actionscript', require('file-loader!./src-noconflict/mode-actionscript.js')) -ace.config.setModuleUrl('ace/mode/ada', require('file-loader!./src-noconflict/mode-ada.js')) -ace.config.setModuleUrl('ace/mode/apache_conf', require('file-loader!./src-noconflict/mode-apache_conf.js')) -ace.config.setModuleUrl('ace/mode/apex', require('file-loader!./src-noconflict/mode-apex.js')) -ace.config.setModuleUrl('ace/mode/applescript', require('file-loader!./src-noconflict/mode-applescript.js')) -ace.config.setModuleUrl('ace/mode/aql', require('file-loader!./src-noconflict/mode-aql.js')) -ace.config.setModuleUrl('ace/mode/asciidoc', require('file-loader!./src-noconflict/mode-asciidoc.js')) -ace.config.setModuleUrl('ace/mode/asl', require('file-loader!./src-noconflict/mode-asl.js')) -ace.config.setModuleUrl('ace/mode/assembly_x86', require('file-loader!./src-noconflict/mode-assembly_x86.js')) -ace.config.setModuleUrl('ace/mode/autohotkey', require('file-loader!./src-noconflict/mode-autohotkey.js')) -ace.config.setModuleUrl('ace/mode/batchfile', require('file-loader!./src-noconflict/mode-batchfile.js')) -ace.config.setModuleUrl('ace/mode/bro', require('file-loader!./src-noconflict/mode-bro.js')) -ace.config.setModuleUrl('ace/mode/c9search', require('file-loader!./src-noconflict/mode-c9search.js')) -ace.config.setModuleUrl('ace/mode/cirru', require('file-loader!./src-noconflict/mode-cirru.js')) -ace.config.setModuleUrl('ace/mode/clojure', require('file-loader!./src-noconflict/mode-clojure.js')) -ace.config.setModuleUrl('ace/mode/cobol', require('file-loader!./src-noconflict/mode-cobol.js')) -ace.config.setModuleUrl('ace/mode/coffee', require('file-loader!./src-noconflict/mode-coffee.js')) -ace.config.setModuleUrl('ace/mode/coldfusion', require('file-loader!./src-noconflict/mode-coldfusion.js')) -ace.config.setModuleUrl('ace/mode/crystal', require('file-loader!./src-noconflict/mode-crystal.js')) -ace.config.setModuleUrl('ace/mode/csharp', require('file-loader!./src-noconflict/mode-csharp.js')) -ace.config.setModuleUrl('ace/mode/csound_document', require('file-loader!./src-noconflict/mode-csound_document.js')) -ace.config.setModuleUrl('ace/mode/csound_orchestra', require('file-loader!./src-noconflict/mode-csound_orchestra.js')) -ace.config.setModuleUrl('ace/mode/csound_score', require('file-loader!./src-noconflict/mode-csound_score.js')) -ace.config.setModuleUrl('ace/mode/csp', require('file-loader!./src-noconflict/mode-csp.js')) -ace.config.setModuleUrl('ace/mode/css', require('file-loader!./src-noconflict/mode-css.js')) -ace.config.setModuleUrl('ace/mode/curly', require('file-loader!./src-noconflict/mode-curly.js')) -ace.config.setModuleUrl('ace/mode/c_cpp', require('file-loader!./src-noconflict/mode-c_cpp.js')) -ace.config.setModuleUrl('ace/mode/d', require('file-loader!./src-noconflict/mode-d.js')) -ace.config.setModuleUrl('ace/mode/dart', require('file-loader!./src-noconflict/mode-dart.js')) -ace.config.setModuleUrl('ace/mode/diff', require('file-loader!./src-noconflict/mode-diff.js')) -ace.config.setModuleUrl('ace/mode/django', require('file-loader!./src-noconflict/mode-django.js')) -ace.config.setModuleUrl('ace/mode/dockerfile', require('file-loader!./src-noconflict/mode-dockerfile.js')) -ace.config.setModuleUrl('ace/mode/dot', require('file-loader!./src-noconflict/mode-dot.js')) -ace.config.setModuleUrl('ace/mode/drools', require('file-loader!./src-noconflict/mode-drools.js')) -ace.config.setModuleUrl('ace/mode/edifact', require('file-loader!./src-noconflict/mode-edifact.js')) -ace.config.setModuleUrl('ace/mode/eiffel', require('file-loader!./src-noconflict/mode-eiffel.js')) -ace.config.setModuleUrl('ace/mode/ejs', require('file-loader!./src-noconflict/mode-ejs.js')) -ace.config.setModuleUrl('ace/mode/elixir', require('file-loader!./src-noconflict/mode-elixir.js')) -ace.config.setModuleUrl('ace/mode/elm', require('file-loader!./src-noconflict/mode-elm.js')) -ace.config.setModuleUrl('ace/mode/erlang', require('file-loader!./src-noconflict/mode-erlang.js')) -ace.config.setModuleUrl('ace/mode/forth', require('file-loader!./src-noconflict/mode-forth.js')) -ace.config.setModuleUrl('ace/mode/fortran', require('file-loader!./src-noconflict/mode-fortran.js')) -ace.config.setModuleUrl('ace/mode/fsharp', require('file-loader!./src-noconflict/mode-fsharp.js')) -ace.config.setModuleUrl('ace/mode/fsl', require('file-loader!./src-noconflict/mode-fsl.js')) -ace.config.setModuleUrl('ace/mode/ftl', require('file-loader!./src-noconflict/mode-ftl.js')) -ace.config.setModuleUrl('ace/mode/gcode', require('file-loader!./src-noconflict/mode-gcode.js')) -ace.config.setModuleUrl('ace/mode/gherkin', require('file-loader!./src-noconflict/mode-gherkin.js')) -ace.config.setModuleUrl('ace/mode/gitignore', require('file-loader!./src-noconflict/mode-gitignore.js')) -ace.config.setModuleUrl('ace/mode/glsl', require('file-loader!./src-noconflict/mode-glsl.js')) -ace.config.setModuleUrl('ace/mode/gobstones', require('file-loader!./src-noconflict/mode-gobstones.js')) -ace.config.setModuleUrl('ace/mode/golang', require('file-loader!./src-noconflict/mode-golang.js')) -ace.config.setModuleUrl('ace/mode/graphqlschema', require('file-loader!./src-noconflict/mode-graphqlschema.js')) -ace.config.setModuleUrl('ace/mode/groovy', require('file-loader!./src-noconflict/mode-groovy.js')) -ace.config.setModuleUrl('ace/mode/haml', require('file-loader!./src-noconflict/mode-haml.js')) -ace.config.setModuleUrl('ace/mode/handlebars', require('file-loader!./src-noconflict/mode-handlebars.js')) -ace.config.setModuleUrl('ace/mode/haskell', require('file-loader!./src-noconflict/mode-haskell.js')) -ace.config.setModuleUrl('ace/mode/haskell_cabal', require('file-loader!./src-noconflict/mode-haskell_cabal.js')) -ace.config.setModuleUrl('ace/mode/haxe', require('file-loader!./src-noconflict/mode-haxe.js')) -ace.config.setModuleUrl('ace/mode/hjson', require('file-loader!./src-noconflict/mode-hjson.js')) -ace.config.setModuleUrl('ace/mode/html', require('file-loader!./src-noconflict/mode-html.js')) -ace.config.setModuleUrl('ace/mode/html_elixir', require('file-loader!./src-noconflict/mode-html_elixir.js')) -ace.config.setModuleUrl('ace/mode/html_ruby', require('file-loader!./src-noconflict/mode-html_ruby.js')) -ace.config.setModuleUrl('ace/mode/ini', require('file-loader!./src-noconflict/mode-ini.js')) -ace.config.setModuleUrl('ace/mode/io', require('file-loader!./src-noconflict/mode-io.js')) -ace.config.setModuleUrl('ace/mode/jack', require('file-loader!./src-noconflict/mode-jack.js')) -ace.config.setModuleUrl('ace/mode/jade', require('file-loader!./src-noconflict/mode-jade.js')) -ace.config.setModuleUrl('ace/mode/java', require('file-loader!./src-noconflict/mode-java.js')) -ace.config.setModuleUrl('ace/mode/javascript', require('file-loader!./src-noconflict/mode-javascript.js')) -ace.config.setModuleUrl('ace/mode/json', require('file-loader!./src-noconflict/mode-json.js')) -ace.config.setModuleUrl('ace/mode/jsoniq', require('file-loader!./src-noconflict/mode-jsoniq.js')) -ace.config.setModuleUrl('ace/mode/jsp', require('file-loader!./src-noconflict/mode-jsp.js')) -ace.config.setModuleUrl('ace/mode/jssm', require('file-loader!./src-noconflict/mode-jssm.js')) -ace.config.setModuleUrl('ace/mode/jsx', require('file-loader!./src-noconflict/mode-jsx.js')) -ace.config.setModuleUrl('ace/mode/julia', require('file-loader!./src-noconflict/mode-julia.js')) -ace.config.setModuleUrl('ace/mode/kotlin', require('file-loader!./src-noconflict/mode-kotlin.js')) -ace.config.setModuleUrl('ace/mode/latex', require('file-loader!./src-noconflict/mode-latex.js')) -ace.config.setModuleUrl('ace/mode/less', require('file-loader!./src-noconflict/mode-less.js')) -ace.config.setModuleUrl('ace/mode/liquid', require('file-loader!./src-noconflict/mode-liquid.js')) -ace.config.setModuleUrl('ace/mode/lisp', require('file-loader!./src-noconflict/mode-lisp.js')) -ace.config.setModuleUrl('ace/mode/livescript', require('file-loader!./src-noconflict/mode-livescript.js')) -ace.config.setModuleUrl('ace/mode/logiql', require('file-loader!./src-noconflict/mode-logiql.js')) -ace.config.setModuleUrl('ace/mode/logtalk', require('file-loader!./src-noconflict/mode-logtalk.js')) -ace.config.setModuleUrl('ace/mode/lsl', require('file-loader!./src-noconflict/mode-lsl.js')) -ace.config.setModuleUrl('ace/mode/lua', require('file-loader!./src-noconflict/mode-lua.js')) -ace.config.setModuleUrl('ace/mode/luapage', require('file-loader!./src-noconflict/mode-luapage.js')) -ace.config.setModuleUrl('ace/mode/lucene', require('file-loader!./src-noconflict/mode-lucene.js')) -ace.config.setModuleUrl('ace/mode/makefile', require('file-loader!./src-noconflict/mode-makefile.js')) -ace.config.setModuleUrl('ace/mode/markdown', require('file-loader!./src-noconflict/mode-markdown.js')) -ace.config.setModuleUrl('ace/mode/mask', require('file-loader!./src-noconflict/mode-mask.js')) -ace.config.setModuleUrl('ace/mode/matlab', require('file-loader!./src-noconflict/mode-matlab.js')) -ace.config.setModuleUrl('ace/mode/maze', require('file-loader!./src-noconflict/mode-maze.js')) -ace.config.setModuleUrl('ace/mode/mel', require('file-loader!./src-noconflict/mode-mel.js')) -ace.config.setModuleUrl('ace/mode/mixal', require('file-loader!./src-noconflict/mode-mixal.js')) -ace.config.setModuleUrl('ace/mode/mushcode', require('file-loader!./src-noconflict/mode-mushcode.js')) -ace.config.setModuleUrl('ace/mode/mysql', require('file-loader!./src-noconflict/mode-mysql.js')) -ace.config.setModuleUrl('ace/mode/nginx', require('file-loader!./src-noconflict/mode-nginx.js')) -ace.config.setModuleUrl('ace/mode/nim', require('file-loader!./src-noconflict/mode-nim.js')) -ace.config.setModuleUrl('ace/mode/nix', require('file-loader!./src-noconflict/mode-nix.js')) -ace.config.setModuleUrl('ace/mode/nsis', require('file-loader!./src-noconflict/mode-nsis.js')) -ace.config.setModuleUrl('ace/mode/objectivec', require('file-loader!./src-noconflict/mode-objectivec.js')) -ace.config.setModuleUrl('ace/mode/ocaml', require('file-loader!./src-noconflict/mode-ocaml.js')) -ace.config.setModuleUrl('ace/mode/pascal', require('file-loader!./src-noconflict/mode-pascal.js')) -ace.config.setModuleUrl('ace/mode/perl', require('file-loader!./src-noconflict/mode-perl.js')) -ace.config.setModuleUrl('ace/mode/perl6', require('file-loader!./src-noconflict/mode-perl6.js')) -ace.config.setModuleUrl('ace/mode/pgsql', require('file-loader!./src-noconflict/mode-pgsql.js')) -ace.config.setModuleUrl('ace/mode/php', require('file-loader!./src-noconflict/mode-php.js')) -ace.config.setModuleUrl('ace/mode/php_laravel_blade', require('file-loader!./src-noconflict/mode-php_laravel_blade.js')) -ace.config.setModuleUrl('ace/mode/pig', require('file-loader!./src-noconflict/mode-pig.js')) -ace.config.setModuleUrl('ace/mode/plain_text', require('file-loader!./src-noconflict/mode-plain_text.js')) -ace.config.setModuleUrl('ace/mode/powershell', require('file-loader!./src-noconflict/mode-powershell.js')) -ace.config.setModuleUrl('ace/mode/praat', require('file-loader!./src-noconflict/mode-praat.js')) -ace.config.setModuleUrl('ace/mode/prolog', require('file-loader!./src-noconflict/mode-prolog.js')) -ace.config.setModuleUrl('ace/mode/properties', require('file-loader!./src-noconflict/mode-properties.js')) -ace.config.setModuleUrl('ace/mode/protobuf', require('file-loader!./src-noconflict/mode-protobuf.js')) -ace.config.setModuleUrl('ace/mode/puppet', require('file-loader!./src-noconflict/mode-puppet.js')) -ace.config.setModuleUrl('ace/mode/python', require('file-loader!./src-noconflict/mode-python.js')) -ace.config.setModuleUrl('ace/mode/r', require('file-loader!./src-noconflict/mode-r.js')) -ace.config.setModuleUrl('ace/mode/razor', require('file-loader!./src-noconflict/mode-razor.js')) -ace.config.setModuleUrl('ace/mode/rdoc', require('file-loader!./src-noconflict/mode-rdoc.js')) -ace.config.setModuleUrl('ace/mode/red', require('file-loader!./src-noconflict/mode-red.js')) -ace.config.setModuleUrl('ace/mode/redshift', require('file-loader!./src-noconflict/mode-redshift.js')) -ace.config.setModuleUrl('ace/mode/rhtml', require('file-loader!./src-noconflict/mode-rhtml.js')) -ace.config.setModuleUrl('ace/mode/rst', require('file-loader!./src-noconflict/mode-rst.js')) -ace.config.setModuleUrl('ace/mode/ruby', require('file-loader!./src-noconflict/mode-ruby.js')) -ace.config.setModuleUrl('ace/mode/rust', require('file-loader!./src-noconflict/mode-rust.js')) -ace.config.setModuleUrl('ace/mode/sass', require('file-loader!./src-noconflict/mode-sass.js')) -ace.config.setModuleUrl('ace/mode/scad', require('file-loader!./src-noconflict/mode-scad.js')) -ace.config.setModuleUrl('ace/mode/scala', require('file-loader!./src-noconflict/mode-scala.js')) -ace.config.setModuleUrl('ace/mode/scheme', require('file-loader!./src-noconflict/mode-scheme.js')) -ace.config.setModuleUrl('ace/mode/scss', require('file-loader!./src-noconflict/mode-scss.js')) -ace.config.setModuleUrl('ace/mode/sh', require('file-loader!./src-noconflict/mode-sh.js')) -ace.config.setModuleUrl('ace/mode/sjs', require('file-loader!./src-noconflict/mode-sjs.js')) -ace.config.setModuleUrl('ace/mode/slim', require('file-loader!./src-noconflict/mode-slim.js')) -ace.config.setModuleUrl('ace/mode/smarty', require('file-loader!./src-noconflict/mode-smarty.js')) -ace.config.setModuleUrl('ace/mode/snippets', require('file-loader!./src-noconflict/mode-snippets.js')) -ace.config.setModuleUrl('ace/mode/soy_template', require('file-loader!./src-noconflict/mode-soy_template.js')) -ace.config.setModuleUrl('ace/mode/space', require('file-loader!./src-noconflict/mode-space.js')) -ace.config.setModuleUrl('ace/mode/sparql', require('file-loader!./src-noconflict/mode-sparql.js')) -ace.config.setModuleUrl('ace/mode/sql', require('file-loader!./src-noconflict/mode-sql.js')) -ace.config.setModuleUrl('ace/mode/sqlserver', require('file-loader!./src-noconflict/mode-sqlserver.js')) -ace.config.setModuleUrl('ace/mode/stylus', require('file-loader!./src-noconflict/mode-stylus.js')) -ace.config.setModuleUrl('ace/mode/svg', require('file-loader!./src-noconflict/mode-svg.js')) -ace.config.setModuleUrl('ace/mode/swift', require('file-loader!./src-noconflict/mode-swift.js')) -ace.config.setModuleUrl('ace/mode/tcl', require('file-loader!./src-noconflict/mode-tcl.js')) -ace.config.setModuleUrl('ace/mode/terraform', require('file-loader!./src-noconflict/mode-terraform.js')) -ace.config.setModuleUrl('ace/mode/tex', require('file-loader!./src-noconflict/mode-tex.js')) -ace.config.setModuleUrl('ace/mode/text', require('file-loader!./src-noconflict/mode-text.js')) -ace.config.setModuleUrl('ace/mode/textile', require('file-loader!./src-noconflict/mode-textile.js')) -ace.config.setModuleUrl('ace/mode/toml', require('file-loader!./src-noconflict/mode-toml.js')) -ace.config.setModuleUrl('ace/mode/tsx', require('file-loader!./src-noconflict/mode-tsx.js')) -ace.config.setModuleUrl('ace/mode/turtle', require('file-loader!./src-noconflict/mode-turtle.js')) -ace.config.setModuleUrl('ace/mode/twig', require('file-loader!./src-noconflict/mode-twig.js')) -ace.config.setModuleUrl('ace/mode/typescript', require('file-loader!./src-noconflict/mode-typescript.js')) -ace.config.setModuleUrl('ace/mode/vala', require('file-loader!./src-noconflict/mode-vala.js')) -ace.config.setModuleUrl('ace/mode/vbscript', require('file-loader!./src-noconflict/mode-vbscript.js')) -ace.config.setModuleUrl('ace/mode/velocity', require('file-loader!./src-noconflict/mode-velocity.js')) -ace.config.setModuleUrl('ace/mode/verilog', require('file-loader!./src-noconflict/mode-verilog.js')) -ace.config.setModuleUrl('ace/mode/vhdl', require('file-loader!./src-noconflict/mode-vhdl.js')) -ace.config.setModuleUrl('ace/mode/visualforce', require('file-loader!./src-noconflict/mode-visualforce.js')) -ace.config.setModuleUrl('ace/mode/wollok', require('file-loader!./src-noconflict/mode-wollok.js')) -ace.config.setModuleUrl('ace/mode/xml', require('file-loader!./src-noconflict/mode-xml.js')) -ace.config.setModuleUrl('ace/mode/xquery', require('file-loader!./src-noconflict/mode-xquery.js')) -ace.config.setModuleUrl('ace/mode/yaml', require('file-loader!./src-noconflict/mode-yaml.js')) -ace.config.setModuleUrl('ace/mode/zeek', require('file-loader!./src-noconflict/mode-zeek.js')) +ace.config.setModuleUrl('ace/ext/beautify', require('file-loader?esModule=false!./src-noconflict/ext-beautify.js')) +ace.config.setModuleUrl('ace/ext/elastic_tabstops_lite', require('file-loader?esModule=false!./src-noconflict/ext-elastic_tabstops_lite.js')) +ace.config.setModuleUrl('ace/ext/emmet', require('file-loader?esModule=false!./src-noconflict/ext-emmet.js')) +ace.config.setModuleUrl('ace/ext/error_marker', require('file-loader?esModule=false!./src-noconflict/ext-error_marker.js')) +ace.config.setModuleUrl('ace/ext/keyboard_menu', require('file-loader?esModule=false!./src-noconflict/ext-keybinding_menu.js')) +ace.config.setModuleUrl('ace/ext/language_tools', require('file-loader?esModule=false!./src-noconflict/ext-language_tools.js')) +ace.config.setModuleUrl('ace/ext/linking', require('file-loader?esModule=false!./src-noconflict/ext-linking.js')) +ace.config.setModuleUrl('ace/ext/modelist', require('file-loader?esModule=false!./src-noconflict/ext-modelist.js')) +ace.config.setModuleUrl('ace/ext/options', require('file-loader?esModule=false!./src-noconflict/ext-options.js')) +ace.config.setModuleUrl('ace/ext/prompt', require('file-loader?esModule=false!./src-noconflict/ext-prompt.js')) +ace.config.setModuleUrl('ace/ext/rtl', require('file-loader?esModule=false!./src-noconflict/ext-rtl.js')) +ace.config.setModuleUrl('ace/ext/searchbox', require('file-loader?esModule=false!./src-noconflict/ext-searchbox.js')) +ace.config.setModuleUrl('ace/ext/settings_menu', require('file-loader?esModule=false!./src-noconflict/ext-settings_menu.js')) +ace.config.setModuleUrl('ace/ext/spellcheck', require('file-loader?esModule=false!./src-noconflict/ext-spellcheck.js')) +ace.config.setModuleUrl('ace/ext/split', require('file-loader?esModule=false!./src-noconflict/ext-split.js')) +ace.config.setModuleUrl('ace/ext/static_highlight', require('file-loader?esModule=false!./src-noconflict/ext-static_highlight.js')) +ace.config.setModuleUrl('ace/ext/statusbar', require('file-loader?esModule=false!./src-noconflict/ext-statusbar.js')) +ace.config.setModuleUrl('ace/ext/textarea', require('file-loader?esModule=false!./src-noconflict/ext-textarea.js')) +ace.config.setModuleUrl('ace/ext/themelist', require('file-loader?esModule=false!./src-noconflict/ext-themelist.js')) +ace.config.setModuleUrl('ace/ext/whitespace', require('file-loader?esModule=false!./src-noconflict/ext-whitespace.js')) +ace.config.setModuleUrl('ace/keyboard/emacs', require('file-loader?esModule=false!./src-noconflict/keybinding-emacs.js')) +ace.config.setModuleUrl('ace/keyboard/sublime', require('file-loader?esModule=false!./src-noconflict/keybinding-sublime.js')) +ace.config.setModuleUrl('ace/keyboard/vim', require('file-loader?esModule=false!./src-noconflict/keybinding-vim.js')) +ace.config.setModuleUrl('ace/mode/abap', require('file-loader?esModule=false!./src-noconflict/mode-abap.js')) +ace.config.setModuleUrl('ace/mode/abc', require('file-loader?esModule=false!./src-noconflict/mode-abc.js')) +ace.config.setModuleUrl('ace/mode/actionscript', require('file-loader?esModule=false!./src-noconflict/mode-actionscript.js')) +ace.config.setModuleUrl('ace/mode/ada', require('file-loader?esModule=false!./src-noconflict/mode-ada.js')) +ace.config.setModuleUrl('ace/mode/apache_conf', require('file-loader?esModule=false!./src-noconflict/mode-apache_conf.js')) +ace.config.setModuleUrl('ace/mode/apex', require('file-loader?esModule=false!./src-noconflict/mode-apex.js')) +ace.config.setModuleUrl('ace/mode/applescript', require('file-loader?esModule=false!./src-noconflict/mode-applescript.js')) +ace.config.setModuleUrl('ace/mode/aql', require('file-loader?esModule=false!./src-noconflict/mode-aql.js')) +ace.config.setModuleUrl('ace/mode/asciidoc', require('file-loader?esModule=false!./src-noconflict/mode-asciidoc.js')) +ace.config.setModuleUrl('ace/mode/asl', require('file-loader?esModule=false!./src-noconflict/mode-asl.js')) +ace.config.setModuleUrl('ace/mode/assembly_x86', require('file-loader?esModule=false!./src-noconflict/mode-assembly_x86.js')) +ace.config.setModuleUrl('ace/mode/autohotkey', require('file-loader?esModule=false!./src-noconflict/mode-autohotkey.js')) +ace.config.setModuleUrl('ace/mode/batchfile', require('file-loader?esModule=false!./src-noconflict/mode-batchfile.js')) +ace.config.setModuleUrl('ace/mode/bro', require('file-loader?esModule=false!./src-noconflict/mode-bro.js')) +ace.config.setModuleUrl('ace/mode/c9search', require('file-loader?esModule=false!./src-noconflict/mode-c9search.js')) +ace.config.setModuleUrl('ace/mode/cirru', require('file-loader?esModule=false!./src-noconflict/mode-cirru.js')) +ace.config.setModuleUrl('ace/mode/clojure', require('file-loader?esModule=false!./src-noconflict/mode-clojure.js')) +ace.config.setModuleUrl('ace/mode/cobol', require('file-loader?esModule=false!./src-noconflict/mode-cobol.js')) +ace.config.setModuleUrl('ace/mode/coffee', require('file-loader?esModule=false!./src-noconflict/mode-coffee.js')) +ace.config.setModuleUrl('ace/mode/coldfusion', require('file-loader?esModule=false!./src-noconflict/mode-coldfusion.js')) +ace.config.setModuleUrl('ace/mode/crystal', require('file-loader?esModule=false!./src-noconflict/mode-crystal.js')) +ace.config.setModuleUrl('ace/mode/csharp', require('file-loader?esModule=false!./src-noconflict/mode-csharp.js')) +ace.config.setModuleUrl('ace/mode/csound_document', require('file-loader?esModule=false!./src-noconflict/mode-csound_document.js')) +ace.config.setModuleUrl('ace/mode/csound_orchestra', require('file-loader?esModule=false!./src-noconflict/mode-csound_orchestra.js')) +ace.config.setModuleUrl('ace/mode/csound_score', require('file-loader?esModule=false!./src-noconflict/mode-csound_score.js')) +ace.config.setModuleUrl('ace/mode/csp', require('file-loader?esModule=false!./src-noconflict/mode-csp.js')) +ace.config.setModuleUrl('ace/mode/css', require('file-loader?esModule=false!./src-noconflict/mode-css.js')) +ace.config.setModuleUrl('ace/mode/curly', require('file-loader?esModule=false!./src-noconflict/mode-curly.js')) +ace.config.setModuleUrl('ace/mode/c_cpp', require('file-loader?esModule=false!./src-noconflict/mode-c_cpp.js')) +ace.config.setModuleUrl('ace/mode/d', require('file-loader?esModule=false!./src-noconflict/mode-d.js')) +ace.config.setModuleUrl('ace/mode/dart', require('file-loader?esModule=false!./src-noconflict/mode-dart.js')) +ace.config.setModuleUrl('ace/mode/diff', require('file-loader?esModule=false!./src-noconflict/mode-diff.js')) +ace.config.setModuleUrl('ace/mode/django', require('file-loader?esModule=false!./src-noconflict/mode-django.js')) +ace.config.setModuleUrl('ace/mode/dockerfile', require('file-loader?esModule=false!./src-noconflict/mode-dockerfile.js')) +ace.config.setModuleUrl('ace/mode/dot', require('file-loader?esModule=false!./src-noconflict/mode-dot.js')) +ace.config.setModuleUrl('ace/mode/drools', require('file-loader?esModule=false!./src-noconflict/mode-drools.js')) +ace.config.setModuleUrl('ace/mode/edifact', require('file-loader?esModule=false!./src-noconflict/mode-edifact.js')) +ace.config.setModuleUrl('ace/mode/eiffel', require('file-loader?esModule=false!./src-noconflict/mode-eiffel.js')) +ace.config.setModuleUrl('ace/mode/ejs', require('file-loader?esModule=false!./src-noconflict/mode-ejs.js')) +ace.config.setModuleUrl('ace/mode/elixir', require('file-loader?esModule=false!./src-noconflict/mode-elixir.js')) +ace.config.setModuleUrl('ace/mode/elm', require('file-loader?esModule=false!./src-noconflict/mode-elm.js')) +ace.config.setModuleUrl('ace/mode/erlang', require('file-loader?esModule=false!./src-noconflict/mode-erlang.js')) +ace.config.setModuleUrl('ace/mode/forth', require('file-loader?esModule=false!./src-noconflict/mode-forth.js')) +ace.config.setModuleUrl('ace/mode/fortran', require('file-loader?esModule=false!./src-noconflict/mode-fortran.js')) +ace.config.setModuleUrl('ace/mode/fsharp', require('file-loader?esModule=false!./src-noconflict/mode-fsharp.js')) +ace.config.setModuleUrl('ace/mode/fsl', require('file-loader?esModule=false!./src-noconflict/mode-fsl.js')) +ace.config.setModuleUrl('ace/mode/ftl', require('file-loader?esModule=false!./src-noconflict/mode-ftl.js')) +ace.config.setModuleUrl('ace/mode/gcode', require('file-loader?esModule=false!./src-noconflict/mode-gcode.js')) +ace.config.setModuleUrl('ace/mode/gherkin', require('file-loader?esModule=false!./src-noconflict/mode-gherkin.js')) +ace.config.setModuleUrl('ace/mode/gitignore', require('file-loader?esModule=false!./src-noconflict/mode-gitignore.js')) +ace.config.setModuleUrl('ace/mode/glsl', require('file-loader?esModule=false!./src-noconflict/mode-glsl.js')) +ace.config.setModuleUrl('ace/mode/gobstones', require('file-loader?esModule=false!./src-noconflict/mode-gobstones.js')) +ace.config.setModuleUrl('ace/mode/golang', require('file-loader?esModule=false!./src-noconflict/mode-golang.js')) +ace.config.setModuleUrl('ace/mode/graphqlschema', require('file-loader?esModule=false!./src-noconflict/mode-graphqlschema.js')) +ace.config.setModuleUrl('ace/mode/groovy', require('file-loader?esModule=false!./src-noconflict/mode-groovy.js')) +ace.config.setModuleUrl('ace/mode/haml', require('file-loader?esModule=false!./src-noconflict/mode-haml.js')) +ace.config.setModuleUrl('ace/mode/handlebars', require('file-loader?esModule=false!./src-noconflict/mode-handlebars.js')) +ace.config.setModuleUrl('ace/mode/haskell', require('file-loader?esModule=false!./src-noconflict/mode-haskell.js')) +ace.config.setModuleUrl('ace/mode/haskell_cabal', require('file-loader?esModule=false!./src-noconflict/mode-haskell_cabal.js')) +ace.config.setModuleUrl('ace/mode/haxe', require('file-loader?esModule=false!./src-noconflict/mode-haxe.js')) +ace.config.setModuleUrl('ace/mode/hjson', require('file-loader?esModule=false!./src-noconflict/mode-hjson.js')) +ace.config.setModuleUrl('ace/mode/html', require('file-loader?esModule=false!./src-noconflict/mode-html.js')) +ace.config.setModuleUrl('ace/mode/html_elixir', require('file-loader?esModule=false!./src-noconflict/mode-html_elixir.js')) +ace.config.setModuleUrl('ace/mode/html_ruby', require('file-loader?esModule=false!./src-noconflict/mode-html_ruby.js')) +ace.config.setModuleUrl('ace/mode/ini', require('file-loader?esModule=false!./src-noconflict/mode-ini.js')) +ace.config.setModuleUrl('ace/mode/io', require('file-loader?esModule=false!./src-noconflict/mode-io.js')) +ace.config.setModuleUrl('ace/mode/jack', require('file-loader?esModule=false!./src-noconflict/mode-jack.js')) +ace.config.setModuleUrl('ace/mode/jade', require('file-loader?esModule=false!./src-noconflict/mode-jade.js')) +ace.config.setModuleUrl('ace/mode/java', require('file-loader?esModule=false!./src-noconflict/mode-java.js')) +ace.config.setModuleUrl('ace/mode/javascript', require('file-loader?esModule=false!./src-noconflict/mode-javascript.js')) +ace.config.setModuleUrl('ace/mode/json', require('file-loader?esModule=false!./src-noconflict/mode-json.js')) +ace.config.setModuleUrl('ace/mode/jsoniq', require('file-loader?esModule=false!./src-noconflict/mode-jsoniq.js')) +ace.config.setModuleUrl('ace/mode/jsp', require('file-loader?esModule=false!./src-noconflict/mode-jsp.js')) +ace.config.setModuleUrl('ace/mode/jssm', require('file-loader?esModule=false!./src-noconflict/mode-jssm.js')) +ace.config.setModuleUrl('ace/mode/jsx', require('file-loader?esModule=false!./src-noconflict/mode-jsx.js')) +ace.config.setModuleUrl('ace/mode/julia', require('file-loader?esModule=false!./src-noconflict/mode-julia.js')) +ace.config.setModuleUrl('ace/mode/kotlin', require('file-loader?esModule=false!./src-noconflict/mode-kotlin.js')) +ace.config.setModuleUrl('ace/mode/latex', require('file-loader?esModule=false!./src-noconflict/mode-latex.js')) +ace.config.setModuleUrl('ace/mode/less', require('file-loader?esModule=false!./src-noconflict/mode-less.js')) +ace.config.setModuleUrl('ace/mode/liquid', require('file-loader?esModule=false!./src-noconflict/mode-liquid.js')) +ace.config.setModuleUrl('ace/mode/lisp', require('file-loader?esModule=false!./src-noconflict/mode-lisp.js')) +ace.config.setModuleUrl('ace/mode/livescript', require('file-loader?esModule=false!./src-noconflict/mode-livescript.js')) +ace.config.setModuleUrl('ace/mode/logiql', require('file-loader?esModule=false!./src-noconflict/mode-logiql.js')) +ace.config.setModuleUrl('ace/mode/logtalk', require('file-loader?esModule=false!./src-noconflict/mode-logtalk.js')) +ace.config.setModuleUrl('ace/mode/lsl', require('file-loader?esModule=false!./src-noconflict/mode-lsl.js')) +ace.config.setModuleUrl('ace/mode/lua', require('file-loader?esModule=false!./src-noconflict/mode-lua.js')) +ace.config.setModuleUrl('ace/mode/luapage', require('file-loader?esModule=false!./src-noconflict/mode-luapage.js')) +ace.config.setModuleUrl('ace/mode/lucene', require('file-loader?esModule=false!./src-noconflict/mode-lucene.js')) +ace.config.setModuleUrl('ace/mode/makefile', require('file-loader?esModule=false!./src-noconflict/mode-makefile.js')) +ace.config.setModuleUrl('ace/mode/markdown', require('file-loader?esModule=false!./src-noconflict/mode-markdown.js')) +ace.config.setModuleUrl('ace/mode/mask', require('file-loader?esModule=false!./src-noconflict/mode-mask.js')) +ace.config.setModuleUrl('ace/mode/matlab', require('file-loader?esModule=false!./src-noconflict/mode-matlab.js')) +ace.config.setModuleUrl('ace/mode/maze', require('file-loader?esModule=false!./src-noconflict/mode-maze.js')) +ace.config.setModuleUrl('ace/mode/mel', require('file-loader?esModule=false!./src-noconflict/mode-mel.js')) +ace.config.setModuleUrl('ace/mode/mixal', require('file-loader?esModule=false!./src-noconflict/mode-mixal.js')) +ace.config.setModuleUrl('ace/mode/mushcode', require('file-loader?esModule=false!./src-noconflict/mode-mushcode.js')) +ace.config.setModuleUrl('ace/mode/mysql', require('file-loader?esModule=false!./src-noconflict/mode-mysql.js')) +ace.config.setModuleUrl('ace/mode/nginx', require('file-loader?esModule=false!./src-noconflict/mode-nginx.js')) +ace.config.setModuleUrl('ace/mode/nim', require('file-loader?esModule=false!./src-noconflict/mode-nim.js')) +ace.config.setModuleUrl('ace/mode/nix', require('file-loader?esModule=false!./src-noconflict/mode-nix.js')) +ace.config.setModuleUrl('ace/mode/nsis', require('file-loader?esModule=false!./src-noconflict/mode-nsis.js')) +ace.config.setModuleUrl('ace/mode/objectivec', require('file-loader?esModule=false!./src-noconflict/mode-objectivec.js')) +ace.config.setModuleUrl('ace/mode/ocaml', require('file-loader?esModule=false!./src-noconflict/mode-ocaml.js')) +ace.config.setModuleUrl('ace/mode/pascal', require('file-loader?esModule=false!./src-noconflict/mode-pascal.js')) +ace.config.setModuleUrl('ace/mode/perl', require('file-loader?esModule=false!./src-noconflict/mode-perl.js')) +ace.config.setModuleUrl('ace/mode/perl6', require('file-loader?esModule=false!./src-noconflict/mode-perl6.js')) +ace.config.setModuleUrl('ace/mode/pgsql', require('file-loader?esModule=false!./src-noconflict/mode-pgsql.js')) +ace.config.setModuleUrl('ace/mode/php', require('file-loader?esModule=false!./src-noconflict/mode-php.js')) +ace.config.setModuleUrl('ace/mode/php_laravel_blade', require('file-loader?esModule=false!./src-noconflict/mode-php_laravel_blade.js')) +ace.config.setModuleUrl('ace/mode/pig', require('file-loader?esModule=false!./src-noconflict/mode-pig.js')) +ace.config.setModuleUrl('ace/mode/plain_text', require('file-loader?esModule=false!./src-noconflict/mode-plain_text.js')) +ace.config.setModuleUrl('ace/mode/powershell', require('file-loader?esModule=false!./src-noconflict/mode-powershell.js')) +ace.config.setModuleUrl('ace/mode/praat', require('file-loader?esModule=false!./src-noconflict/mode-praat.js')) +ace.config.setModuleUrl('ace/mode/prolog', require('file-loader?esModule=false!./src-noconflict/mode-prolog.js')) +ace.config.setModuleUrl('ace/mode/properties', require('file-loader?esModule=false!./src-noconflict/mode-properties.js')) +ace.config.setModuleUrl('ace/mode/protobuf', require('file-loader?esModule=false!./src-noconflict/mode-protobuf.js')) +ace.config.setModuleUrl('ace/mode/puppet', require('file-loader?esModule=false!./src-noconflict/mode-puppet.js')) +ace.config.setModuleUrl('ace/mode/python', require('file-loader?esModule=false!./src-noconflict/mode-python.js')) +ace.config.setModuleUrl('ace/mode/r', require('file-loader?esModule=false!./src-noconflict/mode-r.js')) +ace.config.setModuleUrl('ace/mode/razor', require('file-loader?esModule=false!./src-noconflict/mode-razor.js')) +ace.config.setModuleUrl('ace/mode/rdoc', require('file-loader?esModule=false!./src-noconflict/mode-rdoc.js')) +ace.config.setModuleUrl('ace/mode/red', require('file-loader?esModule=false!./src-noconflict/mode-red.js')) +ace.config.setModuleUrl('ace/mode/redshift', require('file-loader?esModule=false!./src-noconflict/mode-redshift.js')) +ace.config.setModuleUrl('ace/mode/rhtml', require('file-loader?esModule=false!./src-noconflict/mode-rhtml.js')) +ace.config.setModuleUrl('ace/mode/rst', require('file-loader?esModule=false!./src-noconflict/mode-rst.js')) +ace.config.setModuleUrl('ace/mode/ruby', require('file-loader?esModule=false!./src-noconflict/mode-ruby.js')) +ace.config.setModuleUrl('ace/mode/rust', require('file-loader?esModule=false!./src-noconflict/mode-rust.js')) +ace.config.setModuleUrl('ace/mode/sass', require('file-loader?esModule=false!./src-noconflict/mode-sass.js')) +ace.config.setModuleUrl('ace/mode/scad', require('file-loader?esModule=false!./src-noconflict/mode-scad.js')) +ace.config.setModuleUrl('ace/mode/scala', require('file-loader?esModule=false!./src-noconflict/mode-scala.js')) +ace.config.setModuleUrl('ace/mode/scheme', require('file-loader?esModule=false!./src-noconflict/mode-scheme.js')) +ace.config.setModuleUrl('ace/mode/scss', require('file-loader?esModule=false!./src-noconflict/mode-scss.js')) +ace.config.setModuleUrl('ace/mode/sh', require('file-loader?esModule=false!./src-noconflict/mode-sh.js')) +ace.config.setModuleUrl('ace/mode/sjs', require('file-loader?esModule=false!./src-noconflict/mode-sjs.js')) +ace.config.setModuleUrl('ace/mode/slim', require('file-loader?esModule=false!./src-noconflict/mode-slim.js')) +ace.config.setModuleUrl('ace/mode/smarty', require('file-loader?esModule=false!./src-noconflict/mode-smarty.js')) +ace.config.setModuleUrl('ace/mode/snippets', require('file-loader?esModule=false!./src-noconflict/mode-snippets.js')) +ace.config.setModuleUrl('ace/mode/soy_template', require('file-loader?esModule=false!./src-noconflict/mode-soy_template.js')) +ace.config.setModuleUrl('ace/mode/space', require('file-loader?esModule=false!./src-noconflict/mode-space.js')) +ace.config.setModuleUrl('ace/mode/sparql', require('file-loader?esModule=false!./src-noconflict/mode-sparql.js')) +ace.config.setModuleUrl('ace/mode/sql', require('file-loader?esModule=false!./src-noconflict/mode-sql.js')) +ace.config.setModuleUrl('ace/mode/sqlserver', require('file-loader?esModule=false!./src-noconflict/mode-sqlserver.js')) +ace.config.setModuleUrl('ace/mode/stylus', require('file-loader?esModule=false!./src-noconflict/mode-stylus.js')) +ace.config.setModuleUrl('ace/mode/svg', require('file-loader?esModule=false!./src-noconflict/mode-svg.js')) +ace.config.setModuleUrl('ace/mode/swift', require('file-loader?esModule=false!./src-noconflict/mode-swift.js')) +ace.config.setModuleUrl('ace/mode/tcl', require('file-loader?esModule=false!./src-noconflict/mode-tcl.js')) +ace.config.setModuleUrl('ace/mode/terraform', require('file-loader?esModule=false!./src-noconflict/mode-terraform.js')) +ace.config.setModuleUrl('ace/mode/tex', require('file-loader?esModule=false!./src-noconflict/mode-tex.js')) +ace.config.setModuleUrl('ace/mode/text', require('file-loader?esModule=false!./src-noconflict/mode-text.js')) +ace.config.setModuleUrl('ace/mode/textile', require('file-loader?esModule=false!./src-noconflict/mode-textile.js')) +ace.config.setModuleUrl('ace/mode/toml', require('file-loader?esModule=false!./src-noconflict/mode-toml.js')) +ace.config.setModuleUrl('ace/mode/tsx', require('file-loader?esModule=false!./src-noconflict/mode-tsx.js')) +ace.config.setModuleUrl('ace/mode/turtle', require('file-loader?esModule=false!./src-noconflict/mode-turtle.js')) +ace.config.setModuleUrl('ace/mode/twig', require('file-loader?esModule=false!./src-noconflict/mode-twig.js')) +ace.config.setModuleUrl('ace/mode/typescript', require('file-loader?esModule=false!./src-noconflict/mode-typescript.js')) +ace.config.setModuleUrl('ace/mode/vala', require('file-loader?esModule=false!./src-noconflict/mode-vala.js')) +ace.config.setModuleUrl('ace/mode/vbscript', require('file-loader?esModule=false!./src-noconflict/mode-vbscript.js')) +ace.config.setModuleUrl('ace/mode/velocity', require('file-loader?esModule=false!./src-noconflict/mode-velocity.js')) +ace.config.setModuleUrl('ace/mode/verilog', require('file-loader?esModule=false!./src-noconflict/mode-verilog.js')) +ace.config.setModuleUrl('ace/mode/vhdl', require('file-loader?esModule=false!./src-noconflict/mode-vhdl.js')) +ace.config.setModuleUrl('ace/mode/visualforce', require('file-loader?esModule=false!./src-noconflict/mode-visualforce.js')) +ace.config.setModuleUrl('ace/mode/wollok', require('file-loader?esModule=false!./src-noconflict/mode-wollok.js')) +ace.config.setModuleUrl('ace/mode/xml', require('file-loader?esModule=false!./src-noconflict/mode-xml.js')) +ace.config.setModuleUrl('ace/mode/xquery', require('file-loader?esModule=false!./src-noconflict/mode-xquery.js')) +ace.config.setModuleUrl('ace/mode/yaml', require('file-loader?esModule=false!./src-noconflict/mode-yaml.js')) +ace.config.setModuleUrl('ace/mode/zeek', require('file-loader?esModule=false!./src-noconflict/mode-zeek.js')) -ace.config.setModuleUrl('ace/theme/ambiance', require('file-loader!./src-noconflict/theme-ambiance.js')) -ace.config.setModuleUrl('ace/theme/chaos', require('file-loader!./src-noconflict/theme-chaos.js')) -ace.config.setModuleUrl('ace/theme/chrome', require('file-loader!./src-noconflict/theme-chrome.js')) -ace.config.setModuleUrl('ace/theme/clouds', require('file-loader!./src-noconflict/theme-clouds.js')) -ace.config.setModuleUrl('ace/theme/clouds_midnight', require('file-loader!./src-noconflict/theme-clouds_midnight.js')) -ace.config.setModuleUrl('ace/theme/cobalt', require('file-loader!./src-noconflict/theme-cobalt.js')) -ace.config.setModuleUrl('ace/theme/crimson_editor', require('file-loader!./src-noconflict/theme-crimson_editor.js')) -ace.config.setModuleUrl('ace/theme/dawn', require('file-loader!./src-noconflict/theme-dawn.js')) -ace.config.setModuleUrl('ace/theme/dracula', require('file-loader!./src-noconflict/theme-dracula.js')) -ace.config.setModuleUrl('ace/theme/dreamweaver', require('file-loader!./src-noconflict/theme-dreamweaver.js')) -ace.config.setModuleUrl('ace/theme/eclipse', require('file-loader!./src-noconflict/theme-eclipse.js')) -ace.config.setModuleUrl('ace/theme/github', require('file-loader!./src-noconflict/theme-github.js')) -ace.config.setModuleUrl('ace/theme/gob', require('file-loader!./src-noconflict/theme-gob.js')) -ace.config.setModuleUrl('ace/theme/gruvbox', require('file-loader!./src-noconflict/theme-gruvbox.js')) -ace.config.setModuleUrl('ace/theme/idle_fingers', require('file-loader!./src-noconflict/theme-idle_fingers.js')) -ace.config.setModuleUrl('ace/theme/iplastic', require('file-loader!./src-noconflict/theme-iplastic.js')) -ace.config.setModuleUrl('ace/theme/katzenmilch', require('file-loader!./src-noconflict/theme-katzenmilch.js')) -ace.config.setModuleUrl('ace/theme/kr_theme', require('file-loader!./src-noconflict/theme-kr_theme.js')) -ace.config.setModuleUrl('ace/theme/kuroir', require('file-loader!./src-noconflict/theme-kuroir.js')) -ace.config.setModuleUrl('ace/theme/merbivore', require('file-loader!./src-noconflict/theme-merbivore.js')) -ace.config.setModuleUrl('ace/theme/merbivore_soft', require('file-loader!./src-noconflict/theme-merbivore_soft.js')) -ace.config.setModuleUrl('ace/theme/monokai', require('file-loader!./src-noconflict/theme-monokai.js')) -ace.config.setModuleUrl('ace/theme/mono_industrial', require('file-loader!./src-noconflict/theme-mono_industrial.js')) -ace.config.setModuleUrl('ace/theme/pastel_on_dark', require('file-loader!./src-noconflict/theme-pastel_on_dark.js')) -ace.config.setModuleUrl('ace/theme/solarized_dark', require('file-loader!./src-noconflict/theme-solarized_dark.js')) -ace.config.setModuleUrl('ace/theme/solarized_light', require('file-loader!./src-noconflict/theme-solarized_light.js')) -ace.config.setModuleUrl('ace/theme/sqlserver', require('file-loader!./src-noconflict/theme-sqlserver.js')) -ace.config.setModuleUrl('ace/theme/terminal', require('file-loader!./src-noconflict/theme-terminal.js')) -ace.config.setModuleUrl('ace/theme/textmate', require('file-loader!./src-noconflict/theme-textmate.js')) -ace.config.setModuleUrl('ace/theme/tomorrow', require('file-loader!./src-noconflict/theme-tomorrow.js')) -ace.config.setModuleUrl('ace/theme/tomorrow_night', require('file-loader!./src-noconflict/theme-tomorrow_night.js')) -ace.config.setModuleUrl('ace/theme/tomorrow_night_blue', require('file-loader!./src-noconflict/theme-tomorrow_night_blue.js')) -ace.config.setModuleUrl('ace/theme/tomorrow_night_bright', require('file-loader!./src-noconflict/theme-tomorrow_night_bright.js')) -ace.config.setModuleUrl('ace/theme/tomorrow_night_eighties', require('file-loader!./src-noconflict/theme-tomorrow_night_eighties.js')) -ace.config.setModuleUrl('ace/theme/twilight', require('file-loader!./src-noconflict/theme-twilight.js')) -ace.config.setModuleUrl('ace/theme/vibrant_ink', require('file-loader!./src-noconflict/theme-vibrant_ink.js')) -ace.config.setModuleUrl('ace/theme/xcode', require('file-loader!./src-noconflict/theme-xcode.js')) -ace.config.setModuleUrl('ace/mode/coffee_worker', require('file-loader!./src-noconflict/worker-coffee.js')) -ace.config.setModuleUrl('ace/mode/css_worker', require('file-loader!./src-noconflict/worker-css.js')) -ace.config.setModuleUrl('ace/mode/html_worker', require('file-loader!./src-noconflict/worker-html.js')) -ace.config.setModuleUrl('ace/mode/javascript_worker', require('file-loader!./src-noconflict/worker-javascript.js')) -ace.config.setModuleUrl('ace/mode/json_worker', require('file-loader!./src-noconflict/worker-json.js')) -ace.config.setModuleUrl('ace/mode/lua_worker', require('file-loader!./src-noconflict/worker-lua.js')) -ace.config.setModuleUrl('ace/mode/php_worker', require('file-loader!./src-noconflict/worker-php.js')) -ace.config.setModuleUrl('ace/mode/xml_worker', require('file-loader!./src-noconflict/worker-xml.js')) -ace.config.setModuleUrl('ace/mode/xquery_worker', require('file-loader!./src-noconflict/worker-xquery.js')) -ace.config.setModuleUrl('ace/snippets/abap', require('file-loader!./src-noconflict/snippets/abap.js')) -ace.config.setModuleUrl('ace/snippets/abc', require('file-loader!./src-noconflict/snippets/abc.js')) -ace.config.setModuleUrl('ace/snippets/actionscript', require('file-loader!./src-noconflict/snippets/actionscript.js')) -ace.config.setModuleUrl('ace/snippets/ada', require('file-loader!./src-noconflict/snippets/ada.js')) -ace.config.setModuleUrl('ace/snippets/apache_conf', require('file-loader!./src-noconflict/snippets/apache_conf.js')) -ace.config.setModuleUrl('ace/snippets/apex', require('file-loader!./src-noconflict/snippets/apex.js')) -ace.config.setModuleUrl('ace/snippets/applescript', require('file-loader!./src-noconflict/snippets/applescript.js')) -ace.config.setModuleUrl('ace/snippets/aql', require('file-loader!./src-noconflict/snippets/aql.js')) -ace.config.setModuleUrl('ace/snippets/asciidoc', require('file-loader!./src-noconflict/snippets/asciidoc.js')) -ace.config.setModuleUrl('ace/snippets/asl', require('file-loader!./src-noconflict/snippets/asl.js')) -ace.config.setModuleUrl('ace/snippets/assembly_x86', require('file-loader!./src-noconflict/snippets/assembly_x86.js')) -ace.config.setModuleUrl('ace/snippets/autohotkey', require('file-loader!./src-noconflict/snippets/autohotkey.js')) -ace.config.setModuleUrl('ace/snippets/batchfile', require('file-loader!./src-noconflict/snippets/batchfile.js')) -ace.config.setModuleUrl('ace/snippets/bro', require('file-loader!./src-noconflict/snippets/bro.js')) -ace.config.setModuleUrl('ace/snippets/c9search', require('file-loader!./src-noconflict/snippets/c9search.js')) -ace.config.setModuleUrl('ace/snippets/cirru', require('file-loader!./src-noconflict/snippets/cirru.js')) -ace.config.setModuleUrl('ace/snippets/clojure', require('file-loader!./src-noconflict/snippets/clojure.js')) -ace.config.setModuleUrl('ace/snippets/cobol', require('file-loader!./src-noconflict/snippets/cobol.js')) -ace.config.setModuleUrl('ace/snippets/coffee', require('file-loader!./src-noconflict/snippets/coffee.js')) -ace.config.setModuleUrl('ace/snippets/coldfusion', require('file-loader!./src-noconflict/snippets/coldfusion.js')) -ace.config.setModuleUrl('ace/snippets/crystal', require('file-loader!./src-noconflict/snippets/crystal.js')) -ace.config.setModuleUrl('ace/snippets/csharp', require('file-loader!./src-noconflict/snippets/csharp.js')) -ace.config.setModuleUrl('ace/snippets/csound_document', require('file-loader!./src-noconflict/snippets/csound_document.js')) -ace.config.setModuleUrl('ace/snippets/csound_orchestra', require('file-loader!./src-noconflict/snippets/csound_orchestra.js')) -ace.config.setModuleUrl('ace/snippets/csound_score', require('file-loader!./src-noconflict/snippets/csound_score.js')) -ace.config.setModuleUrl('ace/snippets/csp', require('file-loader!./src-noconflict/snippets/csp.js')) -ace.config.setModuleUrl('ace/snippets/css', require('file-loader!./src-noconflict/snippets/css.js')) -ace.config.setModuleUrl('ace/snippets/curly', require('file-loader!./src-noconflict/snippets/curly.js')) -ace.config.setModuleUrl('ace/snippets/c_cpp', require('file-loader!./src-noconflict/snippets/c_cpp.js')) -ace.config.setModuleUrl('ace/snippets/d', require('file-loader!./src-noconflict/snippets/d.js')) -ace.config.setModuleUrl('ace/snippets/dart', require('file-loader!./src-noconflict/snippets/dart.js')) -ace.config.setModuleUrl('ace/snippets/diff', require('file-loader!./src-noconflict/snippets/diff.js')) -ace.config.setModuleUrl('ace/snippets/django', require('file-loader!./src-noconflict/snippets/django.js')) -ace.config.setModuleUrl('ace/snippets/dockerfile', require('file-loader!./src-noconflict/snippets/dockerfile.js')) -ace.config.setModuleUrl('ace/snippets/dot', require('file-loader!./src-noconflict/snippets/dot.js')) -ace.config.setModuleUrl('ace/snippets/drools', require('file-loader!./src-noconflict/snippets/drools.js')) -ace.config.setModuleUrl('ace/snippets/edifact', require('file-loader!./src-noconflict/snippets/edifact.js')) -ace.config.setModuleUrl('ace/snippets/eiffel', require('file-loader!./src-noconflict/snippets/eiffel.js')) -ace.config.setModuleUrl('ace/snippets/ejs', require('file-loader!./src-noconflict/snippets/ejs.js')) -ace.config.setModuleUrl('ace/snippets/elixir', require('file-loader!./src-noconflict/snippets/elixir.js')) -ace.config.setModuleUrl('ace/snippets/elm', require('file-loader!./src-noconflict/snippets/elm.js')) -ace.config.setModuleUrl('ace/snippets/erlang', require('file-loader!./src-noconflict/snippets/erlang.js')) -ace.config.setModuleUrl('ace/snippets/forth', require('file-loader!./src-noconflict/snippets/forth.js')) -ace.config.setModuleUrl('ace/snippets/fortran', require('file-loader!./src-noconflict/snippets/fortran.js')) -ace.config.setModuleUrl('ace/snippets/fsharp', require('file-loader!./src-noconflict/snippets/fsharp.js')) -ace.config.setModuleUrl('ace/snippets/fsl', require('file-loader!./src-noconflict/snippets/fsl.js')) -ace.config.setModuleUrl('ace/snippets/ftl', require('file-loader!./src-noconflict/snippets/ftl.js')) -ace.config.setModuleUrl('ace/snippets/gcode', require('file-loader!./src-noconflict/snippets/gcode.js')) -ace.config.setModuleUrl('ace/snippets/gherkin', require('file-loader!./src-noconflict/snippets/gherkin.js')) -ace.config.setModuleUrl('ace/snippets/gitignore', require('file-loader!./src-noconflict/snippets/gitignore.js')) -ace.config.setModuleUrl('ace/snippets/glsl', require('file-loader!./src-noconflict/snippets/glsl.js')) -ace.config.setModuleUrl('ace/snippets/gobstones', require('file-loader!./src-noconflict/snippets/gobstones.js')) -ace.config.setModuleUrl('ace/snippets/golang', require('file-loader!./src-noconflict/snippets/golang.js')) -ace.config.setModuleUrl('ace/snippets/graphqlschema', require('file-loader!./src-noconflict/snippets/graphqlschema.js')) -ace.config.setModuleUrl('ace/snippets/groovy', require('file-loader!./src-noconflict/snippets/groovy.js')) -ace.config.setModuleUrl('ace/snippets/haml', require('file-loader!./src-noconflict/snippets/haml.js')) -ace.config.setModuleUrl('ace/snippets/handlebars', require('file-loader!./src-noconflict/snippets/handlebars.js')) -ace.config.setModuleUrl('ace/snippets/haskell', require('file-loader!./src-noconflict/snippets/haskell.js')) -ace.config.setModuleUrl('ace/snippets/haskell_cabal', require('file-loader!./src-noconflict/snippets/haskell_cabal.js')) -ace.config.setModuleUrl('ace/snippets/haxe', require('file-loader!./src-noconflict/snippets/haxe.js')) -ace.config.setModuleUrl('ace/snippets/hjson', require('file-loader!./src-noconflict/snippets/hjson.js')) -ace.config.setModuleUrl('ace/snippets/html', require('file-loader!./src-noconflict/snippets/html.js')) -ace.config.setModuleUrl('ace/snippets/html_elixir', require('file-loader!./src-noconflict/snippets/html_elixir.js')) -ace.config.setModuleUrl('ace/snippets/html_ruby', require('file-loader!./src-noconflict/snippets/html_ruby.js')) -ace.config.setModuleUrl('ace/snippets/ini', require('file-loader!./src-noconflict/snippets/ini.js')) -ace.config.setModuleUrl('ace/snippets/io', require('file-loader!./src-noconflict/snippets/io.js')) -ace.config.setModuleUrl('ace/snippets/jack', require('file-loader!./src-noconflict/snippets/jack.js')) -ace.config.setModuleUrl('ace/snippets/jade', require('file-loader!./src-noconflict/snippets/jade.js')) -ace.config.setModuleUrl('ace/snippets/java', require('file-loader!./src-noconflict/snippets/java.js')) -ace.config.setModuleUrl('ace/snippets/javascript', require('file-loader!./src-noconflict/snippets/javascript.js')) -ace.config.setModuleUrl('ace/snippets/json', require('file-loader!./src-noconflict/snippets/json.js')) -ace.config.setModuleUrl('ace/snippets/jsoniq', require('file-loader!./src-noconflict/snippets/jsoniq.js')) -ace.config.setModuleUrl('ace/snippets/jsp', require('file-loader!./src-noconflict/snippets/jsp.js')) -ace.config.setModuleUrl('ace/snippets/jssm', require('file-loader!./src-noconflict/snippets/jssm.js')) -ace.config.setModuleUrl('ace/snippets/jsx', require('file-loader!./src-noconflict/snippets/jsx.js')) -ace.config.setModuleUrl('ace/snippets/julia', require('file-loader!./src-noconflict/snippets/julia.js')) -ace.config.setModuleUrl('ace/snippets/kotlin', require('file-loader!./src-noconflict/snippets/kotlin.js')) -ace.config.setModuleUrl('ace/snippets/latex', require('file-loader!./src-noconflict/snippets/latex.js')) -ace.config.setModuleUrl('ace/snippets/less', require('file-loader!./src-noconflict/snippets/less.js')) -ace.config.setModuleUrl('ace/snippets/liquid', require('file-loader!./src-noconflict/snippets/liquid.js')) -ace.config.setModuleUrl('ace/snippets/lisp', require('file-loader!./src-noconflict/snippets/lisp.js')) -ace.config.setModuleUrl('ace/snippets/livescript', require('file-loader!./src-noconflict/snippets/livescript.js')) -ace.config.setModuleUrl('ace/snippets/logiql', require('file-loader!./src-noconflict/snippets/logiql.js')) -ace.config.setModuleUrl('ace/snippets/logtalk', require('file-loader!./src-noconflict/snippets/logtalk.js')) -ace.config.setModuleUrl('ace/snippets/lsl', require('file-loader!./src-noconflict/snippets/lsl.js')) -ace.config.setModuleUrl('ace/snippets/lua', require('file-loader!./src-noconflict/snippets/lua.js')) -ace.config.setModuleUrl('ace/snippets/luapage', require('file-loader!./src-noconflict/snippets/luapage.js')) -ace.config.setModuleUrl('ace/snippets/lucene', require('file-loader!./src-noconflict/snippets/lucene.js')) -ace.config.setModuleUrl('ace/snippets/makefile', require('file-loader!./src-noconflict/snippets/makefile.js')) -ace.config.setModuleUrl('ace/snippets/markdown', require('file-loader!./src-noconflict/snippets/markdown.js')) -ace.config.setModuleUrl('ace/snippets/mask', require('file-loader!./src-noconflict/snippets/mask.js')) -ace.config.setModuleUrl('ace/snippets/matlab', require('file-loader!./src-noconflict/snippets/matlab.js')) -ace.config.setModuleUrl('ace/snippets/maze', require('file-loader!./src-noconflict/snippets/maze.js')) -ace.config.setModuleUrl('ace/snippets/mel', require('file-loader!./src-noconflict/snippets/mel.js')) -ace.config.setModuleUrl('ace/snippets/mixal', require('file-loader!./src-noconflict/snippets/mixal.js')) -ace.config.setModuleUrl('ace/snippets/mushcode', require('file-loader!./src-noconflict/snippets/mushcode.js')) -ace.config.setModuleUrl('ace/snippets/mysql', require('file-loader!./src-noconflict/snippets/mysql.js')) -ace.config.setModuleUrl('ace/snippets/nginx', require('file-loader!./src-noconflict/snippets/nginx.js')) -ace.config.setModuleUrl('ace/snippets/nim', require('file-loader!./src-noconflict/snippets/nim.js')) -ace.config.setModuleUrl('ace/snippets/nix', require('file-loader!./src-noconflict/snippets/nix.js')) -ace.config.setModuleUrl('ace/snippets/nsis', require('file-loader!./src-noconflict/snippets/nsis.js')) -ace.config.setModuleUrl('ace/snippets/objectivec', require('file-loader!./src-noconflict/snippets/objectivec.js')) -ace.config.setModuleUrl('ace/snippets/ocaml', require('file-loader!./src-noconflict/snippets/ocaml.js')) -ace.config.setModuleUrl('ace/snippets/pascal', require('file-loader!./src-noconflict/snippets/pascal.js')) -ace.config.setModuleUrl('ace/snippets/perl', require('file-loader!./src-noconflict/snippets/perl.js')) -ace.config.setModuleUrl('ace/snippets/perl6', require('file-loader!./src-noconflict/snippets/perl6.js')) -ace.config.setModuleUrl('ace/snippets/pgsql', require('file-loader!./src-noconflict/snippets/pgsql.js')) -ace.config.setModuleUrl('ace/snippets/php', require('file-loader!./src-noconflict/snippets/php.js')) -ace.config.setModuleUrl('ace/snippets/php_laravel_blade', require('file-loader!./src-noconflict/snippets/php_laravel_blade.js')) -ace.config.setModuleUrl('ace/snippets/pig', require('file-loader!./src-noconflict/snippets/pig.js')) -ace.config.setModuleUrl('ace/snippets/plain_text', require('file-loader!./src-noconflict/snippets/plain_text.js')) -ace.config.setModuleUrl('ace/snippets/powershell', require('file-loader!./src-noconflict/snippets/powershell.js')) -ace.config.setModuleUrl('ace/snippets/praat', require('file-loader!./src-noconflict/snippets/praat.js')) -ace.config.setModuleUrl('ace/snippets/prolog', require('file-loader!./src-noconflict/snippets/prolog.js')) -ace.config.setModuleUrl('ace/snippets/properties', require('file-loader!./src-noconflict/snippets/properties.js')) -ace.config.setModuleUrl('ace/snippets/protobuf', require('file-loader!./src-noconflict/snippets/protobuf.js')) -ace.config.setModuleUrl('ace/snippets/puppet', require('file-loader!./src-noconflict/snippets/puppet.js')) -ace.config.setModuleUrl('ace/snippets/python', require('file-loader!./src-noconflict/snippets/python.js')) -ace.config.setModuleUrl('ace/snippets/r', require('file-loader!./src-noconflict/snippets/r.js')) -ace.config.setModuleUrl('ace/snippets/razor', require('file-loader!./src-noconflict/snippets/razor.js')) -ace.config.setModuleUrl('ace/snippets/rdoc', require('file-loader!./src-noconflict/snippets/rdoc.js')) -ace.config.setModuleUrl('ace/snippets/red', require('file-loader!./src-noconflict/snippets/red.js')) -ace.config.setModuleUrl('ace/snippets/redshift', require('file-loader!./src-noconflict/snippets/redshift.js')) -ace.config.setModuleUrl('ace/snippets/rhtml', require('file-loader!./src-noconflict/snippets/rhtml.js')) -ace.config.setModuleUrl('ace/snippets/rst', require('file-loader!./src-noconflict/snippets/rst.js')) -ace.config.setModuleUrl('ace/snippets/ruby', require('file-loader!./src-noconflict/snippets/ruby.js')) -ace.config.setModuleUrl('ace/snippets/rust', require('file-loader!./src-noconflict/snippets/rust.js')) -ace.config.setModuleUrl('ace/snippets/sass', require('file-loader!./src-noconflict/snippets/sass.js')) -ace.config.setModuleUrl('ace/snippets/scad', require('file-loader!./src-noconflict/snippets/scad.js')) -ace.config.setModuleUrl('ace/snippets/scala', require('file-loader!./src-noconflict/snippets/scala.js')) -ace.config.setModuleUrl('ace/snippets/scheme', require('file-loader!./src-noconflict/snippets/scheme.js')) -ace.config.setModuleUrl('ace/snippets/scss', require('file-loader!./src-noconflict/snippets/scss.js')) -ace.config.setModuleUrl('ace/snippets/sh', require('file-loader!./src-noconflict/snippets/sh.js')) -ace.config.setModuleUrl('ace/snippets/sjs', require('file-loader!./src-noconflict/snippets/sjs.js')) -ace.config.setModuleUrl('ace/snippets/slim', require('file-loader!./src-noconflict/snippets/slim.js')) -ace.config.setModuleUrl('ace/snippets/smarty', require('file-loader!./src-noconflict/snippets/smarty.js')) -ace.config.setModuleUrl('ace/snippets/snippets', require('file-loader!./src-noconflict/snippets/snippets.js')) -ace.config.setModuleUrl('ace/snippets/soy_template', require('file-loader!./src-noconflict/snippets/soy_template.js')) -ace.config.setModuleUrl('ace/snippets/space', require('file-loader!./src-noconflict/snippets/space.js')) -ace.config.setModuleUrl('ace/snippets/sparql', require('file-loader!./src-noconflict/snippets/sparql.js')) -ace.config.setModuleUrl('ace/snippets/sql', require('file-loader!./src-noconflict/snippets/sql.js')) -ace.config.setModuleUrl('ace/snippets/sqlserver', require('file-loader!./src-noconflict/snippets/sqlserver.js')) -ace.config.setModuleUrl('ace/snippets/stylus', require('file-loader!./src-noconflict/snippets/stylus.js')) -ace.config.setModuleUrl('ace/snippets/svg', require('file-loader!./src-noconflict/snippets/svg.js')) -ace.config.setModuleUrl('ace/snippets/swift', require('file-loader!./src-noconflict/snippets/swift.js')) -ace.config.setModuleUrl('ace/snippets/tcl', require('file-loader!./src-noconflict/snippets/tcl.js')) -ace.config.setModuleUrl('ace/snippets/terraform', require('file-loader!./src-noconflict/snippets/terraform.js')) -ace.config.setModuleUrl('ace/snippets/tex', require('file-loader!./src-noconflict/snippets/tex.js')) -ace.config.setModuleUrl('ace/snippets/text', require('file-loader!./src-noconflict/snippets/text.js')) -ace.config.setModuleUrl('ace/snippets/textile', require('file-loader!./src-noconflict/snippets/textile.js')) -ace.config.setModuleUrl('ace/snippets/toml', require('file-loader!./src-noconflict/snippets/toml.js')) -ace.config.setModuleUrl('ace/snippets/tsx', require('file-loader!./src-noconflict/snippets/tsx.js')) -ace.config.setModuleUrl('ace/snippets/turtle', require('file-loader!./src-noconflict/snippets/turtle.js')) -ace.config.setModuleUrl('ace/snippets/twig', require('file-loader!./src-noconflict/snippets/twig.js')) -ace.config.setModuleUrl('ace/snippets/typescript', require('file-loader!./src-noconflict/snippets/typescript.js')) -ace.config.setModuleUrl('ace/snippets/vala', require('file-loader!./src-noconflict/snippets/vala.js')) -ace.config.setModuleUrl('ace/snippets/vbscript', require('file-loader!./src-noconflict/snippets/vbscript.js')) -ace.config.setModuleUrl('ace/snippets/velocity', require('file-loader!./src-noconflict/snippets/velocity.js')) -ace.config.setModuleUrl('ace/snippets/verilog', require('file-loader!./src-noconflict/snippets/verilog.js')) -ace.config.setModuleUrl('ace/snippets/vhdl', require('file-loader!./src-noconflict/snippets/vhdl.js')) -ace.config.setModuleUrl('ace/snippets/visualforce', require('file-loader!./src-noconflict/snippets/visualforce.js')) -ace.config.setModuleUrl('ace/snippets/wollok', require('file-loader!./src-noconflict/snippets/wollok.js')) -ace.config.setModuleUrl('ace/snippets/xml', require('file-loader!./src-noconflict/snippets/xml.js')) -ace.config.setModuleUrl('ace/snippets/xquery', require('file-loader!./src-noconflict/snippets/xquery.js')) -ace.config.setModuleUrl('ace/snippets/yaml', require('file-loader!./src-noconflict/snippets/yaml.js')) -ace.config.setModuleUrl('ace/snippets/zeek', require('file-loader!./src-noconflict/snippets/zeek.js')) \ No newline at end of file +ace.config.setModuleUrl('ace/theme/ambiance', require('file-loader?esModule=false!./src-noconflict/theme-ambiance.js')) +ace.config.setModuleUrl('ace/theme/chaos', require('file-loader?esModule=false!./src-noconflict/theme-chaos.js')) +ace.config.setModuleUrl('ace/theme/chrome', require('file-loader?esModule=false!./src-noconflict/theme-chrome.js')) +ace.config.setModuleUrl('ace/theme/clouds', require('file-loader?esModule=false!./src-noconflict/theme-clouds.js')) +ace.config.setModuleUrl('ace/theme/clouds_midnight', require('file-loader?esModule=false!./src-noconflict/theme-clouds_midnight.js')) +ace.config.setModuleUrl('ace/theme/cobalt', require('file-loader?esModule=false!./src-noconflict/theme-cobalt.js')) +ace.config.setModuleUrl('ace/theme/crimson_editor', require('file-loader?esModule=false!./src-noconflict/theme-crimson_editor.js')) +ace.config.setModuleUrl('ace/theme/dawn', require('file-loader?esModule=false!./src-noconflict/theme-dawn.js')) +ace.config.setModuleUrl('ace/theme/dracula', require('file-loader?esModule=false!./src-noconflict/theme-dracula.js')) +ace.config.setModuleUrl('ace/theme/dreamweaver', require('file-loader?esModule=false!./src-noconflict/theme-dreamweaver.js')) +ace.config.setModuleUrl('ace/theme/eclipse', require('file-loader?esModule=false!./src-noconflict/theme-eclipse.js')) +ace.config.setModuleUrl('ace/theme/github', require('file-loader?esModule=false!./src-noconflict/theme-github.js')) +ace.config.setModuleUrl('ace/theme/gob', require('file-loader?esModule=false!./src-noconflict/theme-gob.js')) +ace.config.setModuleUrl('ace/theme/gruvbox', require('file-loader?esModule=false!./src-noconflict/theme-gruvbox.js')) +ace.config.setModuleUrl('ace/theme/idle_fingers', require('file-loader?esModule=false!./src-noconflict/theme-idle_fingers.js')) +ace.config.setModuleUrl('ace/theme/iplastic', require('file-loader?esModule=false!./src-noconflict/theme-iplastic.js')) +ace.config.setModuleUrl('ace/theme/katzenmilch', require('file-loader?esModule=false!./src-noconflict/theme-katzenmilch.js')) +ace.config.setModuleUrl('ace/theme/kr_theme', require('file-loader?esModule=false!./src-noconflict/theme-kr_theme.js')) +ace.config.setModuleUrl('ace/theme/kuroir', require('file-loader?esModule=false!./src-noconflict/theme-kuroir.js')) +ace.config.setModuleUrl('ace/theme/merbivore', require('file-loader?esModule=false!./src-noconflict/theme-merbivore.js')) +ace.config.setModuleUrl('ace/theme/merbivore_soft', require('file-loader?esModule=false!./src-noconflict/theme-merbivore_soft.js')) +ace.config.setModuleUrl('ace/theme/monokai', require('file-loader?esModule=false!./src-noconflict/theme-monokai.js')) +ace.config.setModuleUrl('ace/theme/mono_industrial', require('file-loader?esModule=false!./src-noconflict/theme-mono_industrial.js')) +ace.config.setModuleUrl('ace/theme/pastel_on_dark', require('file-loader?esModule=false!./src-noconflict/theme-pastel_on_dark.js')) +ace.config.setModuleUrl('ace/theme/solarized_dark', require('file-loader?esModule=false!./src-noconflict/theme-solarized_dark.js')) +ace.config.setModuleUrl('ace/theme/solarized_light', require('file-loader?esModule=false!./src-noconflict/theme-solarized_light.js')) +ace.config.setModuleUrl('ace/theme/sqlserver', require('file-loader?esModule=false!./src-noconflict/theme-sqlserver.js')) +ace.config.setModuleUrl('ace/theme/terminal', require('file-loader?esModule=false!./src-noconflict/theme-terminal.js')) +ace.config.setModuleUrl('ace/theme/textmate', require('file-loader?esModule=false!./src-noconflict/theme-textmate.js')) +ace.config.setModuleUrl('ace/theme/tomorrow', require('file-loader?esModule=false!./src-noconflict/theme-tomorrow.js')) +ace.config.setModuleUrl('ace/theme/tomorrow_night', require('file-loader?esModule=false!./src-noconflict/theme-tomorrow_night.js')) +ace.config.setModuleUrl('ace/theme/tomorrow_night_blue', require('file-loader?esModule=false!./src-noconflict/theme-tomorrow_night_blue.js')) +ace.config.setModuleUrl('ace/theme/tomorrow_night_bright', require('file-loader?esModule=false!./src-noconflict/theme-tomorrow_night_bright.js')) +ace.config.setModuleUrl('ace/theme/tomorrow_night_eighties', require('file-loader?esModule=false!./src-noconflict/theme-tomorrow_night_eighties.js')) +ace.config.setModuleUrl('ace/theme/twilight', require('file-loader?esModule=false!./src-noconflict/theme-twilight.js')) +ace.config.setModuleUrl('ace/theme/vibrant_ink', require('file-loader?esModule=false!./src-noconflict/theme-vibrant_ink.js')) +ace.config.setModuleUrl('ace/theme/xcode', require('file-loader?esModule=false!./src-noconflict/theme-xcode.js')) +ace.config.setModuleUrl('ace/mode/coffee_worker', require('file-loader?esModule=false!./src-noconflict/worker-coffee.js')) +ace.config.setModuleUrl('ace/mode/css_worker', require('file-loader?esModule=false!./src-noconflict/worker-css.js')) +ace.config.setModuleUrl('ace/mode/html_worker', require('file-loader?esModule=false!./src-noconflict/worker-html.js')) +ace.config.setModuleUrl('ace/mode/javascript_worker', require('file-loader?esModule=false!./src-noconflict/worker-javascript.js')) +ace.config.setModuleUrl('ace/mode/json_worker', require('file-loader?esModule=false!./src-noconflict/worker-json.js')) +ace.config.setModuleUrl('ace/mode/lua_worker', require('file-loader?esModule=false!./src-noconflict/worker-lua.js')) +ace.config.setModuleUrl('ace/mode/php_worker', require('file-loader?esModule=false!./src-noconflict/worker-php.js')) +ace.config.setModuleUrl('ace/mode/xml_worker', require('file-loader?esModule=false!./src-noconflict/worker-xml.js')) +ace.config.setModuleUrl('ace/mode/xquery_worker', require('file-loader?esModule=false!./src-noconflict/worker-xquery.js')) +ace.config.setModuleUrl('ace/snippets/abap', require('file-loader?esModule=false!./src-noconflict/snippets/abap.js')) +ace.config.setModuleUrl('ace/snippets/abc', require('file-loader?esModule=false!./src-noconflict/snippets/abc.js')) +ace.config.setModuleUrl('ace/snippets/actionscript', require('file-loader?esModule=false!./src-noconflict/snippets/actionscript.js')) +ace.config.setModuleUrl('ace/snippets/ada', require('file-loader?esModule=false!./src-noconflict/snippets/ada.js')) +ace.config.setModuleUrl('ace/snippets/apache_conf', require('file-loader?esModule=false!./src-noconflict/snippets/apache_conf.js')) +ace.config.setModuleUrl('ace/snippets/apex', require('file-loader?esModule=false!./src-noconflict/snippets/apex.js')) +ace.config.setModuleUrl('ace/snippets/applescript', require('file-loader?esModule=false!./src-noconflict/snippets/applescript.js')) +ace.config.setModuleUrl('ace/snippets/aql', require('file-loader?esModule=false!./src-noconflict/snippets/aql.js')) +ace.config.setModuleUrl('ace/snippets/asciidoc', require('file-loader?esModule=false!./src-noconflict/snippets/asciidoc.js')) +ace.config.setModuleUrl('ace/snippets/asl', require('file-loader?esModule=false!./src-noconflict/snippets/asl.js')) +ace.config.setModuleUrl('ace/snippets/assembly_x86', require('file-loader?esModule=false!./src-noconflict/snippets/assembly_x86.js')) +ace.config.setModuleUrl('ace/snippets/autohotkey', require('file-loader?esModule=false!./src-noconflict/snippets/autohotkey.js')) +ace.config.setModuleUrl('ace/snippets/batchfile', require('file-loader?esModule=false!./src-noconflict/snippets/batchfile.js')) +ace.config.setModuleUrl('ace/snippets/bro', require('file-loader?esModule=false!./src-noconflict/snippets/bro.js')) +ace.config.setModuleUrl('ace/snippets/c9search', require('file-loader?esModule=false!./src-noconflict/snippets/c9search.js')) +ace.config.setModuleUrl('ace/snippets/cirru', require('file-loader?esModule=false!./src-noconflict/snippets/cirru.js')) +ace.config.setModuleUrl('ace/snippets/clojure', require('file-loader?esModule=false!./src-noconflict/snippets/clojure.js')) +ace.config.setModuleUrl('ace/snippets/cobol', require('file-loader?esModule=false!./src-noconflict/snippets/cobol.js')) +ace.config.setModuleUrl('ace/snippets/coffee', require('file-loader?esModule=false!./src-noconflict/snippets/coffee.js')) +ace.config.setModuleUrl('ace/snippets/coldfusion', require('file-loader?esModule=false!./src-noconflict/snippets/coldfusion.js')) +ace.config.setModuleUrl('ace/snippets/crystal', require('file-loader?esModule=false!./src-noconflict/snippets/crystal.js')) +ace.config.setModuleUrl('ace/snippets/csharp', require('file-loader?esModule=false!./src-noconflict/snippets/csharp.js')) +ace.config.setModuleUrl('ace/snippets/csound_document', require('file-loader?esModule=false!./src-noconflict/snippets/csound_document.js')) +ace.config.setModuleUrl('ace/snippets/csound_orchestra', require('file-loader?esModule=false!./src-noconflict/snippets/csound_orchestra.js')) +ace.config.setModuleUrl('ace/snippets/csound_score', require('file-loader?esModule=false!./src-noconflict/snippets/csound_score.js')) +ace.config.setModuleUrl('ace/snippets/csp', require('file-loader?esModule=false!./src-noconflict/snippets/csp.js')) +ace.config.setModuleUrl('ace/snippets/css', require('file-loader?esModule=false!./src-noconflict/snippets/css.js')) +ace.config.setModuleUrl('ace/snippets/curly', require('file-loader?esModule=false!./src-noconflict/snippets/curly.js')) +ace.config.setModuleUrl('ace/snippets/c_cpp', require('file-loader?esModule=false!./src-noconflict/snippets/c_cpp.js')) +ace.config.setModuleUrl('ace/snippets/d', require('file-loader?esModule=false!./src-noconflict/snippets/d.js')) +ace.config.setModuleUrl('ace/snippets/dart', require('file-loader?esModule=false!./src-noconflict/snippets/dart.js')) +ace.config.setModuleUrl('ace/snippets/diff', require('file-loader?esModule=false!./src-noconflict/snippets/diff.js')) +ace.config.setModuleUrl('ace/snippets/django', require('file-loader?esModule=false!./src-noconflict/snippets/django.js')) +ace.config.setModuleUrl('ace/snippets/dockerfile', require('file-loader?esModule=false!./src-noconflict/snippets/dockerfile.js')) +ace.config.setModuleUrl('ace/snippets/dot', require('file-loader?esModule=false!./src-noconflict/snippets/dot.js')) +ace.config.setModuleUrl('ace/snippets/drools', require('file-loader?esModule=false!./src-noconflict/snippets/drools.js')) +ace.config.setModuleUrl('ace/snippets/edifact', require('file-loader?esModule=false!./src-noconflict/snippets/edifact.js')) +ace.config.setModuleUrl('ace/snippets/eiffel', require('file-loader?esModule=false!./src-noconflict/snippets/eiffel.js')) +ace.config.setModuleUrl('ace/snippets/ejs', require('file-loader?esModule=false!./src-noconflict/snippets/ejs.js')) +ace.config.setModuleUrl('ace/snippets/elixir', require('file-loader?esModule=false!./src-noconflict/snippets/elixir.js')) +ace.config.setModuleUrl('ace/snippets/elm', require('file-loader?esModule=false!./src-noconflict/snippets/elm.js')) +ace.config.setModuleUrl('ace/snippets/erlang', require('file-loader?esModule=false!./src-noconflict/snippets/erlang.js')) +ace.config.setModuleUrl('ace/snippets/forth', require('file-loader?esModule=false!./src-noconflict/snippets/forth.js')) +ace.config.setModuleUrl('ace/snippets/fortran', require('file-loader?esModule=false!./src-noconflict/snippets/fortran.js')) +ace.config.setModuleUrl('ace/snippets/fsharp', require('file-loader?esModule=false!./src-noconflict/snippets/fsharp.js')) +ace.config.setModuleUrl('ace/snippets/fsl', require('file-loader?esModule=false!./src-noconflict/snippets/fsl.js')) +ace.config.setModuleUrl('ace/snippets/ftl', require('file-loader?esModule=false!./src-noconflict/snippets/ftl.js')) +ace.config.setModuleUrl('ace/snippets/gcode', require('file-loader?esModule=false!./src-noconflict/snippets/gcode.js')) +ace.config.setModuleUrl('ace/snippets/gherkin', require('file-loader?esModule=false!./src-noconflict/snippets/gherkin.js')) +ace.config.setModuleUrl('ace/snippets/gitignore', require('file-loader?esModule=false!./src-noconflict/snippets/gitignore.js')) +ace.config.setModuleUrl('ace/snippets/glsl', require('file-loader?esModule=false!./src-noconflict/snippets/glsl.js')) +ace.config.setModuleUrl('ace/snippets/gobstones', require('file-loader?esModule=false!./src-noconflict/snippets/gobstones.js')) +ace.config.setModuleUrl('ace/snippets/golang', require('file-loader?esModule=false!./src-noconflict/snippets/golang.js')) +ace.config.setModuleUrl('ace/snippets/graphqlschema', require('file-loader?esModule=false!./src-noconflict/snippets/graphqlschema.js')) +ace.config.setModuleUrl('ace/snippets/groovy', require('file-loader?esModule=false!./src-noconflict/snippets/groovy.js')) +ace.config.setModuleUrl('ace/snippets/haml', require('file-loader?esModule=false!./src-noconflict/snippets/haml.js')) +ace.config.setModuleUrl('ace/snippets/handlebars', require('file-loader?esModule=false!./src-noconflict/snippets/handlebars.js')) +ace.config.setModuleUrl('ace/snippets/haskell', require('file-loader?esModule=false!./src-noconflict/snippets/haskell.js')) +ace.config.setModuleUrl('ace/snippets/haskell_cabal', require('file-loader?esModule=false!./src-noconflict/snippets/haskell_cabal.js')) +ace.config.setModuleUrl('ace/snippets/haxe', require('file-loader?esModule=false!./src-noconflict/snippets/haxe.js')) +ace.config.setModuleUrl('ace/snippets/hjson', require('file-loader?esModule=false!./src-noconflict/snippets/hjson.js')) +ace.config.setModuleUrl('ace/snippets/html', require('file-loader?esModule=false!./src-noconflict/snippets/html.js')) +ace.config.setModuleUrl('ace/snippets/html_elixir', require('file-loader?esModule=false!./src-noconflict/snippets/html_elixir.js')) +ace.config.setModuleUrl('ace/snippets/html_ruby', require('file-loader?esModule=false!./src-noconflict/snippets/html_ruby.js')) +ace.config.setModuleUrl('ace/snippets/ini', require('file-loader?esModule=false!./src-noconflict/snippets/ini.js')) +ace.config.setModuleUrl('ace/snippets/io', require('file-loader?esModule=false!./src-noconflict/snippets/io.js')) +ace.config.setModuleUrl('ace/snippets/jack', require('file-loader?esModule=false!./src-noconflict/snippets/jack.js')) +ace.config.setModuleUrl('ace/snippets/jade', require('file-loader?esModule=false!./src-noconflict/snippets/jade.js')) +ace.config.setModuleUrl('ace/snippets/java', require('file-loader?esModule=false!./src-noconflict/snippets/java.js')) +ace.config.setModuleUrl('ace/snippets/javascript', require('file-loader?esModule=false!./src-noconflict/snippets/javascript.js')) +ace.config.setModuleUrl('ace/snippets/json', require('file-loader?esModule=false!./src-noconflict/snippets/json.js')) +ace.config.setModuleUrl('ace/snippets/jsoniq', require('file-loader?esModule=false!./src-noconflict/snippets/jsoniq.js')) +ace.config.setModuleUrl('ace/snippets/jsp', require('file-loader?esModule=false!./src-noconflict/snippets/jsp.js')) +ace.config.setModuleUrl('ace/snippets/jssm', require('file-loader?esModule=false!./src-noconflict/snippets/jssm.js')) +ace.config.setModuleUrl('ace/snippets/jsx', require('file-loader?esModule=false!./src-noconflict/snippets/jsx.js')) +ace.config.setModuleUrl('ace/snippets/julia', require('file-loader?esModule=false!./src-noconflict/snippets/julia.js')) +ace.config.setModuleUrl('ace/snippets/kotlin', require('file-loader?esModule=false!./src-noconflict/snippets/kotlin.js')) +ace.config.setModuleUrl('ace/snippets/latex', require('file-loader?esModule=false!./src-noconflict/snippets/latex.js')) +ace.config.setModuleUrl('ace/snippets/less', require('file-loader?esModule=false!./src-noconflict/snippets/less.js')) +ace.config.setModuleUrl('ace/snippets/liquid', require('file-loader?esModule=false!./src-noconflict/snippets/liquid.js')) +ace.config.setModuleUrl('ace/snippets/lisp', require('file-loader?esModule=false!./src-noconflict/snippets/lisp.js')) +ace.config.setModuleUrl('ace/snippets/livescript', require('file-loader?esModule=false!./src-noconflict/snippets/livescript.js')) +ace.config.setModuleUrl('ace/snippets/logiql', require('file-loader?esModule=false!./src-noconflict/snippets/logiql.js')) +ace.config.setModuleUrl('ace/snippets/logtalk', require('file-loader?esModule=false!./src-noconflict/snippets/logtalk.js')) +ace.config.setModuleUrl('ace/snippets/lsl', require('file-loader?esModule=false!./src-noconflict/snippets/lsl.js')) +ace.config.setModuleUrl('ace/snippets/lua', require('file-loader?esModule=false!./src-noconflict/snippets/lua.js')) +ace.config.setModuleUrl('ace/snippets/luapage', require('file-loader?esModule=false!./src-noconflict/snippets/luapage.js')) +ace.config.setModuleUrl('ace/snippets/lucene', require('file-loader?esModule=false!./src-noconflict/snippets/lucene.js')) +ace.config.setModuleUrl('ace/snippets/makefile', require('file-loader?esModule=false!./src-noconflict/snippets/makefile.js')) +ace.config.setModuleUrl('ace/snippets/markdown', require('file-loader?esModule=false!./src-noconflict/snippets/markdown.js')) +ace.config.setModuleUrl('ace/snippets/mask', require('file-loader?esModule=false!./src-noconflict/snippets/mask.js')) +ace.config.setModuleUrl('ace/snippets/matlab', require('file-loader?esModule=false!./src-noconflict/snippets/matlab.js')) +ace.config.setModuleUrl('ace/snippets/maze', require('file-loader?esModule=false!./src-noconflict/snippets/maze.js')) +ace.config.setModuleUrl('ace/snippets/mel', require('file-loader?esModule=false!./src-noconflict/snippets/mel.js')) +ace.config.setModuleUrl('ace/snippets/mixal', require('file-loader?esModule=false!./src-noconflict/snippets/mixal.js')) +ace.config.setModuleUrl('ace/snippets/mushcode', require('file-loader?esModule=false!./src-noconflict/snippets/mushcode.js')) +ace.config.setModuleUrl('ace/snippets/mysql', require('file-loader?esModule=false!./src-noconflict/snippets/mysql.js')) +ace.config.setModuleUrl('ace/snippets/nginx', require('file-loader?esModule=false!./src-noconflict/snippets/nginx.js')) +ace.config.setModuleUrl('ace/snippets/nim', require('file-loader?esModule=false!./src-noconflict/snippets/nim.js')) +ace.config.setModuleUrl('ace/snippets/nix', require('file-loader?esModule=false!./src-noconflict/snippets/nix.js')) +ace.config.setModuleUrl('ace/snippets/nsis', require('file-loader?esModule=false!./src-noconflict/snippets/nsis.js')) +ace.config.setModuleUrl('ace/snippets/objectivec', require('file-loader?esModule=false!./src-noconflict/snippets/objectivec.js')) +ace.config.setModuleUrl('ace/snippets/ocaml', require('file-loader?esModule=false!./src-noconflict/snippets/ocaml.js')) +ace.config.setModuleUrl('ace/snippets/pascal', require('file-loader?esModule=false!./src-noconflict/snippets/pascal.js')) +ace.config.setModuleUrl('ace/snippets/perl', require('file-loader?esModule=false!./src-noconflict/snippets/perl.js')) +ace.config.setModuleUrl('ace/snippets/perl6', require('file-loader?esModule=false!./src-noconflict/snippets/perl6.js')) +ace.config.setModuleUrl('ace/snippets/pgsql', require('file-loader?esModule=false!./src-noconflict/snippets/pgsql.js')) +ace.config.setModuleUrl('ace/snippets/php', require('file-loader?esModule=false!./src-noconflict/snippets/php.js')) +ace.config.setModuleUrl('ace/snippets/php_laravel_blade', require('file-loader?esModule=false!./src-noconflict/snippets/php_laravel_blade.js')) +ace.config.setModuleUrl('ace/snippets/pig', require('file-loader?esModule=false!./src-noconflict/snippets/pig.js')) +ace.config.setModuleUrl('ace/snippets/plain_text', require('file-loader?esModule=false!./src-noconflict/snippets/plain_text.js')) +ace.config.setModuleUrl('ace/snippets/powershell', require('file-loader?esModule=false!./src-noconflict/snippets/powershell.js')) +ace.config.setModuleUrl('ace/snippets/praat', require('file-loader?esModule=false!./src-noconflict/snippets/praat.js')) +ace.config.setModuleUrl('ace/snippets/prolog', require('file-loader?esModule=false!./src-noconflict/snippets/prolog.js')) +ace.config.setModuleUrl('ace/snippets/properties', require('file-loader?esModule=false!./src-noconflict/snippets/properties.js')) +ace.config.setModuleUrl('ace/snippets/protobuf', require('file-loader?esModule=false!./src-noconflict/snippets/protobuf.js')) +ace.config.setModuleUrl('ace/snippets/puppet', require('file-loader?esModule=false!./src-noconflict/snippets/puppet.js')) +ace.config.setModuleUrl('ace/snippets/python', require('file-loader?esModule=false!./src-noconflict/snippets/python.js')) +ace.config.setModuleUrl('ace/snippets/r', require('file-loader?esModule=false!./src-noconflict/snippets/r.js')) +ace.config.setModuleUrl('ace/snippets/razor', require('file-loader?esModule=false!./src-noconflict/snippets/razor.js')) +ace.config.setModuleUrl('ace/snippets/rdoc', require('file-loader?esModule=false!./src-noconflict/snippets/rdoc.js')) +ace.config.setModuleUrl('ace/snippets/red', require('file-loader?esModule=false!./src-noconflict/snippets/red.js')) +ace.config.setModuleUrl('ace/snippets/redshift', require('file-loader?esModule=false!./src-noconflict/snippets/redshift.js')) +ace.config.setModuleUrl('ace/snippets/rhtml', require('file-loader?esModule=false!./src-noconflict/snippets/rhtml.js')) +ace.config.setModuleUrl('ace/snippets/rst', require('file-loader?esModule=false!./src-noconflict/snippets/rst.js')) +ace.config.setModuleUrl('ace/snippets/ruby', require('file-loader?esModule=false!./src-noconflict/snippets/ruby.js')) +ace.config.setModuleUrl('ace/snippets/rust', require('file-loader?esModule=false!./src-noconflict/snippets/rust.js')) +ace.config.setModuleUrl('ace/snippets/sass', require('file-loader?esModule=false!./src-noconflict/snippets/sass.js')) +ace.config.setModuleUrl('ace/snippets/scad', require('file-loader?esModule=false!./src-noconflict/snippets/scad.js')) +ace.config.setModuleUrl('ace/snippets/scala', require('file-loader?esModule=false!./src-noconflict/snippets/scala.js')) +ace.config.setModuleUrl('ace/snippets/scheme', require('file-loader?esModule=false!./src-noconflict/snippets/scheme.js')) +ace.config.setModuleUrl('ace/snippets/scss', require('file-loader?esModule=false!./src-noconflict/snippets/scss.js')) +ace.config.setModuleUrl('ace/snippets/sh', require('file-loader?esModule=false!./src-noconflict/snippets/sh.js')) +ace.config.setModuleUrl('ace/snippets/sjs', require('file-loader?esModule=false!./src-noconflict/snippets/sjs.js')) +ace.config.setModuleUrl('ace/snippets/slim', require('file-loader?esModule=false!./src-noconflict/snippets/slim.js')) +ace.config.setModuleUrl('ace/snippets/smarty', require('file-loader?esModule=false!./src-noconflict/snippets/smarty.js')) +ace.config.setModuleUrl('ace/snippets/snippets', require('file-loader?esModule=false!./src-noconflict/snippets/snippets.js')) +ace.config.setModuleUrl('ace/snippets/soy_template', require('file-loader?esModule=false!./src-noconflict/snippets/soy_template.js')) +ace.config.setModuleUrl('ace/snippets/space', require('file-loader?esModule=false!./src-noconflict/snippets/space.js')) +ace.config.setModuleUrl('ace/snippets/sparql', require('file-loader?esModule=false!./src-noconflict/snippets/sparql.js')) +ace.config.setModuleUrl('ace/snippets/sql', require('file-loader?esModule=false!./src-noconflict/snippets/sql.js')) +ace.config.setModuleUrl('ace/snippets/sqlserver', require('file-loader?esModule=false!./src-noconflict/snippets/sqlserver.js')) +ace.config.setModuleUrl('ace/snippets/stylus', require('file-loader?esModule=false!./src-noconflict/snippets/stylus.js')) +ace.config.setModuleUrl('ace/snippets/svg', require('file-loader?esModule=false!./src-noconflict/snippets/svg.js')) +ace.config.setModuleUrl('ace/snippets/swift', require('file-loader?esModule=false!./src-noconflict/snippets/swift.js')) +ace.config.setModuleUrl('ace/snippets/tcl', require('file-loader?esModule=false!./src-noconflict/snippets/tcl.js')) +ace.config.setModuleUrl('ace/snippets/terraform', require('file-loader?esModule=false!./src-noconflict/snippets/terraform.js')) +ace.config.setModuleUrl('ace/snippets/tex', require('file-loader?esModule=false!./src-noconflict/snippets/tex.js')) +ace.config.setModuleUrl('ace/snippets/text', require('file-loader?esModule=false!./src-noconflict/snippets/text.js')) +ace.config.setModuleUrl('ace/snippets/textile', require('file-loader?esModule=false!./src-noconflict/snippets/textile.js')) +ace.config.setModuleUrl('ace/snippets/toml', require('file-loader?esModule=false!./src-noconflict/snippets/toml.js')) +ace.config.setModuleUrl('ace/snippets/tsx', require('file-loader?esModule=false!./src-noconflict/snippets/tsx.js')) +ace.config.setModuleUrl('ace/snippets/turtle', require('file-loader?esModule=false!./src-noconflict/snippets/turtle.js')) +ace.config.setModuleUrl('ace/snippets/twig', require('file-loader?esModule=false!./src-noconflict/snippets/twig.js')) +ace.config.setModuleUrl('ace/snippets/typescript', require('file-loader?esModule=false!./src-noconflict/snippets/typescript.js')) +ace.config.setModuleUrl('ace/snippets/vala', require('file-loader?esModule=false!./src-noconflict/snippets/vala.js')) +ace.config.setModuleUrl('ace/snippets/vbscript', require('file-loader?esModule=false!./src-noconflict/snippets/vbscript.js')) +ace.config.setModuleUrl('ace/snippets/velocity', require('file-loader?esModule=false!./src-noconflict/snippets/velocity.js')) +ace.config.setModuleUrl('ace/snippets/verilog', require('file-loader?esModule=false!./src-noconflict/snippets/verilog.js')) +ace.config.setModuleUrl('ace/snippets/vhdl', require('file-loader?esModule=false!./src-noconflict/snippets/vhdl.js')) +ace.config.setModuleUrl('ace/snippets/visualforce', require('file-loader?esModule=false!./src-noconflict/snippets/visualforce.js')) +ace.config.setModuleUrl('ace/snippets/wollok', require('file-loader?esModule=false!./src-noconflict/snippets/wollok.js')) +ace.config.setModuleUrl('ace/snippets/xml', require('file-loader?esModule=false!./src-noconflict/snippets/xml.js')) +ace.config.setModuleUrl('ace/snippets/xquery', require('file-loader?esModule=false!./src-noconflict/snippets/xquery.js')) +ace.config.setModuleUrl('ace/snippets/yaml', require('file-loader?esModule=false!./src-noconflict/snippets/yaml.js')) +ace.config.setModuleUrl('ace/snippets/zeek', require('file-loader?esModule=false!./src-noconflict/snippets/zeek.js')) \ No newline at end of file diff --git a/htdocs/includes/chart/.codeclimate.yml b/htdocs/includes/chart/.codeclimate.yml new file mode 100644 index 00000000000..0b8340feb58 --- /dev/null +++ b/htdocs/includes/chart/.codeclimate.yml @@ -0,0 +1,19 @@ +version: "2" +plugins: + duplication: + enabled: true + config: + languages: + - javascript + fixme: + enabled: true +exclude_patterns: + - "dist/" + - "docs/" + - "samples/" + - "scripts/" + - "test/" + - "*.js" + - "*.json" + - "*.md" + - ".*" diff --git a/htdocs/includes/chart/.editorconfig b/htdocs/includes/chart/.editorconfig new file mode 100644 index 00000000000..922810ad734 --- /dev/null +++ b/htdocs/includes/chart/.editorconfig @@ -0,0 +1,18 @@ +# https://editorconfig.org +root = true + +[*] +indent_style = tab +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[gulpfile.js] +indent_style = space +indent_size = 2 + +[*.yml] +indent_style = space +indent_size = 2 diff --git a/htdocs/includes/chart/.eslintignore b/htdocs/includes/chart/.eslintignore new file mode 100644 index 00000000000..96212a3593b --- /dev/null +++ b/htdocs/includes/chart/.eslintignore @@ -0,0 +1 @@ +**/*{.,-}min.js diff --git a/htdocs/includes/chart/.eslintrc.yml b/htdocs/includes/chart/.eslintrc.yml new file mode 100644 index 00000000000..b0d9d5695a9 --- /dev/null +++ b/htdocs/includes/chart/.eslintrc.yml @@ -0,0 +1,7 @@ +extends: chartjs + +env: + browser: true + node: true + +plugins: ['html'] diff --git a/htdocs/includes/chart/.gitignore b/htdocs/includes/chart/.gitignore new file mode 100644 index 00000000000..c4998047b01 --- /dev/null +++ b/htdocs/includes/chart/.gitignore @@ -0,0 +1,16 @@ +/_book +/coverage +/custom +/docs/index.md +/gh-pages +/jsdoc +/node_modules +.DS_Store +.idea +.project +.settings +.vscode +bower.json +*.log +*.swp +*.stackdump diff --git a/htdocs/includes/chart/.htmllintrc b/htdocs/includes/chart/.htmllintrc new file mode 100644 index 00000000000..1ab933490de --- /dev/null +++ b/htdocs/includes/chart/.htmllintrc @@ -0,0 +1,19 @@ +{ + "indent-style": "tabs", + "line-end-style": false, + "attr-quote-style": "double", + "spec-char-escape": false, + "attr-bans": [ + "align", + "background", + "bgcolor", + "border", + "frameborder", + "longdesc", + "marginwidth", + "marginheight", + "scrolling" + ], + "tag-bans": [ "b", "i" ], + "id-class-style": false +} diff --git a/htdocs/includes/chart/.travis.yml b/htdocs/includes/chart/.travis.yml new file mode 100644 index 00000000000..beb8789b46b --- /dev/null +++ b/htdocs/includes/chart/.travis.yml @@ -0,0 +1,55 @@ +language: node_js +node_js: + - lts/* + +before_install: + - "export CHROME_BIN=/usr/bin/google-chrome" + - "export DISPLAY=:99.0" + - "sh -e /etc/init.d/xvfb start" + +script: + - gulp build + - gulp test --coverage + - gulp docs + - gulp package + - gulp bower + - cat ./coverage/lcov.info | ./node_modules/.bin/coveralls || true + +sudo: required +dist: trusty + +addons: + chrome: stable + firefox: latest + +# IMPORTANT: scripts require GITHUB_AUTH_TOKEN and GITHUB_AUTH_EMAIL environment variables +# IMPORTANT: scripts has to be set executables in the Git repository (error 127) +# https://github.com/travis-ci/travis-ci/issues/5538#issuecomment-225025939 + +deploy: +- provider: script + script: ./scripts/deploy.sh + skip_cleanup: true + on: + all_branches: true +- provider: script + script: ./scripts/release.sh + skip_cleanup: true + on: + branch: release +- provider: releases + api_key: $GITHUB_AUTH_TOKEN + skip_cleanup: true + file_glob: true + file: + - ./dist/*.css + - ./dist/*.js + - ./dist/*.zip + on: + tags: true +- provider: npm + email: $NPM_AUTH_EMAIL + api_key: $NPM_AUTH_TOKEN + skip_cleanup: true + on: + tags: true diff --git a/htdocs/includes/chart/LICENSE.md b/htdocs/includes/chart/LICENSE.md new file mode 100644 index 00000000000..29c941dcccf --- /dev/null +++ b/htdocs/includes/chart/LICENSE.md @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright (c) 2018 Chart.js Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/htdocs/includes/chart/MAINTAINING.md b/htdocs/includes/chart/MAINTAINING.md new file mode 100644 index 00000000000..288b03945ff --- /dev/null +++ b/htdocs/includes/chart/MAINTAINING.md @@ -0,0 +1,36 @@ +# Maintaining +## Release Process +Chart.js relies on [Travis CI](https://travis-ci.org/) to automate the library [releases](https://github.com/chartjs/Chart.js/releases). + +### Releasing a New Version + +1. draft release notes on [GitHub](https://github.com/chartjs/Chart.js/releases/new) for the upcoming tag +1. update `master` `package.json` version using [semver](https://semver.org/) semantic +1. merge `master` into the `release` branch +1. follow the build process on [Travis CI](https://travis-ci.org/chartjs/Chart.js) + +> **Note:** if `master` is merged in `release` with a `package.json` version that already exists, the tag +creation fails and the release process is aborted. + +### Automated Tasks +Merging into the `release` branch kicks off the automated release process: + +* build of the `dist/*.js` files +* `bower.json` is generated from `package.json` +* `dist/*.js` and `bower.json` are added to a detached branch +* a tag is created from the `package.json` version +* tag (with dist files) is pushed to GitHub + +Creation of this tag triggers a new build: + +* `Chart.js.zip` package is generated, containing dist files and examples +* `dist/*.js` and `Chart.js.zip` are attached to the GitHub release (downloads) +* a new npm package is published on [npmjs](https://www.npmjs.com/package/chart.js) + +Finally, [cdnjs](https://cdnjs.com/libraries/Chart.js) is automatically updated from the npm release. + +### Further Reading + +* [Travis GitHub releases](https://github.com/chartjs/Chart.js/pull/2555) +* [Bower support and dist/* files](https://github.com/chartjs/Chart.js/issues/3033) +* [cdnjs npm auto update](https://github.com/cdnjs/cdnjs/pull/8401) diff --git a/htdocs/includes/chart/README.md b/htdocs/includes/chart/README.md new file mode 100644 index 00000000000..5a522a5e915 --- /dev/null +++ b/htdocs/includes/chart/README.md @@ -0,0 +1,32 @@ +

+
+ Simple yet flexible JavaScript charting for designers & developers +

+ +

+ Downloads + Builds + Coverage + Awesome + Slack +

+ +## Documentation + +- [Introduction](https://www.chartjs.org/docs/latest/) +- [Getting Started](https://www.chartjs.org/docs/latest/getting-started/) +- [General](https://www.chartjs.org/docs/latest/general/) +- [Configuration](https://www.chartjs.org/docs/latest/configuration/) +- [Charts](https://www.chartjs.org/docs/latest/charts/) +- [Axes](https://www.chartjs.org/docs/latest/axes/) +- [Developers](https://www.chartjs.org/docs/latest/developers/) +- [Popular Extensions](https://github.com/chartjs/awesome) +- [Samples](https://www.chartjs.org/samples/) + +## Contributing + +Instructions on building and testing Chart.js can be found in [the documentation](https://github.com/chartjs/Chart.js/blob/master/docs/developers/contributing.md#building-and-testing). Before submitting an issue or a pull request, please take a moment to look over the [contributing guidelines](https://github.com/chartjs/Chart.js/blob/master/docs/developers/contributing.md) first. For support, please post questions on [Stack Overflow](https://stackoverflow.com/questions/tagged/chartjs) with the `chartjs` tag. + +## License + +Chart.js is available under the [MIT license](https://opensource.org/licenses/MIT). diff --git a/htdocs/includes/chart/book.json b/htdocs/includes/chart/book.json new file mode 100644 index 00000000000..22acbde968c --- /dev/null +++ b/htdocs/includes/chart/book.json @@ -0,0 +1,32 @@ +{ + "root": "./docs", + "title": "Chart.js documentation", + "author": "chartjs", + "gitbook": "3.2.2", + "plugins": [ + "-lunr", + "-search", + "search-plus", + "anchorjs", + "chartjs", + "ga", + "redirect" + ], + "pluginsConfig": { + "anchorjs": { + "icon": "#", + "placement": "left", + "visible": "always" + }, + "ga": { + "token": "UA-28909194-3", + "configuration": "auto" + }, + "theme-default": { + "showLevel": false, + "styles": { + "website": "style.css" + } + } + } +} diff --git a/htdocs/includes/chart/composer.json b/htdocs/includes/chart/composer.json new file mode 100644 index 00000000000..b332bb0f595 --- /dev/null +++ b/htdocs/includes/chart/composer.json @@ -0,0 +1,26 @@ +{ + "name": "nnnick/chartjs", + "type": "library", + "description": "Simple HTML5 charts using the canvas element.", + "keywords": [ + "chart", + "js" + ], + "homepage": "https://www.chartjs.org/", + "license": "MIT", + "authors": [ + { + "name": "NICK DOWNIE", + "email": "hello@nickdownie.com" + } + ], + "require": { + "php": ">=5.3.3" + }, + "minimum-stability": "stable", + "extra": { + "branch-alias": { + "release/2.0": "v2.0-dev" + } + } +} diff --git a/htdocs/includes/chart/dist/Chart.bundle.js b/htdocs/includes/chart/dist/Chart.bundle.js new file mode 100644 index 00000000000..204156a8fc7 --- /dev/null +++ b/htdocs/includes/chart/dist/Chart.bundle.js @@ -0,0 +1,20755 @@ +/*! + * Chart.js v2.9.3 + * https://www.chartjs.org + * (c) 2019 Chart.js Contributors + * Released under the MIT License + */ +(function (global, factory) { +typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : +typeof define === 'function' && define.amd ? define(factory) : +(global = global || self, global.Chart = factory()); +}(this, (function () { 'use strict'; + +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function commonjsRequire () { + throw new Error('Dynamic requires are not currently supported by rollup-plugin-commonjs'); +} + +function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; +} + +function getCjsExportFromNamespace (n) { + return n && n['default'] || n; +} + +var colorName = { + "aliceblue": [240, 248, 255], + "antiquewhite": [250, 235, 215], + "aqua": [0, 255, 255], + "aquamarine": [127, 255, 212], + "azure": [240, 255, 255], + "beige": [245, 245, 220], + "bisque": [255, 228, 196], + "black": [0, 0, 0], + "blanchedalmond": [255, 235, 205], + "blue": [0, 0, 255], + "blueviolet": [138, 43, 226], + "brown": [165, 42, 42], + "burlywood": [222, 184, 135], + "cadetblue": [95, 158, 160], + "chartreuse": [127, 255, 0], + "chocolate": [210, 105, 30], + "coral": [255, 127, 80], + "cornflowerblue": [100, 149, 237], + "cornsilk": [255, 248, 220], + "crimson": [220, 20, 60], + "cyan": [0, 255, 255], + "darkblue": [0, 0, 139], + "darkcyan": [0, 139, 139], + "darkgoldenrod": [184, 134, 11], + "darkgray": [169, 169, 169], + "darkgreen": [0, 100, 0], + "darkgrey": [169, 169, 169], + "darkkhaki": [189, 183, 107], + "darkmagenta": [139, 0, 139], + "darkolivegreen": [85, 107, 47], + "darkorange": [255, 140, 0], + "darkorchid": [153, 50, 204], + "darkred": [139, 0, 0], + "darksalmon": [233, 150, 122], + "darkseagreen": [143, 188, 143], + "darkslateblue": [72, 61, 139], + "darkslategray": [47, 79, 79], + "darkslategrey": [47, 79, 79], + "darkturquoise": [0, 206, 209], + "darkviolet": [148, 0, 211], + "deeppink": [255, 20, 147], + "deepskyblue": [0, 191, 255], + "dimgray": [105, 105, 105], + "dimgrey": [105, 105, 105], + "dodgerblue": [30, 144, 255], + "firebrick": [178, 34, 34], + "floralwhite": [255, 250, 240], + "forestgreen": [34, 139, 34], + "fuchsia": [255, 0, 255], + "gainsboro": [220, 220, 220], + "ghostwhite": [248, 248, 255], + "gold": [255, 215, 0], + "goldenrod": [218, 165, 32], + "gray": [128, 128, 128], + "green": [0, 128, 0], + "greenyellow": [173, 255, 47], + "grey": [128, 128, 128], + "honeydew": [240, 255, 240], + "hotpink": [255, 105, 180], + "indianred": [205, 92, 92], + "indigo": [75, 0, 130], + "ivory": [255, 255, 240], + "khaki": [240, 230, 140], + "lavender": [230, 230, 250], + "lavenderblush": [255, 240, 245], + "lawngreen": [124, 252, 0], + "lemonchiffon": [255, 250, 205], + "lightblue": [173, 216, 230], + "lightcoral": [240, 128, 128], + "lightcyan": [224, 255, 255], + "lightgoldenrodyellow": [250, 250, 210], + "lightgray": [211, 211, 211], + "lightgreen": [144, 238, 144], + "lightgrey": [211, 211, 211], + "lightpink": [255, 182, 193], + "lightsalmon": [255, 160, 122], + "lightseagreen": [32, 178, 170], + "lightskyblue": [135, 206, 250], + "lightslategray": [119, 136, 153], + "lightslategrey": [119, 136, 153], + "lightsteelblue": [176, 196, 222], + "lightyellow": [255, 255, 224], + "lime": [0, 255, 0], + "limegreen": [50, 205, 50], + "linen": [250, 240, 230], + "magenta": [255, 0, 255], + "maroon": [128, 0, 0], + "mediumaquamarine": [102, 205, 170], + "mediumblue": [0, 0, 205], + "mediumorchid": [186, 85, 211], + "mediumpurple": [147, 112, 219], + "mediumseagreen": [60, 179, 113], + "mediumslateblue": [123, 104, 238], + "mediumspringgreen": [0, 250, 154], + "mediumturquoise": [72, 209, 204], + "mediumvioletred": [199, 21, 133], + "midnightblue": [25, 25, 112], + "mintcream": [245, 255, 250], + "mistyrose": [255, 228, 225], + "moccasin": [255, 228, 181], + "navajowhite": [255, 222, 173], + "navy": [0, 0, 128], + "oldlace": [253, 245, 230], + "olive": [128, 128, 0], + "olivedrab": [107, 142, 35], + "orange": [255, 165, 0], + "orangered": [255, 69, 0], + "orchid": [218, 112, 214], + "palegoldenrod": [238, 232, 170], + "palegreen": [152, 251, 152], + "paleturquoise": [175, 238, 238], + "palevioletred": [219, 112, 147], + "papayawhip": [255, 239, 213], + "peachpuff": [255, 218, 185], + "peru": [205, 133, 63], + "pink": [255, 192, 203], + "plum": [221, 160, 221], + "powderblue": [176, 224, 230], + "purple": [128, 0, 128], + "rebeccapurple": [102, 51, 153], + "red": [255, 0, 0], + "rosybrown": [188, 143, 143], + "royalblue": [65, 105, 225], + "saddlebrown": [139, 69, 19], + "salmon": [250, 128, 114], + "sandybrown": [244, 164, 96], + "seagreen": [46, 139, 87], + "seashell": [255, 245, 238], + "sienna": [160, 82, 45], + "silver": [192, 192, 192], + "skyblue": [135, 206, 235], + "slateblue": [106, 90, 205], + "slategray": [112, 128, 144], + "slategrey": [112, 128, 144], + "snow": [255, 250, 250], + "springgreen": [0, 255, 127], + "steelblue": [70, 130, 180], + "tan": [210, 180, 140], + "teal": [0, 128, 128], + "thistle": [216, 191, 216], + "tomato": [255, 99, 71], + "turquoise": [64, 224, 208], + "violet": [238, 130, 238], + "wheat": [245, 222, 179], + "white": [255, 255, 255], + "whitesmoke": [245, 245, 245], + "yellow": [255, 255, 0], + "yellowgreen": [154, 205, 50] +}; + +var conversions = createCommonjsModule(function (module) { +/* MIT license */ + + +// NOTE: conversions should only return primitive values (i.e. arrays, or +// values that give correct `typeof` results). +// do not use box values types (i.e. Number(), String(), etc.) + +var reverseKeywords = {}; +for (var key in colorName) { + if (colorName.hasOwnProperty(key)) { + reverseKeywords[colorName[key]] = key; + } +} + +var convert = module.exports = { + rgb: {channels: 3, labels: 'rgb'}, + hsl: {channels: 3, labels: 'hsl'}, + hsv: {channels: 3, labels: 'hsv'}, + hwb: {channels: 3, labels: 'hwb'}, + cmyk: {channels: 4, labels: 'cmyk'}, + xyz: {channels: 3, labels: 'xyz'}, + lab: {channels: 3, labels: 'lab'}, + lch: {channels: 3, labels: 'lch'}, + hex: {channels: 1, labels: ['hex']}, + keyword: {channels: 1, labels: ['keyword']}, + ansi16: {channels: 1, labels: ['ansi16']}, + ansi256: {channels: 1, labels: ['ansi256']}, + hcg: {channels: 3, labels: ['h', 'c', 'g']}, + apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, + gray: {channels: 1, labels: ['gray']} +}; + +// hide .channels and .labels properties +for (var model in convert) { + if (convert.hasOwnProperty(model)) { + if (!('channels' in convert[model])) { + throw new Error('missing channels property: ' + model); + } + + if (!('labels' in convert[model])) { + throw new Error('missing channel labels property: ' + model); + } + + if (convert[model].labels.length !== convert[model].channels) { + throw new Error('channel and label counts mismatch: ' + model); + } + + var channels = convert[model].channels; + var labels = convert[model].labels; + delete convert[model].channels; + delete convert[model].labels; + Object.defineProperty(convert[model], 'channels', {value: channels}); + Object.defineProperty(convert[model], 'labels', {value: labels}); + } +} + +convert.rgb.hsl = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var min = Math.min(r, g, b); + var max = Math.max(r, g, b); + var delta = max - min; + var h; + var s; + var l; + + if (max === min) { + h = 0; + } else if (r === max) { + h = (g - b) / delta; + } else if (g === max) { + h = 2 + (b - r) / delta; + } else if (b === max) { + h = 4 + (r - g) / delta; + } + + h = Math.min(h * 60, 360); + + if (h < 0) { + h += 360; + } + + l = (min + max) / 2; + + if (max === min) { + s = 0; + } else if (l <= 0.5) { + s = delta / (max + min); + } else { + s = delta / (2 - max - min); + } + + return [h, s * 100, l * 100]; +}; + +convert.rgb.hsv = function (rgb) { + var rdif; + var gdif; + var bdif; + var h; + var s; + + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var v = Math.max(r, g, b); + var diff = v - Math.min(r, g, b); + var diffc = function (c) { + return (v - c) / 6 / diff + 1 / 2; + }; + + if (diff === 0) { + h = s = 0; + } else { + s = diff / v; + rdif = diffc(r); + gdif = diffc(g); + bdif = diffc(b); + + if (r === v) { + h = bdif - gdif; + } else if (g === v) { + h = (1 / 3) + rdif - bdif; + } else if (b === v) { + h = (2 / 3) + gdif - rdif; + } + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + } + + return [ + h * 360, + s * 100, + v * 100 + ]; +}; + +convert.rgb.hwb = function (rgb) { + var r = rgb[0]; + var g = rgb[1]; + var b = rgb[2]; + var h = convert.rgb.hsl(rgb)[0]; + var w = 1 / 255 * Math.min(r, Math.min(g, b)); + + b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); + + return [h, w * 100, b * 100]; +}; + +convert.rgb.cmyk = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var c; + var m; + var y; + var k; + + k = Math.min(1 - r, 1 - g, 1 - b); + c = (1 - r - k) / (1 - k) || 0; + m = (1 - g - k) / (1 - k) || 0; + y = (1 - b - k) / (1 - k) || 0; + + return [c * 100, m * 100, y * 100, k * 100]; +}; + +/** + * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance + * */ +function comparativeDistance(x, y) { + return ( + Math.pow(x[0] - y[0], 2) + + Math.pow(x[1] - y[1], 2) + + Math.pow(x[2] - y[2], 2) + ); +} + +convert.rgb.keyword = function (rgb) { + var reversed = reverseKeywords[rgb]; + if (reversed) { + return reversed; + } + + var currentClosestDistance = Infinity; + var currentClosestKeyword; + + for (var keyword in colorName) { + if (colorName.hasOwnProperty(keyword)) { + var value = colorName[keyword]; + + // Compute comparative distance + var distance = comparativeDistance(rgb, value); + + // Check if its less, if so set as closest + if (distance < currentClosestDistance) { + currentClosestDistance = distance; + currentClosestKeyword = keyword; + } + } + } + + return currentClosestKeyword; +}; + +convert.keyword.rgb = function (keyword) { + return colorName[keyword]; +}; + +convert.rgb.xyz = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + + // assume sRGB + r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); + g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); + b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); + + var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); + var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); + var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); + + return [x * 100, y * 100, z * 100]; +}; + +convert.rgb.lab = function (rgb) { + var xyz = convert.rgb.xyz(rgb); + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var b; + + x /= 95.047; + y /= 100; + z /= 108.883; + + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); + + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); + + return [l, a, b]; +}; + +convert.hsl.rgb = function (hsl) { + var h = hsl[0] / 360; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var t1; + var t2; + var t3; + var rgb; + var val; + + if (s === 0) { + val = l * 255; + return [val, val, val]; + } + + if (l < 0.5) { + t2 = l * (1 + s); + } else { + t2 = l + s - l * s; + } + + t1 = 2 * l - t2; + + rgb = [0, 0, 0]; + for (var i = 0; i < 3; i++) { + t3 = h + 1 / 3 * -(i - 1); + if (t3 < 0) { + t3++; + } + if (t3 > 1) { + t3--; + } + + if (6 * t3 < 1) { + val = t1 + (t2 - t1) * 6 * t3; + } else if (2 * t3 < 1) { + val = t2; + } else if (3 * t3 < 2) { + val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; + } else { + val = t1; + } + + rgb[i] = val * 255; + } + + return rgb; +}; + +convert.hsl.hsv = function (hsl) { + var h = hsl[0]; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var smin = s; + var lmin = Math.max(l, 0.01); + var sv; + var v; + + l *= 2; + s *= (l <= 1) ? l : 2 - l; + smin *= lmin <= 1 ? lmin : 2 - lmin; + v = (l + s) / 2; + sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); + + return [h, sv * 100, v * 100]; +}; + +convert.hsv.rgb = function (hsv) { + var h = hsv[0] / 60; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var hi = Math.floor(h) % 6; + + var f = h - Math.floor(h); + var p = 255 * v * (1 - s); + var q = 255 * v * (1 - (s * f)); + var t = 255 * v * (1 - (s * (1 - f))); + v *= 255; + + switch (hi) { + case 0: + return [v, t, p]; + case 1: + return [q, v, p]; + case 2: + return [p, v, t]; + case 3: + return [p, q, v]; + case 4: + return [t, p, v]; + case 5: + return [v, p, q]; + } +}; + +convert.hsv.hsl = function (hsv) { + var h = hsv[0]; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var vmin = Math.max(v, 0.01); + var lmin; + var sl; + var l; + + l = (2 - s) * v; + lmin = (2 - s) * vmin; + sl = s * vmin; + sl /= (lmin <= 1) ? lmin : 2 - lmin; + sl = sl || 0; + l /= 2; + + return [h, sl * 100, l * 100]; +}; + +// http://dev.w3.org/csswg/css-color/#hwb-to-rgb +convert.hwb.rgb = function (hwb) { + var h = hwb[0] / 360; + var wh = hwb[1] / 100; + var bl = hwb[2] / 100; + var ratio = wh + bl; + var i; + var v; + var f; + var n; + + // wh + bl cant be > 1 + if (ratio > 1) { + wh /= ratio; + bl /= ratio; + } + + i = Math.floor(6 * h); + v = 1 - bl; + f = 6 * h - i; + + if ((i & 0x01) !== 0) { + f = 1 - f; + } + + n = wh + f * (v - wh); // linear interpolation + + var r; + var g; + var b; + switch (i) { + default: + case 6: + case 0: r = v; g = n; b = wh; break; + case 1: r = n; g = v; b = wh; break; + case 2: r = wh; g = v; b = n; break; + case 3: r = wh; g = n; b = v; break; + case 4: r = n; g = wh; b = v; break; + case 5: r = v; g = wh; b = n; break; + } + + return [r * 255, g * 255, b * 255]; +}; + +convert.cmyk.rgb = function (cmyk) { + var c = cmyk[0] / 100; + var m = cmyk[1] / 100; + var y = cmyk[2] / 100; + var k = cmyk[3] / 100; + var r; + var g; + var b; + + r = 1 - Math.min(1, c * (1 - k) + k); + g = 1 - Math.min(1, m * (1 - k) + k); + b = 1 - Math.min(1, y * (1 - k) + k); + + return [r * 255, g * 255, b * 255]; +}; + +convert.xyz.rgb = function (xyz) { + var x = xyz[0] / 100; + var y = xyz[1] / 100; + var z = xyz[2] / 100; + var r; + var g; + var b; + + r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); + g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); + b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); + + // assume sRGB + r = r > 0.0031308 + ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) + : r * 12.92; + + g = g > 0.0031308 + ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) + : g * 12.92; + + b = b > 0.0031308 + ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) + : b * 12.92; + + r = Math.min(Math.max(0, r), 1); + g = Math.min(Math.max(0, g), 1); + b = Math.min(Math.max(0, b), 1); + + return [r * 255, g * 255, b * 255]; +}; + +convert.xyz.lab = function (xyz) { + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var b; + + x /= 95.047; + y /= 100; + z /= 108.883; + + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); + + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); + + return [l, a, b]; +}; + +convert.lab.xyz = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var x; + var y; + var z; + + y = (l + 16) / 116; + x = a / 500 + y; + z = y - b / 200; + + var y2 = Math.pow(y, 3); + var x2 = Math.pow(x, 3); + var z2 = Math.pow(z, 3); + y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; + x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; + z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; + + x *= 95.047; + y *= 100; + z *= 108.883; + + return [x, y, z]; +}; + +convert.lab.lch = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var hr; + var h; + var c; + + hr = Math.atan2(b, a); + h = hr * 360 / 2 / Math.PI; + + if (h < 0) { + h += 360; + } + + c = Math.sqrt(a * a + b * b); + + return [l, c, h]; +}; + +convert.lch.lab = function (lch) { + var l = lch[0]; + var c = lch[1]; + var h = lch[2]; + var a; + var b; + var hr; + + hr = h / 360 * 2 * Math.PI; + a = c * Math.cos(hr); + b = c * Math.sin(hr); + + return [l, a, b]; +}; + +convert.rgb.ansi16 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; + var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization + + value = Math.round(value / 50); + + if (value === 0) { + return 30; + } + + var ansi = 30 + + ((Math.round(b / 255) << 2) + | (Math.round(g / 255) << 1) + | Math.round(r / 255)); + + if (value === 2) { + ansi += 60; + } + + return ansi; +}; + +convert.hsv.ansi16 = function (args) { + // optimization here; we already know the value and don't need to get + // it converted for us. + return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]); +}; + +convert.rgb.ansi256 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; + + // we use the extended greyscale palette here, with the exception of + // black and white. normal palette only has 4 greyscale shades. + if (r === g && g === b) { + if (r < 8) { + return 16; + } + + if (r > 248) { + return 231; + } + + return Math.round(((r - 8) / 247) * 24) + 232; + } + + var ansi = 16 + + (36 * Math.round(r / 255 * 5)) + + (6 * Math.round(g / 255 * 5)) + + Math.round(b / 255 * 5); + + return ansi; +}; + +convert.ansi16.rgb = function (args) { + var color = args % 10; + + // handle greyscale + if (color === 0 || color === 7) { + if (args > 50) { + color += 3.5; + } + + color = color / 10.5 * 255; + + return [color, color, color]; + } + + var mult = (~~(args > 50) + 1) * 0.5; + var r = ((color & 1) * mult) * 255; + var g = (((color >> 1) & 1) * mult) * 255; + var b = (((color >> 2) & 1) * mult) * 255; + + return [r, g, b]; +}; + +convert.ansi256.rgb = function (args) { + // handle greyscale + if (args >= 232) { + var c = (args - 232) * 10 + 8; + return [c, c, c]; + } + + args -= 16; + + var rem; + var r = Math.floor(args / 36) / 5 * 255; + var g = Math.floor((rem = args % 36) / 6) / 5 * 255; + var b = (rem % 6) / 5 * 255; + + return [r, g, b]; +}; + +convert.rgb.hex = function (args) { + var integer = ((Math.round(args[0]) & 0xFF) << 16) + + ((Math.round(args[1]) & 0xFF) << 8) + + (Math.round(args[2]) & 0xFF); + + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; + +convert.hex.rgb = function (args) { + var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); + if (!match) { + return [0, 0, 0]; + } + + var colorString = match[0]; + + if (match[0].length === 3) { + colorString = colorString.split('').map(function (char) { + return char + char; + }).join(''); + } + + var integer = parseInt(colorString, 16); + var r = (integer >> 16) & 0xFF; + var g = (integer >> 8) & 0xFF; + var b = integer & 0xFF; + + return [r, g, b]; +}; + +convert.rgb.hcg = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var max = Math.max(Math.max(r, g), b); + var min = Math.min(Math.min(r, g), b); + var chroma = (max - min); + var grayscale; + var hue; + + if (chroma < 1) { + grayscale = min / (1 - chroma); + } else { + grayscale = 0; + } + + if (chroma <= 0) { + hue = 0; + } else + if (max === r) { + hue = ((g - b) / chroma) % 6; + } else + if (max === g) { + hue = 2 + (b - r) / chroma; + } else { + hue = 4 + (r - g) / chroma + 4; + } + + hue /= 6; + hue %= 1; + + return [hue * 360, chroma * 100, grayscale * 100]; +}; + +convert.hsl.hcg = function (hsl) { + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var c = 1; + var f = 0; + + if (l < 0.5) { + c = 2.0 * s * l; + } else { + c = 2.0 * s * (1.0 - l); + } + + if (c < 1.0) { + f = (l - 0.5 * c) / (1.0 - c); + } + + return [hsl[0], c * 100, f * 100]; +}; + +convert.hsv.hcg = function (hsv) { + var s = hsv[1] / 100; + var v = hsv[2] / 100; + + var c = s * v; + var f = 0; + + if (c < 1.0) { + f = (v - c) / (1 - c); + } + + return [hsv[0], c * 100, f * 100]; +}; + +convert.hcg.rgb = function (hcg) { + var h = hcg[0] / 360; + var c = hcg[1] / 100; + var g = hcg[2] / 100; + + if (c === 0.0) { + return [g * 255, g * 255, g * 255]; + } + + var pure = [0, 0, 0]; + var hi = (h % 1) * 6; + var v = hi % 1; + var w = 1 - v; + var mg = 0; + + switch (Math.floor(hi)) { + case 0: + pure[0] = 1; pure[1] = v; pure[2] = 0; break; + case 1: + pure[0] = w; pure[1] = 1; pure[2] = 0; break; + case 2: + pure[0] = 0; pure[1] = 1; pure[2] = v; break; + case 3: + pure[0] = 0; pure[1] = w; pure[2] = 1; break; + case 4: + pure[0] = v; pure[1] = 0; pure[2] = 1; break; + default: + pure[0] = 1; pure[1] = 0; pure[2] = w; + } + + mg = (1.0 - c) * g; + + return [ + (c * pure[0] + mg) * 255, + (c * pure[1] + mg) * 255, + (c * pure[2] + mg) * 255 + ]; +}; + +convert.hcg.hsv = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + + var v = c + g * (1.0 - c); + var f = 0; + + if (v > 0.0) { + f = c / v; + } + + return [hcg[0], f * 100, v * 100]; +}; + +convert.hcg.hsl = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + + var l = g * (1.0 - c) + 0.5 * c; + var s = 0; + + if (l > 0.0 && l < 0.5) { + s = c / (2 * l); + } else + if (l >= 0.5 && l < 1.0) { + s = c / (2 * (1 - l)); + } + + return [hcg[0], s * 100, l * 100]; +}; + +convert.hcg.hwb = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + var v = c + g * (1.0 - c); + return [hcg[0], (v - c) * 100, (1 - v) * 100]; +}; + +convert.hwb.hcg = function (hwb) { + var w = hwb[1] / 100; + var b = hwb[2] / 100; + var v = 1 - b; + var c = v - w; + var g = 0; + + if (c < 1) { + g = (v - c) / (1 - c); + } + + return [hwb[0], c * 100, g * 100]; +}; + +convert.apple.rgb = function (apple) { + return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; +}; + +convert.rgb.apple = function (rgb) { + return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; +}; + +convert.gray.rgb = function (args) { + return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; +}; + +convert.gray.hsl = convert.gray.hsv = function (args) { + return [0, 0, args[0]]; +}; + +convert.gray.hwb = function (gray) { + return [0, 100, gray[0]]; +}; + +convert.gray.cmyk = function (gray) { + return [0, 0, 0, gray[0]]; +}; + +convert.gray.lab = function (gray) { + return [gray[0], 0, 0]; +}; + +convert.gray.hex = function (gray) { + var val = Math.round(gray[0] / 100 * 255) & 0xFF; + var integer = (val << 16) + (val << 8) + val; + + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; + +convert.rgb.gray = function (rgb) { + var val = (rgb[0] + rgb[1] + rgb[2]) / 3; + return [val / 255 * 100]; +}; +}); +var conversions_1 = conversions.rgb; +var conversions_2 = conversions.hsl; +var conversions_3 = conversions.hsv; +var conversions_4 = conversions.hwb; +var conversions_5 = conversions.cmyk; +var conversions_6 = conversions.xyz; +var conversions_7 = conversions.lab; +var conversions_8 = conversions.lch; +var conversions_9 = conversions.hex; +var conversions_10 = conversions.keyword; +var conversions_11 = conversions.ansi16; +var conversions_12 = conversions.ansi256; +var conversions_13 = conversions.hcg; +var conversions_14 = conversions.apple; +var conversions_15 = conversions.gray; + +/* + this function routes a model to all other models. + + all functions that are routed have a property `.conversion` attached + to the returned synthetic function. This property is an array + of strings, each with the steps in between the 'from' and 'to' + color models (inclusive). + + conversions that are not possible simply are not included. +*/ + +function buildGraph() { + var graph = {}; + // https://jsperf.com/object-keys-vs-for-in-with-closure/3 + var models = Object.keys(conversions); + + for (var len = models.length, i = 0; i < len; i++) { + graph[models[i]] = { + // http://jsperf.com/1-vs-infinity + // micro-opt, but this is simple. + distance: -1, + parent: null + }; + } + + return graph; +} + +// https://en.wikipedia.org/wiki/Breadth-first_search +function deriveBFS(fromModel) { + var graph = buildGraph(); + var queue = [fromModel]; // unshift -> queue -> pop + + graph[fromModel].distance = 0; + + while (queue.length) { + var current = queue.pop(); + var adjacents = Object.keys(conversions[current]); + + for (var len = adjacents.length, i = 0; i < len; i++) { + var adjacent = adjacents[i]; + var node = graph[adjacent]; + + if (node.distance === -1) { + node.distance = graph[current].distance + 1; + node.parent = current; + queue.unshift(adjacent); + } + } + } + + return graph; +} + +function link(from, to) { + return function (args) { + return to(from(args)); + }; +} + +function wrapConversion(toModel, graph) { + var path = [graph[toModel].parent, toModel]; + var fn = conversions[graph[toModel].parent][toModel]; + + var cur = graph[toModel].parent; + while (graph[cur].parent) { + path.unshift(graph[cur].parent); + fn = link(conversions[graph[cur].parent][cur], fn); + cur = graph[cur].parent; + } + + fn.conversion = path; + return fn; +} + +var route = function (fromModel) { + var graph = deriveBFS(fromModel); + var conversion = {}; + + var models = Object.keys(graph); + for (var len = models.length, i = 0; i < len; i++) { + var toModel = models[i]; + var node = graph[toModel]; + + if (node.parent === null) { + // no possible conversion, or this node is the source model. + continue; + } + + conversion[toModel] = wrapConversion(toModel, graph); + } + + return conversion; +}; + +var convert = {}; + +var models = Object.keys(conversions); + +function wrapRaw(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } + + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } + + return fn(args); + }; + + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } + + return wrappedFn; +} + +function wrapRounded(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } + + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } + + var result = fn(args); + + // we're assuming the result is an array here. + // see notice in conversions.js; don't use box types + // in conversion functions. + if (typeof result === 'object') { + for (var len = result.length, i = 0; i < len; i++) { + result[i] = Math.round(result[i]); + } + } + + return result; + }; + + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } + + return wrappedFn; +} + +models.forEach(function (fromModel) { + convert[fromModel] = {}; + + Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); + Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); + + var routes = route(fromModel); + var routeModels = Object.keys(routes); + + routeModels.forEach(function (toModel) { + var fn = routes[toModel]; + + convert[fromModel][toModel] = wrapRounded(fn); + convert[fromModel][toModel].raw = wrapRaw(fn); + }); +}); + +var colorConvert = convert; + +var colorName$1 = { + "aliceblue": [240, 248, 255], + "antiquewhite": [250, 235, 215], + "aqua": [0, 255, 255], + "aquamarine": [127, 255, 212], + "azure": [240, 255, 255], + "beige": [245, 245, 220], + "bisque": [255, 228, 196], + "black": [0, 0, 0], + "blanchedalmond": [255, 235, 205], + "blue": [0, 0, 255], + "blueviolet": [138, 43, 226], + "brown": [165, 42, 42], + "burlywood": [222, 184, 135], + "cadetblue": [95, 158, 160], + "chartreuse": [127, 255, 0], + "chocolate": [210, 105, 30], + "coral": [255, 127, 80], + "cornflowerblue": [100, 149, 237], + "cornsilk": [255, 248, 220], + "crimson": [220, 20, 60], + "cyan": [0, 255, 255], + "darkblue": [0, 0, 139], + "darkcyan": [0, 139, 139], + "darkgoldenrod": [184, 134, 11], + "darkgray": [169, 169, 169], + "darkgreen": [0, 100, 0], + "darkgrey": [169, 169, 169], + "darkkhaki": [189, 183, 107], + "darkmagenta": [139, 0, 139], + "darkolivegreen": [85, 107, 47], + "darkorange": [255, 140, 0], + "darkorchid": [153, 50, 204], + "darkred": [139, 0, 0], + "darksalmon": [233, 150, 122], + "darkseagreen": [143, 188, 143], + "darkslateblue": [72, 61, 139], + "darkslategray": [47, 79, 79], + "darkslategrey": [47, 79, 79], + "darkturquoise": [0, 206, 209], + "darkviolet": [148, 0, 211], + "deeppink": [255, 20, 147], + "deepskyblue": [0, 191, 255], + "dimgray": [105, 105, 105], + "dimgrey": [105, 105, 105], + "dodgerblue": [30, 144, 255], + "firebrick": [178, 34, 34], + "floralwhite": [255, 250, 240], + "forestgreen": [34, 139, 34], + "fuchsia": [255, 0, 255], + "gainsboro": [220, 220, 220], + "ghostwhite": [248, 248, 255], + "gold": [255, 215, 0], + "goldenrod": [218, 165, 32], + "gray": [128, 128, 128], + "green": [0, 128, 0], + "greenyellow": [173, 255, 47], + "grey": [128, 128, 128], + "honeydew": [240, 255, 240], + "hotpink": [255, 105, 180], + "indianred": [205, 92, 92], + "indigo": [75, 0, 130], + "ivory": [255, 255, 240], + "khaki": [240, 230, 140], + "lavender": [230, 230, 250], + "lavenderblush": [255, 240, 245], + "lawngreen": [124, 252, 0], + "lemonchiffon": [255, 250, 205], + "lightblue": [173, 216, 230], + "lightcoral": [240, 128, 128], + "lightcyan": [224, 255, 255], + "lightgoldenrodyellow": [250, 250, 210], + "lightgray": [211, 211, 211], + "lightgreen": [144, 238, 144], + "lightgrey": [211, 211, 211], + "lightpink": [255, 182, 193], + "lightsalmon": [255, 160, 122], + "lightseagreen": [32, 178, 170], + "lightskyblue": [135, 206, 250], + "lightslategray": [119, 136, 153], + "lightslategrey": [119, 136, 153], + "lightsteelblue": [176, 196, 222], + "lightyellow": [255, 255, 224], + "lime": [0, 255, 0], + "limegreen": [50, 205, 50], + "linen": [250, 240, 230], + "magenta": [255, 0, 255], + "maroon": [128, 0, 0], + "mediumaquamarine": [102, 205, 170], + "mediumblue": [0, 0, 205], + "mediumorchid": [186, 85, 211], + "mediumpurple": [147, 112, 219], + "mediumseagreen": [60, 179, 113], + "mediumslateblue": [123, 104, 238], + "mediumspringgreen": [0, 250, 154], + "mediumturquoise": [72, 209, 204], + "mediumvioletred": [199, 21, 133], + "midnightblue": [25, 25, 112], + "mintcream": [245, 255, 250], + "mistyrose": [255, 228, 225], + "moccasin": [255, 228, 181], + "navajowhite": [255, 222, 173], + "navy": [0, 0, 128], + "oldlace": [253, 245, 230], + "olive": [128, 128, 0], + "olivedrab": [107, 142, 35], + "orange": [255, 165, 0], + "orangered": [255, 69, 0], + "orchid": [218, 112, 214], + "palegoldenrod": [238, 232, 170], + "palegreen": [152, 251, 152], + "paleturquoise": [175, 238, 238], + "palevioletred": [219, 112, 147], + "papayawhip": [255, 239, 213], + "peachpuff": [255, 218, 185], + "peru": [205, 133, 63], + "pink": [255, 192, 203], + "plum": [221, 160, 221], + "powderblue": [176, 224, 230], + "purple": [128, 0, 128], + "rebeccapurple": [102, 51, 153], + "red": [255, 0, 0], + "rosybrown": [188, 143, 143], + "royalblue": [65, 105, 225], + "saddlebrown": [139, 69, 19], + "salmon": [250, 128, 114], + "sandybrown": [244, 164, 96], + "seagreen": [46, 139, 87], + "seashell": [255, 245, 238], + "sienna": [160, 82, 45], + "silver": [192, 192, 192], + "skyblue": [135, 206, 235], + "slateblue": [106, 90, 205], + "slategray": [112, 128, 144], + "slategrey": [112, 128, 144], + "snow": [255, 250, 250], + "springgreen": [0, 255, 127], + "steelblue": [70, 130, 180], + "tan": [210, 180, 140], + "teal": [0, 128, 128], + "thistle": [216, 191, 216], + "tomato": [255, 99, 71], + "turquoise": [64, 224, 208], + "violet": [238, 130, 238], + "wheat": [245, 222, 179], + "white": [255, 255, 255], + "whitesmoke": [245, 245, 245], + "yellow": [255, 255, 0], + "yellowgreen": [154, 205, 50] +}; + +/* MIT license */ + + +var colorString = { + getRgba: getRgba, + getHsla: getHsla, + getRgb: getRgb, + getHsl: getHsl, + getHwb: getHwb, + getAlpha: getAlpha, + + hexString: hexString, + rgbString: rgbString, + rgbaString: rgbaString, + percentString: percentString, + percentaString: percentaString, + hslString: hslString, + hslaString: hslaString, + hwbString: hwbString, + keyword: keyword +}; + +function getRgba(string) { + if (!string) { + return; + } + var abbr = /^#([a-fA-F0-9]{3,4})$/i, + hex = /^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i, + rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i, + per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/i, + keyword = /(\w+)/; + + var rgb = [0, 0, 0], + a = 1, + match = string.match(abbr), + hexAlpha = ""; + if (match) { + match = match[1]; + hexAlpha = match[3]; + for (var i = 0; i < rgb.length; i++) { + rgb[i] = parseInt(match[i] + match[i], 16); + } + if (hexAlpha) { + a = Math.round((parseInt(hexAlpha + hexAlpha, 16) / 255) * 100) / 100; + } + } + else if (match = string.match(hex)) { + hexAlpha = match[2]; + match = match[1]; + for (var i = 0; i < rgb.length; i++) { + rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16); + } + if (hexAlpha) { + a = Math.round((parseInt(hexAlpha, 16) / 255) * 100) / 100; + } + } + else if (match = string.match(rgba)) { + for (var i = 0; i < rgb.length; i++) { + rgb[i] = parseInt(match[i + 1]); + } + a = parseFloat(match[4]); + } + else if (match = string.match(per)) { + for (var i = 0; i < rgb.length; i++) { + rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55); + } + a = parseFloat(match[4]); + } + else if (match = string.match(keyword)) { + if (match[1] == "transparent") { + return [0, 0, 0, 0]; + } + rgb = colorName$1[match[1]]; + if (!rgb) { + return; + } + } + + for (var i = 0; i < rgb.length; i++) { + rgb[i] = scale(rgb[i], 0, 255); + } + if (!a && a != 0) { + a = 1; + } + else { + a = scale(a, 0, 1); + } + rgb[3] = a; + return rgb; +} + +function getHsla(string) { + if (!string) { + return; + } + var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/; + var match = string.match(hsl); + if (match) { + var alpha = parseFloat(match[4]); + var h = scale(parseInt(match[1]), 0, 360), + s = scale(parseFloat(match[2]), 0, 100), + l = scale(parseFloat(match[3]), 0, 100), + a = scale(isNaN(alpha) ? 1 : alpha, 0, 1); + return [h, s, l, a]; + } +} + +function getHwb(string) { + if (!string) { + return; + } + var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/; + var match = string.match(hwb); + if (match) { + var alpha = parseFloat(match[4]); + var h = scale(parseInt(match[1]), 0, 360), + w = scale(parseFloat(match[2]), 0, 100), + b = scale(parseFloat(match[3]), 0, 100), + a = scale(isNaN(alpha) ? 1 : alpha, 0, 1); + return [h, w, b, a]; + } +} + +function getRgb(string) { + var rgba = getRgba(string); + return rgba && rgba.slice(0, 3); +} + +function getHsl(string) { + var hsla = getHsla(string); + return hsla && hsla.slice(0, 3); +} + +function getAlpha(string) { + var vals = getRgba(string); + if (vals) { + return vals[3]; + } + else if (vals = getHsla(string)) { + return vals[3]; + } + else if (vals = getHwb(string)) { + return vals[3]; + } +} + +// generators +function hexString(rgba, a) { + var a = (a !== undefined && rgba.length === 3) ? a : rgba[3]; + return "#" + hexDouble(rgba[0]) + + hexDouble(rgba[1]) + + hexDouble(rgba[2]) + + ( + (a >= 0 && a < 1) + ? hexDouble(Math.round(a * 255)) + : "" + ); +} + +function rgbString(rgba, alpha) { + if (alpha < 1 || (rgba[3] && rgba[3] < 1)) { + return rgbaString(rgba, alpha); + } + return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")"; +} + +function rgbaString(rgba, alpha) { + if (alpha === undefined) { + alpha = (rgba[3] !== undefined ? rgba[3] : 1); + } + return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + + ", " + alpha + ")"; +} + +function percentString(rgba, alpha) { + if (alpha < 1 || (rgba[3] && rgba[3] < 1)) { + return percentaString(rgba, alpha); + } + var r = Math.round(rgba[0]/255 * 100), + g = Math.round(rgba[1]/255 * 100), + b = Math.round(rgba[2]/255 * 100); + + return "rgb(" + r + "%, " + g + "%, " + b + "%)"; +} + +function percentaString(rgba, alpha) { + var r = Math.round(rgba[0]/255 * 100), + g = Math.round(rgba[1]/255 * 100), + b = Math.round(rgba[2]/255 * 100); + return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")"; +} + +function hslString(hsla, alpha) { + if (alpha < 1 || (hsla[3] && hsla[3] < 1)) { + return hslaString(hsla, alpha); + } + return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)"; +} + +function hslaString(hsla, alpha) { + if (alpha === undefined) { + alpha = (hsla[3] !== undefined ? hsla[3] : 1); + } + return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " + + alpha + ")"; +} + +// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax +// (hwb have alpha optional & 1 is default value) +function hwbString(hwb, alpha) { + if (alpha === undefined) { + alpha = (hwb[3] !== undefined ? hwb[3] : 1); + } + return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%" + + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")"; +} + +function keyword(rgb) { + return reverseNames[rgb.slice(0, 3)]; +} + +// helpers +function scale(num, min, max) { + return Math.min(Math.max(min, num), max); +} + +function hexDouble(num) { + var str = num.toString(16).toUpperCase(); + return (str.length < 2) ? "0" + str : str; +} + + +//create a list of reverse color names +var reverseNames = {}; +for (var name in colorName$1) { + reverseNames[colorName$1[name]] = name; +} + +/* MIT license */ + + + +var Color = function (obj) { + if (obj instanceof Color) { + return obj; + } + if (!(this instanceof Color)) { + return new Color(obj); + } + + this.valid = false; + this.values = { + rgb: [0, 0, 0], + hsl: [0, 0, 0], + hsv: [0, 0, 0], + hwb: [0, 0, 0], + cmyk: [0, 0, 0, 0], + alpha: 1 + }; + + // parse Color() argument + var vals; + if (typeof obj === 'string') { + vals = colorString.getRgba(obj); + if (vals) { + this.setValues('rgb', vals); + } else if (vals = colorString.getHsla(obj)) { + this.setValues('hsl', vals); + } else if (vals = colorString.getHwb(obj)) { + this.setValues('hwb', vals); + } + } else if (typeof obj === 'object') { + vals = obj; + if (vals.r !== undefined || vals.red !== undefined) { + this.setValues('rgb', vals); + } else if (vals.l !== undefined || vals.lightness !== undefined) { + this.setValues('hsl', vals); + } else if (vals.v !== undefined || vals.value !== undefined) { + this.setValues('hsv', vals); + } else if (vals.w !== undefined || vals.whiteness !== undefined) { + this.setValues('hwb', vals); + } else if (vals.c !== undefined || vals.cyan !== undefined) { + this.setValues('cmyk', vals); + } + } +}; + +Color.prototype = { + isValid: function () { + return this.valid; + }, + rgb: function () { + return this.setSpace('rgb', arguments); + }, + hsl: function () { + return this.setSpace('hsl', arguments); + }, + hsv: function () { + return this.setSpace('hsv', arguments); + }, + hwb: function () { + return this.setSpace('hwb', arguments); + }, + cmyk: function () { + return this.setSpace('cmyk', arguments); + }, + + rgbArray: function () { + return this.values.rgb; + }, + hslArray: function () { + return this.values.hsl; + }, + hsvArray: function () { + return this.values.hsv; + }, + hwbArray: function () { + var values = this.values; + if (values.alpha !== 1) { + return values.hwb.concat([values.alpha]); + } + return values.hwb; + }, + cmykArray: function () { + return this.values.cmyk; + }, + rgbaArray: function () { + var values = this.values; + return values.rgb.concat([values.alpha]); + }, + hslaArray: function () { + var values = this.values; + return values.hsl.concat([values.alpha]); + }, + alpha: function (val) { + if (val === undefined) { + return this.values.alpha; + } + this.setValues('alpha', val); + return this; + }, + + red: function (val) { + return this.setChannel('rgb', 0, val); + }, + green: function (val) { + return this.setChannel('rgb', 1, val); + }, + blue: function (val) { + return this.setChannel('rgb', 2, val); + }, + hue: function (val) { + if (val) { + val %= 360; + val = val < 0 ? 360 + val : val; + } + return this.setChannel('hsl', 0, val); + }, + saturation: function (val) { + return this.setChannel('hsl', 1, val); + }, + lightness: function (val) { + return this.setChannel('hsl', 2, val); + }, + saturationv: function (val) { + return this.setChannel('hsv', 1, val); + }, + whiteness: function (val) { + return this.setChannel('hwb', 1, val); + }, + blackness: function (val) { + return this.setChannel('hwb', 2, val); + }, + value: function (val) { + return this.setChannel('hsv', 2, val); + }, + cyan: function (val) { + return this.setChannel('cmyk', 0, val); + }, + magenta: function (val) { + return this.setChannel('cmyk', 1, val); + }, + yellow: function (val) { + return this.setChannel('cmyk', 2, val); + }, + black: function (val) { + return this.setChannel('cmyk', 3, val); + }, + + hexString: function () { + return colorString.hexString(this.values.rgb); + }, + rgbString: function () { + return colorString.rgbString(this.values.rgb, this.values.alpha); + }, + rgbaString: function () { + return colorString.rgbaString(this.values.rgb, this.values.alpha); + }, + percentString: function () { + return colorString.percentString(this.values.rgb, this.values.alpha); + }, + hslString: function () { + return colorString.hslString(this.values.hsl, this.values.alpha); + }, + hslaString: function () { + return colorString.hslaString(this.values.hsl, this.values.alpha); + }, + hwbString: function () { + return colorString.hwbString(this.values.hwb, this.values.alpha); + }, + keyword: function () { + return colorString.keyword(this.values.rgb, this.values.alpha); + }, + + rgbNumber: function () { + var rgb = this.values.rgb; + return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; + }, + + luminosity: function () { + // http://www.w3.org/TR/WCAG20/#relativeluminancedef + var rgb = this.values.rgb; + var lum = []; + for (var i = 0; i < rgb.length; i++) { + var chan = rgb[i] / 255; + lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4); + } + return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; + }, + + contrast: function (color2) { + // http://www.w3.org/TR/WCAG20/#contrast-ratiodef + var lum1 = this.luminosity(); + var lum2 = color2.luminosity(); + if (lum1 > lum2) { + return (lum1 + 0.05) / (lum2 + 0.05); + } + return (lum2 + 0.05) / (lum1 + 0.05); + }, + + level: function (color2) { + var contrastRatio = this.contrast(color2); + if (contrastRatio >= 7.1) { + return 'AAA'; + } + + return (contrastRatio >= 4.5) ? 'AA' : ''; + }, + + dark: function () { + // YIQ equation from http://24ways.org/2010/calculating-color-contrast + var rgb = this.values.rgb; + var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; + return yiq < 128; + }, + + light: function () { + return !this.dark(); + }, + + negate: function () { + var rgb = []; + for (var i = 0; i < 3; i++) { + rgb[i] = 255 - this.values.rgb[i]; + } + this.setValues('rgb', rgb); + return this; + }, + + lighten: function (ratio) { + var hsl = this.values.hsl; + hsl[2] += hsl[2] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + darken: function (ratio) { + var hsl = this.values.hsl; + hsl[2] -= hsl[2] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + saturate: function (ratio) { + var hsl = this.values.hsl; + hsl[1] += hsl[1] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + desaturate: function (ratio) { + var hsl = this.values.hsl; + hsl[1] -= hsl[1] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + whiten: function (ratio) { + var hwb = this.values.hwb; + hwb[1] += hwb[1] * ratio; + this.setValues('hwb', hwb); + return this; + }, + + blacken: function (ratio) { + var hwb = this.values.hwb; + hwb[2] += hwb[2] * ratio; + this.setValues('hwb', hwb); + return this; + }, + + greyscale: function () { + var rgb = this.values.rgb; + // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale + var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; + this.setValues('rgb', [val, val, val]); + return this; + }, + + clearer: function (ratio) { + var alpha = this.values.alpha; + this.setValues('alpha', alpha - (alpha * ratio)); + return this; + }, + + opaquer: function (ratio) { + var alpha = this.values.alpha; + this.setValues('alpha', alpha + (alpha * ratio)); + return this; + }, + + rotate: function (degrees) { + var hsl = this.values.hsl; + var hue = (hsl[0] + degrees) % 360; + hsl[0] = hue < 0 ? 360 + hue : hue; + this.setValues('hsl', hsl); + return this; + }, + + /** + * Ported from sass implementation in C + * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209 + */ + mix: function (mixinColor, weight) { + var color1 = this; + var color2 = mixinColor; + var p = weight === undefined ? 0.5 : weight; + + var w = 2 * p - 1; + var a = color1.alpha() - color2.alpha(); + + var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; + var w2 = 1 - w1; + + return this + .rgb( + w1 * color1.red() + w2 * color2.red(), + w1 * color1.green() + w2 * color2.green(), + w1 * color1.blue() + w2 * color2.blue() + ) + .alpha(color1.alpha() * p + color2.alpha() * (1 - p)); + }, + + toJSON: function () { + return this.rgb(); + }, + + clone: function () { + // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify, + // making the final build way to big to embed in Chart.js. So let's do it manually, + // assuming that values to clone are 1 dimension arrays containing only numbers, + // except 'alpha' which is a number. + var result = new Color(); + var source = this.values; + var target = result.values; + var value, type; + + for (var prop in source) { + if (source.hasOwnProperty(prop)) { + value = source[prop]; + type = ({}).toString.call(value); + if (type === '[object Array]') { + target[prop] = value.slice(0); + } else if (type === '[object Number]') { + target[prop] = value; + } else { + console.error('unexpected color value:', value); + } + } + } + + return result; + } +}; + +Color.prototype.spaces = { + rgb: ['red', 'green', 'blue'], + hsl: ['hue', 'saturation', 'lightness'], + hsv: ['hue', 'saturation', 'value'], + hwb: ['hue', 'whiteness', 'blackness'], + cmyk: ['cyan', 'magenta', 'yellow', 'black'] +}; + +Color.prototype.maxes = { + rgb: [255, 255, 255], + hsl: [360, 100, 100], + hsv: [360, 100, 100], + hwb: [360, 100, 100], + cmyk: [100, 100, 100, 100] +}; + +Color.prototype.getValues = function (space) { + var values = this.values; + var vals = {}; + + for (var i = 0; i < space.length; i++) { + vals[space.charAt(i)] = values[space][i]; + } + + if (values.alpha !== 1) { + vals.a = values.alpha; + } + + // {r: 255, g: 255, b: 255, a: 0.4} + return vals; +}; + +Color.prototype.setValues = function (space, vals) { + var values = this.values; + var spaces = this.spaces; + var maxes = this.maxes; + var alpha = 1; + var i; + + this.valid = true; + + if (space === 'alpha') { + alpha = vals; + } else if (vals.length) { + // [10, 10, 10] + values[space] = vals.slice(0, space.length); + alpha = vals[space.length]; + } else if (vals[space.charAt(0)] !== undefined) { + // {r: 10, g: 10, b: 10} + for (i = 0; i < space.length; i++) { + values[space][i] = vals[space.charAt(i)]; + } + + alpha = vals.a; + } else if (vals[spaces[space][0]] !== undefined) { + // {red: 10, green: 10, blue: 10} + var chans = spaces[space]; + + for (i = 0; i < space.length; i++) { + values[space][i] = vals[chans[i]]; + } + + alpha = vals.alpha; + } + + values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha))); + + if (space === 'alpha') { + return false; + } + + var capped; + + // cap values of the space prior converting all values + for (i = 0; i < space.length; i++) { + capped = Math.max(0, Math.min(maxes[space][i], values[space][i])); + values[space][i] = Math.round(capped); + } + + // convert to all the other color spaces + for (var sname in spaces) { + if (sname !== space) { + values[sname] = colorConvert[space][sname](values[space]); + } + } + + return true; +}; + +Color.prototype.setSpace = function (space, args) { + var vals = args[0]; + + if (vals === undefined) { + // color.rgb() + return this.getValues(space); + } + + // color.rgb(10, 10, 10) + if (typeof vals === 'number') { + vals = Array.prototype.slice.call(args); + } + + this.setValues(space, vals); + return this; +}; + +Color.prototype.setChannel = function (space, index, val) { + var svalues = this.values[space]; + if (val === undefined) { + // color.red() + return svalues[index]; + } else if (val === svalues[index]) { + // color.red(color.red()) + return this; + } + + // color.red(100) + svalues[index] = val; + this.setValues(space, svalues); + + return this; +}; + +if (typeof window !== 'undefined') { + window.Color = Color; +} + +var chartjsColor = Color; + +/** + * @namespace Chart.helpers + */ +var helpers = { + /** + * An empty function that can be used, for example, for optional callback. + */ + noop: function() {}, + + /** + * Returns a unique id, sequentially generated from a global variable. + * @returns {number} + * @function + */ + uid: (function() { + var id = 0; + return function() { + return id++; + }; + }()), + + /** + * Returns true if `value` is neither null nor undefined, else returns false. + * @param {*} value - The value to test. + * @returns {boolean} + * @since 2.7.0 + */ + isNullOrUndef: function(value) { + return value === null || typeof value === 'undefined'; + }, + + /** + * Returns true if `value` is an array (including typed arrays), else returns false. + * @param {*} value - The value to test. + * @returns {boolean} + * @function + */ + isArray: function(value) { + if (Array.isArray && Array.isArray(value)) { + return true; + } + var type = Object.prototype.toString.call(value); + if (type.substr(0, 7) === '[object' && type.substr(-6) === 'Array]') { + return true; + } + return false; + }, + + /** + * Returns true if `value` is an object (excluding null), else returns false. + * @param {*} value - The value to test. + * @returns {boolean} + * @since 2.7.0 + */ + isObject: function(value) { + return value !== null && Object.prototype.toString.call(value) === '[object Object]'; + }, + + /** + * Returns true if `value` is a finite number, else returns false + * @param {*} value - The value to test. + * @returns {boolean} + */ + isFinite: function(value) { + return (typeof value === 'number' || value instanceof Number) && isFinite(value); + }, + + /** + * Returns `value` if defined, else returns `defaultValue`. + * @param {*} value - The value to return if defined. + * @param {*} defaultValue - The value to return if `value` is undefined. + * @returns {*} + */ + valueOrDefault: function(value, defaultValue) { + return typeof value === 'undefined' ? defaultValue : value; + }, + + /** + * Returns value at the given `index` in array if defined, else returns `defaultValue`. + * @param {Array} value - The array to lookup for value at `index`. + * @param {number} index - The index in `value` to lookup for value. + * @param {*} defaultValue - The value to return if `value[index]` is undefined. + * @returns {*} + */ + valueAtIndexOrDefault: function(value, index, defaultValue) { + return helpers.valueOrDefault(helpers.isArray(value) ? value[index] : value, defaultValue); + }, + + /** + * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the + * value returned by `fn`. If `fn` is not a function, this method returns undefined. + * @param {function} fn - The function to call. + * @param {Array|undefined|null} args - The arguments with which `fn` should be called. + * @param {object} [thisArg] - The value of `this` provided for the call to `fn`. + * @returns {*} + */ + callback: function(fn, args, thisArg) { + if (fn && typeof fn.call === 'function') { + return fn.apply(thisArg, args); + } + }, + + /** + * Note(SB) for performance sake, this method should only be used when loopable type + * is unknown or in none intensive code (not called often and small loopable). Else + * it's preferable to use a regular for() loop and save extra function calls. + * @param {object|Array} loopable - The object or array to be iterated. + * @param {function} fn - The function to call for each item. + * @param {object} [thisArg] - The value of `this` provided for the call to `fn`. + * @param {boolean} [reverse] - If true, iterates backward on the loopable. + */ + each: function(loopable, fn, thisArg, reverse) { + var i, len, keys; + if (helpers.isArray(loopable)) { + len = loopable.length; + if (reverse) { + for (i = len - 1; i >= 0; i--) { + fn.call(thisArg, loopable[i], i); + } + } else { + for (i = 0; i < len; i++) { + fn.call(thisArg, loopable[i], i); + } + } + } else if (helpers.isObject(loopable)) { + keys = Object.keys(loopable); + len = keys.length; + for (i = 0; i < len; i++) { + fn.call(thisArg, loopable[keys[i]], keys[i]); + } + } + }, + + /** + * Returns true if the `a0` and `a1` arrays have the same content, else returns false. + * @see https://stackoverflow.com/a/14853974 + * @param {Array} a0 - The array to compare + * @param {Array} a1 - The array to compare + * @returns {boolean} + */ + arrayEquals: function(a0, a1) { + var i, ilen, v0, v1; + + if (!a0 || !a1 || a0.length !== a1.length) { + return false; + } + + for (i = 0, ilen = a0.length; i < ilen; ++i) { + v0 = a0[i]; + v1 = a1[i]; + + if (v0 instanceof Array && v1 instanceof Array) { + if (!helpers.arrayEquals(v0, v1)) { + return false; + } + } else if (v0 !== v1) { + // NOTE: two different object instances will never be equal: {x:20} != {x:20} + return false; + } + } + + return true; + }, + + /** + * Returns a deep copy of `source` without keeping references on objects and arrays. + * @param {*} source - The value to clone. + * @returns {*} + */ + clone: function(source) { + if (helpers.isArray(source)) { + return source.map(helpers.clone); + } + + if (helpers.isObject(source)) { + var target = {}; + var keys = Object.keys(source); + var klen = keys.length; + var k = 0; + + for (; k < klen; ++k) { + target[keys[k]] = helpers.clone(source[keys[k]]); + } + + return target; + } + + return source; + }, + + /** + * The default merger when Chart.helpers.merge is called without merger option. + * Note(SB): also used by mergeConfig and mergeScaleConfig as fallback. + * @private + */ + _merger: function(key, target, source, options) { + var tval = target[key]; + var sval = source[key]; + + if (helpers.isObject(tval) && helpers.isObject(sval)) { + helpers.merge(tval, sval, options); + } else { + target[key] = helpers.clone(sval); + } + }, + + /** + * Merges source[key] in target[key] only if target[key] is undefined. + * @private + */ + _mergerIf: function(key, target, source) { + var tval = target[key]; + var sval = source[key]; + + if (helpers.isObject(tval) && helpers.isObject(sval)) { + helpers.mergeIf(tval, sval); + } else if (!target.hasOwnProperty(key)) { + target[key] = helpers.clone(sval); + } + }, + + /** + * Recursively deep copies `source` properties into `target` with the given `options`. + * IMPORTANT: `target` is not cloned and will be updated with `source` properties. + * @param {object} target - The target object in which all sources are merged into. + * @param {object|object[]} source - Object(s) to merge into `target`. + * @param {object} [options] - Merging options: + * @param {function} [options.merger] - The merge method (key, target, source, options) + * @returns {object} The `target` object. + */ + merge: function(target, source, options) { + var sources = helpers.isArray(source) ? source : [source]; + var ilen = sources.length; + var merge, i, keys, klen, k; + + if (!helpers.isObject(target)) { + return target; + } + + options = options || {}; + merge = options.merger || helpers._merger; + + for (i = 0; i < ilen; ++i) { + source = sources[i]; + if (!helpers.isObject(source)) { + continue; + } + + keys = Object.keys(source); + for (k = 0, klen = keys.length; k < klen; ++k) { + merge(keys[k], target, source, options); + } + } + + return target; + }, + + /** + * Recursively deep copies `source` properties into `target` *only* if not defined in target. + * IMPORTANT: `target` is not cloned and will be updated with `source` properties. + * @param {object} target - The target object in which all sources are merged into. + * @param {object|object[]} source - Object(s) to merge into `target`. + * @returns {object} The `target` object. + */ + mergeIf: function(target, source) { + return helpers.merge(target, source, {merger: helpers._mergerIf}); + }, + + /** + * Applies the contents of two or more objects together into the first object. + * @param {object} target - The target object in which all objects are merged into. + * @param {object} arg1 - Object containing additional properties to merge in target. + * @param {object} argN - Additional objects containing properties to merge in target. + * @returns {object} The `target` object. + */ + extend: Object.assign || function(target) { + return helpers.merge(target, [].slice.call(arguments, 1), { + merger: function(key, dst, src) { + dst[key] = src[key]; + } + }); + }, + + /** + * Basic javascript inheritance based on the model created in Backbone.js + */ + inherits: function(extensions) { + var me = this; + var ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() { + return me.apply(this, arguments); + }; + + var Surrogate = function() { + this.constructor = ChartElement; + }; + + Surrogate.prototype = me.prototype; + ChartElement.prototype = new Surrogate(); + ChartElement.extend = helpers.inherits; + + if (extensions) { + helpers.extend(ChartElement.prototype, extensions); + } + + ChartElement.__super__ = me.prototype; + return ChartElement; + }, + + _deprecated: function(scope, value, previous, current) { + if (value !== undefined) { + console.warn(scope + ': "' + previous + + '" is deprecated. Please use "' + current + '" instead'); + } + } +}; + +var helpers_core = helpers; + +// DEPRECATIONS + +/** + * Provided for backward compatibility, use Chart.helpers.callback instead. + * @function Chart.helpers.callCallback + * @deprecated since version 2.6.0 + * @todo remove at version 3 + * @private + */ +helpers.callCallback = helpers.callback; + +/** + * Provided for backward compatibility, use Array.prototype.indexOf instead. + * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+ + * @function Chart.helpers.indexOf + * @deprecated since version 2.7.0 + * @todo remove at version 3 + * @private + */ +helpers.indexOf = function(array, item, fromIndex) { + return Array.prototype.indexOf.call(array, item, fromIndex); +}; + +/** + * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead. + * @function Chart.helpers.getValueOrDefault + * @deprecated since version 2.7.0 + * @todo remove at version 3 + * @private + */ +helpers.getValueOrDefault = helpers.valueOrDefault; + +/** + * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead. + * @function Chart.helpers.getValueAtIndexOrDefault + * @deprecated since version 2.7.0 + * @todo remove at version 3 + * @private + */ +helpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault; + +/** + * Easing functions adapted from Robert Penner's easing equations. + * @namespace Chart.helpers.easingEffects + * @see http://www.robertpenner.com/easing/ + */ +var effects = { + linear: function(t) { + return t; + }, + + easeInQuad: function(t) { + return t * t; + }, + + easeOutQuad: function(t) { + return -t * (t - 2); + }, + + easeInOutQuad: function(t) { + if ((t /= 0.5) < 1) { + return 0.5 * t * t; + } + return -0.5 * ((--t) * (t - 2) - 1); + }, + + easeInCubic: function(t) { + return t * t * t; + }, + + easeOutCubic: function(t) { + return (t = t - 1) * t * t + 1; + }, + + easeInOutCubic: function(t) { + if ((t /= 0.5) < 1) { + return 0.5 * t * t * t; + } + return 0.5 * ((t -= 2) * t * t + 2); + }, + + easeInQuart: function(t) { + return t * t * t * t; + }, + + easeOutQuart: function(t) { + return -((t = t - 1) * t * t * t - 1); + }, + + easeInOutQuart: function(t) { + if ((t /= 0.5) < 1) { + return 0.5 * t * t * t * t; + } + return -0.5 * ((t -= 2) * t * t * t - 2); + }, + + easeInQuint: function(t) { + return t * t * t * t * t; + }, + + easeOutQuint: function(t) { + return (t = t - 1) * t * t * t * t + 1; + }, + + easeInOutQuint: function(t) { + if ((t /= 0.5) < 1) { + return 0.5 * t * t * t * t * t; + } + return 0.5 * ((t -= 2) * t * t * t * t + 2); + }, + + easeInSine: function(t) { + return -Math.cos(t * (Math.PI / 2)) + 1; + }, + + easeOutSine: function(t) { + return Math.sin(t * (Math.PI / 2)); + }, + + easeInOutSine: function(t) { + return -0.5 * (Math.cos(Math.PI * t) - 1); + }, + + easeInExpo: function(t) { + return (t === 0) ? 0 : Math.pow(2, 10 * (t - 1)); + }, + + easeOutExpo: function(t) { + return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1; + }, + + easeInOutExpo: function(t) { + if (t === 0) { + return 0; + } + if (t === 1) { + return 1; + } + if ((t /= 0.5) < 1) { + return 0.5 * Math.pow(2, 10 * (t - 1)); + } + return 0.5 * (-Math.pow(2, -10 * --t) + 2); + }, + + easeInCirc: function(t) { + if (t >= 1) { + return t; + } + return -(Math.sqrt(1 - t * t) - 1); + }, + + easeOutCirc: function(t) { + return Math.sqrt(1 - (t = t - 1) * t); + }, + + easeInOutCirc: function(t) { + if ((t /= 0.5) < 1) { + return -0.5 * (Math.sqrt(1 - t * t) - 1); + } + return 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1); + }, + + easeInElastic: function(t) { + var s = 1.70158; + var p = 0; + var a = 1; + if (t === 0) { + return 0; + } + if (t === 1) { + return 1; + } + if (!p) { + p = 0.3; + } + if (a < 1) { + a = 1; + s = p / 4; + } else { + s = p / (2 * Math.PI) * Math.asin(1 / a); + } + return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p)); + }, + + easeOutElastic: function(t) { + var s = 1.70158; + var p = 0; + var a = 1; + if (t === 0) { + return 0; + } + if (t === 1) { + return 1; + } + if (!p) { + p = 0.3; + } + if (a < 1) { + a = 1; + s = p / 4; + } else { + s = p / (2 * Math.PI) * Math.asin(1 / a); + } + return a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p) + 1; + }, + + easeInOutElastic: function(t) { + var s = 1.70158; + var p = 0; + var a = 1; + if (t === 0) { + return 0; + } + if ((t /= 0.5) === 2) { + return 1; + } + if (!p) { + p = 0.45; + } + if (a < 1) { + a = 1; + s = p / 4; + } else { + s = p / (2 * Math.PI) * Math.asin(1 / a); + } + if (t < 1) { + return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p)); + } + return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p) * 0.5 + 1; + }, + easeInBack: function(t) { + var s = 1.70158; + return t * t * ((s + 1) * t - s); + }, + + easeOutBack: function(t) { + var s = 1.70158; + return (t = t - 1) * t * ((s + 1) * t + s) + 1; + }, + + easeInOutBack: function(t) { + var s = 1.70158; + if ((t /= 0.5) < 1) { + return 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s)); + } + return 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2); + }, + + easeInBounce: function(t) { + return 1 - effects.easeOutBounce(1 - t); + }, + + easeOutBounce: function(t) { + if (t < (1 / 2.75)) { + return 7.5625 * t * t; + } + if (t < (2 / 2.75)) { + return 7.5625 * (t -= (1.5 / 2.75)) * t + 0.75; + } + if (t < (2.5 / 2.75)) { + return 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375; + } + return 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375; + }, + + easeInOutBounce: function(t) { + if (t < 0.5) { + return effects.easeInBounce(t * 2) * 0.5; + } + return effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5; + } +}; + +var helpers_easing = { + effects: effects +}; + +// DEPRECATIONS + +/** + * Provided for backward compatibility, use Chart.helpers.easing.effects instead. + * @function Chart.helpers.easingEffects + * @deprecated since version 2.7.0 + * @todo remove at version 3 + * @private + */ +helpers_core.easingEffects = effects; + +var PI = Math.PI; +var RAD_PER_DEG = PI / 180; +var DOUBLE_PI = PI * 2; +var HALF_PI = PI / 2; +var QUARTER_PI = PI / 4; +var TWO_THIRDS_PI = PI * 2 / 3; + +/** + * @namespace Chart.helpers.canvas + */ +var exports$1 = { + /** + * Clears the entire canvas associated to the given `chart`. + * @param {Chart} chart - The chart for which to clear the canvas. + */ + clear: function(chart) { + chart.ctx.clearRect(0, 0, chart.width, chart.height); + }, + + /** + * Creates a "path" for a rectangle with rounded corners at position (x, y) with a + * given size (width, height) and the same `radius` for all corners. + * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context. + * @param {number} x - The x axis of the coordinate for the rectangle starting point. + * @param {number} y - The y axis of the coordinate for the rectangle starting point. + * @param {number} width - The rectangle's width. + * @param {number} height - The rectangle's height. + * @param {number} radius - The rounded amount (in pixels) for the four corners. + * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object? + */ + roundedRect: function(ctx, x, y, width, height, radius) { + if (radius) { + var r = Math.min(radius, height / 2, width / 2); + var left = x + r; + var top = y + r; + var right = x + width - r; + var bottom = y + height - r; + + ctx.moveTo(x, top); + if (left < right && top < bottom) { + ctx.arc(left, top, r, -PI, -HALF_PI); + ctx.arc(right, top, r, -HALF_PI, 0); + ctx.arc(right, bottom, r, 0, HALF_PI); + ctx.arc(left, bottom, r, HALF_PI, PI); + } else if (left < right) { + ctx.moveTo(left, y); + ctx.arc(right, top, r, -HALF_PI, HALF_PI); + ctx.arc(left, top, r, HALF_PI, PI + HALF_PI); + } else if (top < bottom) { + ctx.arc(left, top, r, -PI, 0); + ctx.arc(left, bottom, r, 0, PI); + } else { + ctx.arc(left, top, r, -PI, PI); + } + ctx.closePath(); + ctx.moveTo(x, y); + } else { + ctx.rect(x, y, width, height); + } + }, + + drawPoint: function(ctx, style, radius, x, y, rotation) { + var type, xOffset, yOffset, size, cornerRadius; + var rad = (rotation || 0) * RAD_PER_DEG; + + if (style && typeof style === 'object') { + type = style.toString(); + if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') { + ctx.save(); + ctx.translate(x, y); + ctx.rotate(rad); + ctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height); + ctx.restore(); + return; + } + } + + if (isNaN(radius) || radius <= 0) { + return; + } + + ctx.beginPath(); + + switch (style) { + // Default includes circle + default: + ctx.arc(x, y, radius, 0, DOUBLE_PI); + ctx.closePath(); + break; + case 'triangle': + ctx.moveTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); + rad += TWO_THIRDS_PI; + ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); + rad += TWO_THIRDS_PI; + ctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius); + ctx.closePath(); + break; + case 'rectRounded': + // NOTE: the rounded rect implementation changed to use `arc` instead of + // `quadraticCurveTo` since it generates better results when rect is + // almost a circle. 0.516 (instead of 0.5) produces results with visually + // closer proportion to the previous impl and it is inscribed in the + // circle with `radius`. For more details, see the following PRs: + // https://github.com/chartjs/Chart.js/issues/5597 + // https://github.com/chartjs/Chart.js/issues/5858 + cornerRadius = radius * 0.516; + size = radius - cornerRadius; + xOffset = Math.cos(rad + QUARTER_PI) * size; + yOffset = Math.sin(rad + QUARTER_PI) * size; + ctx.arc(x - xOffset, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI); + ctx.arc(x + yOffset, y - xOffset, cornerRadius, rad - HALF_PI, rad); + ctx.arc(x + xOffset, y + yOffset, cornerRadius, rad, rad + HALF_PI); + ctx.arc(x - yOffset, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI); + ctx.closePath(); + break; + case 'rect': + if (!rotation) { + size = Math.SQRT1_2 * radius; + ctx.rect(x - size, y - size, 2 * size, 2 * size); + break; + } + rad += QUARTER_PI; + /* falls through */ + case 'rectRot': + xOffset = Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + ctx.moveTo(x - xOffset, y - yOffset); + ctx.lineTo(x + yOffset, y - xOffset); + ctx.lineTo(x + xOffset, y + yOffset); + ctx.lineTo(x - yOffset, y + xOffset); + ctx.closePath(); + break; + case 'crossRot': + rad += QUARTER_PI; + /* falls through */ + case 'cross': + xOffset = Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + ctx.moveTo(x - xOffset, y - yOffset); + ctx.lineTo(x + xOffset, y + yOffset); + ctx.moveTo(x + yOffset, y - xOffset); + ctx.lineTo(x - yOffset, y + xOffset); + break; + case 'star': + xOffset = Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + ctx.moveTo(x - xOffset, y - yOffset); + ctx.lineTo(x + xOffset, y + yOffset); + ctx.moveTo(x + yOffset, y - xOffset); + ctx.lineTo(x - yOffset, y + xOffset); + rad += QUARTER_PI; + xOffset = Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + ctx.moveTo(x - xOffset, y - yOffset); + ctx.lineTo(x + xOffset, y + yOffset); + ctx.moveTo(x + yOffset, y - xOffset); + ctx.lineTo(x - yOffset, y + xOffset); + break; + case 'line': + xOffset = Math.cos(rad) * radius; + yOffset = Math.sin(rad) * radius; + ctx.moveTo(x - xOffset, y - yOffset); + ctx.lineTo(x + xOffset, y + yOffset); + break; + case 'dash': + ctx.moveTo(x, y); + ctx.lineTo(x + Math.cos(rad) * radius, y + Math.sin(rad) * radius); + break; + } + + ctx.fill(); + ctx.stroke(); + }, + + /** + * Returns true if the point is inside the rectangle + * @param {object} point - The point to test + * @param {object} area - The rectangle + * @returns {boolean} + * @private + */ + _isPointInArea: function(point, area) { + var epsilon = 1e-6; // 1e-6 is margin in pixels for accumulated error. + + return point.x > area.left - epsilon && point.x < area.right + epsilon && + point.y > area.top - epsilon && point.y < area.bottom + epsilon; + }, + + clipArea: function(ctx, area) { + ctx.save(); + ctx.beginPath(); + ctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top); + ctx.clip(); + }, + + unclipArea: function(ctx) { + ctx.restore(); + }, + + lineTo: function(ctx, previous, target, flip) { + var stepped = target.steppedLine; + if (stepped) { + if (stepped === 'middle') { + var midpoint = (previous.x + target.x) / 2.0; + ctx.lineTo(midpoint, flip ? target.y : previous.y); + ctx.lineTo(midpoint, flip ? previous.y : target.y); + } else if ((stepped === 'after' && !flip) || (stepped !== 'after' && flip)) { + ctx.lineTo(previous.x, target.y); + } else { + ctx.lineTo(target.x, previous.y); + } + ctx.lineTo(target.x, target.y); + return; + } + + if (!target.tension) { + ctx.lineTo(target.x, target.y); + return; + } + + ctx.bezierCurveTo( + flip ? previous.controlPointPreviousX : previous.controlPointNextX, + flip ? previous.controlPointPreviousY : previous.controlPointNextY, + flip ? target.controlPointNextX : target.controlPointPreviousX, + flip ? target.controlPointNextY : target.controlPointPreviousY, + target.x, + target.y); + } +}; + +var helpers_canvas = exports$1; + +// DEPRECATIONS + +/** + * Provided for backward compatibility, use Chart.helpers.canvas.clear instead. + * @namespace Chart.helpers.clear + * @deprecated since version 2.7.0 + * @todo remove at version 3 + * @private + */ +helpers_core.clear = exports$1.clear; + +/** + * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead. + * @namespace Chart.helpers.drawRoundedRectangle + * @deprecated since version 2.7.0 + * @todo remove at version 3 + * @private + */ +helpers_core.drawRoundedRectangle = function(ctx) { + ctx.beginPath(); + exports$1.roundedRect.apply(exports$1, arguments); +}; + +var defaults = { + /** + * @private + */ + _set: function(scope, values) { + return helpers_core.merge(this[scope] || (this[scope] = {}), values); + } +}; + +// TODO(v3): remove 'global' from namespace. all default are global and +// there's inconsistency around which options are under 'global' +defaults._set('global', { + defaultColor: 'rgba(0,0,0,0.1)', + defaultFontColor: '#666', + defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", + defaultFontSize: 12, + defaultFontStyle: 'normal', + defaultLineHeight: 1.2, + showLines: true +}); + +var core_defaults = defaults; + +var valueOrDefault = helpers_core.valueOrDefault; + +/** + * Converts the given font object into a CSS font string. + * @param {object} font - A font object. + * @return {string} The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font + * @private + */ +function toFontString(font) { + if (!font || helpers_core.isNullOrUndef(font.size) || helpers_core.isNullOrUndef(font.family)) { + return null; + } + + return (font.style ? font.style + ' ' : '') + + (font.weight ? font.weight + ' ' : '') + + font.size + 'px ' + + font.family; +} + +/** + * @alias Chart.helpers.options + * @namespace + */ +var helpers_options = { + /** + * Converts the given line height `value` in pixels for a specific font `size`. + * @param {number|string} value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em'). + * @param {number} size - The font size (in pixels) used to resolve relative `value`. + * @returns {number} The effective line height in pixels (size * 1.2 if value is invalid). + * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height + * @since 2.7.0 + */ + toLineHeight: function(value, size) { + var matches = ('' + value).match(/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/); + if (!matches || matches[1] === 'normal') { + return size * 1.2; + } + + value = +matches[2]; + + switch (matches[3]) { + case 'px': + return value; + case '%': + value /= 100; + break; + } + + return size * value; + }, + + /** + * Converts the given value into a padding object with pre-computed width/height. + * @param {number|object} value - If a number, set the value to all TRBL component, + * else, if and object, use defined properties and sets undefined ones to 0. + * @returns {object} The padding values (top, right, bottom, left, width, height) + * @since 2.7.0 + */ + toPadding: function(value) { + var t, r, b, l; + + if (helpers_core.isObject(value)) { + t = +value.top || 0; + r = +value.right || 0; + b = +value.bottom || 0; + l = +value.left || 0; + } else { + t = r = b = l = +value || 0; + } + + return { + top: t, + right: r, + bottom: b, + left: l, + height: t + b, + width: l + r + }; + }, + + /** + * Parses font options and returns the font object. + * @param {object} options - A object that contains font options to be parsed. + * @return {object} The font object. + * @todo Support font.* options and renamed to toFont(). + * @private + */ + _parseFont: function(options) { + var globalDefaults = core_defaults.global; + var size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize); + var font = { + family: valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily), + lineHeight: helpers_core.options.toLineHeight(valueOrDefault(options.lineHeight, globalDefaults.defaultLineHeight), size), + size: size, + style: valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle), + weight: null, + string: '' + }; + + font.string = toFontString(font); + return font; + }, + + /** + * Evaluates the given `inputs` sequentially and returns the first defined value. + * @param {Array} inputs - An array of values, falling back to the last value. + * @param {object} [context] - If defined and the current value is a function, the value + * is called with `context` as first argument and the result becomes the new input. + * @param {number} [index] - If defined and the current value is an array, the value + * at `index` become the new input. + * @param {object} [info] - object to return information about resolution in + * @param {boolean} [info.cacheable] - Will be set to `false` if option is not cacheable. + * @since 2.7.0 + */ + resolve: function(inputs, context, index, info) { + var cacheable = true; + var i, ilen, value; + + for (i = 0, ilen = inputs.length; i < ilen; ++i) { + value = inputs[i]; + if (value === undefined) { + continue; + } + if (context !== undefined && typeof value === 'function') { + value = value(context); + cacheable = false; + } + if (index !== undefined && helpers_core.isArray(value)) { + value = value[index]; + cacheable = false; + } + if (value !== undefined) { + if (info && !cacheable) { + info.cacheable = false; + } + return value; + } + } + } +}; + +/** + * @alias Chart.helpers.math + * @namespace + */ +var exports$2 = { + /** + * Returns an array of factors sorted from 1 to sqrt(value) + * @private + */ + _factorize: function(value) { + var result = []; + var sqrt = Math.sqrt(value); + var i; + + for (i = 1; i < sqrt; i++) { + if (value % i === 0) { + result.push(i); + result.push(value / i); + } + } + if (sqrt === (sqrt | 0)) { // if value is a square number + result.push(sqrt); + } + + result.sort(function(a, b) { + return a - b; + }).pop(); + return result; + }, + + log10: Math.log10 || function(x) { + var exponent = Math.log(x) * Math.LOG10E; // Math.LOG10E = 1 / Math.LN10. + // Check for whole powers of 10, + // which due to floating point rounding error should be corrected. + var powerOf10 = Math.round(exponent); + var isPowerOf10 = x === Math.pow(10, powerOf10); + + return isPowerOf10 ? powerOf10 : exponent; + } +}; + +var helpers_math = exports$2; + +// DEPRECATIONS + +/** + * Provided for backward compatibility, use Chart.helpers.math.log10 instead. + * @namespace Chart.helpers.log10 + * @deprecated since version 2.9.0 + * @todo remove at version 3 + * @private + */ +helpers_core.log10 = exports$2.log10; + +var getRtlAdapter = function(rectX, width) { + return { + x: function(x) { + return rectX + rectX + width - x; + }, + setWidth: function(w) { + width = w; + }, + textAlign: function(align) { + if (align === 'center') { + return align; + } + return align === 'right' ? 'left' : 'right'; + }, + xPlus: function(x, value) { + return x - value; + }, + leftForLtr: function(x, itemWidth) { + return x - itemWidth; + }, + }; +}; + +var getLtrAdapter = function() { + return { + x: function(x) { + return x; + }, + setWidth: function(w) { // eslint-disable-line no-unused-vars + }, + textAlign: function(align) { + return align; + }, + xPlus: function(x, value) { + return x + value; + }, + leftForLtr: function(x, _itemWidth) { // eslint-disable-line no-unused-vars + return x; + }, + }; +}; + +var getAdapter = function(rtl, rectX, width) { + return rtl ? getRtlAdapter(rectX, width) : getLtrAdapter(); +}; + +var overrideTextDirection = function(ctx, direction) { + var style, original; + if (direction === 'ltr' || direction === 'rtl') { + style = ctx.canvas.style; + original = [ + style.getPropertyValue('direction'), + style.getPropertyPriority('direction'), + ]; + + style.setProperty('direction', direction, 'important'); + ctx.prevTextDirection = original; + } +}; + +var restoreTextDirection = function(ctx) { + var original = ctx.prevTextDirection; + if (original !== undefined) { + delete ctx.prevTextDirection; + ctx.canvas.style.setProperty('direction', original[0], original[1]); + } +}; + +var helpers_rtl = { + getRtlAdapter: getAdapter, + overrideTextDirection: overrideTextDirection, + restoreTextDirection: restoreTextDirection, +}; + +var helpers$1 = helpers_core; +var easing = helpers_easing; +var canvas = helpers_canvas; +var options = helpers_options; +var math = helpers_math; +var rtl = helpers_rtl; +helpers$1.easing = easing; +helpers$1.canvas = canvas; +helpers$1.options = options; +helpers$1.math = math; +helpers$1.rtl = rtl; + +function interpolate(start, view, model, ease) { + var keys = Object.keys(model); + var i, ilen, key, actual, origin, target, type, c0, c1; + + for (i = 0, ilen = keys.length; i < ilen; ++i) { + key = keys[i]; + + target = model[key]; + + // if a value is added to the model after pivot() has been called, the view + // doesn't contain it, so let's initialize the view to the target value. + if (!view.hasOwnProperty(key)) { + view[key] = target; + } + + actual = view[key]; + + if (actual === target || key[0] === '_') { + continue; + } + + if (!start.hasOwnProperty(key)) { + start[key] = actual; + } + + origin = start[key]; + + type = typeof target; + + if (type === typeof origin) { + if (type === 'string') { + c0 = chartjsColor(origin); + if (c0.valid) { + c1 = chartjsColor(target); + if (c1.valid) { + view[key] = c1.mix(c0, ease).rgbString(); + continue; + } + } + } else if (helpers$1.isFinite(origin) && helpers$1.isFinite(target)) { + view[key] = origin + (target - origin) * ease; + continue; + } + } + + view[key] = target; + } +} + +var Element = function(configuration) { + helpers$1.extend(this, configuration); + this.initialize.apply(this, arguments); +}; + +helpers$1.extend(Element.prototype, { + _type: undefined, + + initialize: function() { + this.hidden = false; + }, + + pivot: function() { + var me = this; + if (!me._view) { + me._view = helpers$1.extend({}, me._model); + } + me._start = {}; + return me; + }, + + transition: function(ease) { + var me = this; + var model = me._model; + var start = me._start; + var view = me._view; + + // No animation -> No Transition + if (!model || ease === 1) { + me._view = helpers$1.extend({}, model); + me._start = null; + return me; + } + + if (!view) { + view = me._view = {}; + } + + if (!start) { + start = me._start = {}; + } + + interpolate(start, view, model, ease); + + return me; + }, + + tooltipPosition: function() { + return { + x: this._model.x, + y: this._model.y + }; + }, + + hasValue: function() { + return helpers$1.isNumber(this._model.x) && helpers$1.isNumber(this._model.y); + } +}); + +Element.extend = helpers$1.inherits; + +var core_element = Element; + +var exports$3 = core_element.extend({ + chart: null, // the animation associated chart instance + currentStep: 0, // the current animation step + numSteps: 60, // default number of steps + easing: '', // the easing to use for this animation + render: null, // render function used by the animation service + + onAnimationProgress: null, // user specified callback to fire on each step of the animation + onAnimationComplete: null, // user specified callback to fire when the animation finishes +}); + +var core_animation = exports$3; + +// DEPRECATIONS + +/** + * Provided for backward compatibility, use Chart.Animation instead + * @prop Chart.Animation#animationObject + * @deprecated since version 2.6.0 + * @todo remove at version 3 + */ +Object.defineProperty(exports$3.prototype, 'animationObject', { + get: function() { + return this; + } +}); + +/** + * Provided for backward compatibility, use Chart.Animation#chart instead + * @prop Chart.Animation#chartInstance + * @deprecated since version 2.6.0 + * @todo remove at version 3 + */ +Object.defineProperty(exports$3.prototype, 'chartInstance', { + get: function() { + return this.chart; + }, + set: function(value) { + this.chart = value; + } +}); + +core_defaults._set('global', { + animation: { + duration: 1000, + easing: 'easeOutQuart', + onProgress: helpers$1.noop, + onComplete: helpers$1.noop + } +}); + +var core_animations = { + animations: [], + request: null, + + /** + * @param {Chart} chart - The chart to animate. + * @param {Chart.Animation} animation - The animation that we will animate. + * @param {number} duration - The animation duration in ms. + * @param {boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions + */ + addAnimation: function(chart, animation, duration, lazy) { + var animations = this.animations; + var i, ilen; + + animation.chart = chart; + animation.startTime = Date.now(); + animation.duration = duration; + + if (!lazy) { + chart.animating = true; + } + + for (i = 0, ilen = animations.length; i < ilen; ++i) { + if (animations[i].chart === chart) { + animations[i] = animation; + return; + } + } + + animations.push(animation); + + // If there are no animations queued, manually kickstart a digest, for lack of a better word + if (animations.length === 1) { + this.requestAnimationFrame(); + } + }, + + cancelAnimation: function(chart) { + var index = helpers$1.findIndex(this.animations, function(animation) { + return animation.chart === chart; + }); + + if (index !== -1) { + this.animations.splice(index, 1); + chart.animating = false; + } + }, + + requestAnimationFrame: function() { + var me = this; + if (me.request === null) { + // Skip animation frame requests until the active one is executed. + // This can happen when processing mouse events, e.g. 'mousemove' + // and 'mouseout' events will trigger multiple renders. + me.request = helpers$1.requestAnimFrame.call(window, function() { + me.request = null; + me.startDigest(); + }); + } + }, + + /** + * @private + */ + startDigest: function() { + var me = this; + + me.advance(); + + // Do we have more stuff to animate? + if (me.animations.length > 0) { + me.requestAnimationFrame(); + } + }, + + /** + * @private + */ + advance: function() { + var animations = this.animations; + var animation, chart, numSteps, nextStep; + var i = 0; + + // 1 animation per chart, so we are looping charts here + while (i < animations.length) { + animation = animations[i]; + chart = animation.chart; + numSteps = animation.numSteps; + + // Make sure that currentStep starts at 1 + // https://github.com/chartjs/Chart.js/issues/6104 + nextStep = Math.floor((Date.now() - animation.startTime) / animation.duration * numSteps) + 1; + animation.currentStep = Math.min(nextStep, numSteps); + + helpers$1.callback(animation.render, [chart, animation], chart); + helpers$1.callback(animation.onAnimationProgress, [animation], chart); + + if (animation.currentStep >= numSteps) { + helpers$1.callback(animation.onAnimationComplete, [animation], chart); + chart.animating = false; + animations.splice(i, 1); + } else { + ++i; + } + } + } +}; + +var resolve = helpers$1.options.resolve; + +var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift']; + +/** + * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice', + * 'unshift') and notify the listener AFTER the array has been altered. Listeners are + * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments. + */ +function listenArrayEvents(array, listener) { + if (array._chartjs) { + array._chartjs.listeners.push(listener); + return; + } + + Object.defineProperty(array, '_chartjs', { + configurable: true, + enumerable: false, + value: { + listeners: [listener] + } + }); + + arrayEvents.forEach(function(key) { + var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1); + var base = array[key]; + + Object.defineProperty(array, key, { + configurable: true, + enumerable: false, + value: function() { + var args = Array.prototype.slice.call(arguments); + var res = base.apply(this, args); + + helpers$1.each(array._chartjs.listeners, function(object) { + if (typeof object[method] === 'function') { + object[method].apply(object, args); + } + }); + + return res; + } + }); + }); +} + +/** + * Removes the given array event listener and cleanup extra attached properties (such as + * the _chartjs stub and overridden methods) if array doesn't have any more listeners. + */ +function unlistenArrayEvents(array, listener) { + var stub = array._chartjs; + if (!stub) { + return; + } + + var listeners = stub.listeners; + var index = listeners.indexOf(listener); + if (index !== -1) { + listeners.splice(index, 1); + } + + if (listeners.length > 0) { + return; + } + + arrayEvents.forEach(function(key) { + delete array[key]; + }); + + delete array._chartjs; +} + +// Base class for all dataset controllers (line, bar, etc) +var DatasetController = function(chart, datasetIndex) { + this.initialize(chart, datasetIndex); +}; + +helpers$1.extend(DatasetController.prototype, { + + /** + * Element type used to generate a meta dataset (e.g. Chart.element.Line). + * @type {Chart.core.element} + */ + datasetElementType: null, + + /** + * Element type used to generate a meta data (e.g. Chart.element.Point). + * @type {Chart.core.element} + */ + dataElementType: null, + + /** + * Dataset element option keys to be resolved in _resolveDatasetElementOptions. + * A derived controller may override this to resolve controller-specific options. + * The keys defined here are for backward compatibility for legend styles. + * @private + */ + _datasetElementOptions: [ + 'backgroundColor', + 'borderCapStyle', + 'borderColor', + 'borderDash', + 'borderDashOffset', + 'borderJoinStyle', + 'borderWidth' + ], + + /** + * Data element option keys to be resolved in _resolveDataElementOptions. + * A derived controller may override this to resolve controller-specific options. + * The keys defined here are for backward compatibility for legend styles. + * @private + */ + _dataElementOptions: [ + 'backgroundColor', + 'borderColor', + 'borderWidth', + 'pointStyle' + ], + + initialize: function(chart, datasetIndex) { + var me = this; + me.chart = chart; + me.index = datasetIndex; + me.linkScales(); + me.addElements(); + me._type = me.getMeta().type; + }, + + updateIndex: function(datasetIndex) { + this.index = datasetIndex; + }, + + linkScales: function() { + var me = this; + var meta = me.getMeta(); + var chart = me.chart; + var scales = chart.scales; + var dataset = me.getDataset(); + var scalesOpts = chart.options.scales; + + if (meta.xAxisID === null || !(meta.xAxisID in scales) || dataset.xAxisID) { + meta.xAxisID = dataset.xAxisID || scalesOpts.xAxes[0].id; + } + if (meta.yAxisID === null || !(meta.yAxisID in scales) || dataset.yAxisID) { + meta.yAxisID = dataset.yAxisID || scalesOpts.yAxes[0].id; + } + }, + + getDataset: function() { + return this.chart.data.datasets[this.index]; + }, + + getMeta: function() { + return this.chart.getDatasetMeta(this.index); + }, + + getScaleForId: function(scaleID) { + return this.chart.scales[scaleID]; + }, + + /** + * @private + */ + _getValueScaleId: function() { + return this.getMeta().yAxisID; + }, + + /** + * @private + */ + _getIndexScaleId: function() { + return this.getMeta().xAxisID; + }, + + /** + * @private + */ + _getValueScale: function() { + return this.getScaleForId(this._getValueScaleId()); + }, + + /** + * @private + */ + _getIndexScale: function() { + return this.getScaleForId(this._getIndexScaleId()); + }, + + reset: function() { + this._update(true); + }, + + /** + * @private + */ + destroy: function() { + if (this._data) { + unlistenArrayEvents(this._data, this); + } + }, + + createMetaDataset: function() { + var me = this; + var type = me.datasetElementType; + return type && new type({ + _chart: me.chart, + _datasetIndex: me.index + }); + }, + + createMetaData: function(index) { + var me = this; + var type = me.dataElementType; + return type && new type({ + _chart: me.chart, + _datasetIndex: me.index, + _index: index + }); + }, + + addElements: function() { + var me = this; + var meta = me.getMeta(); + var data = me.getDataset().data || []; + var metaData = meta.data; + var i, ilen; + + for (i = 0, ilen = data.length; i < ilen; ++i) { + metaData[i] = metaData[i] || me.createMetaData(i); + } + + meta.dataset = meta.dataset || me.createMetaDataset(); + }, + + addElementAndReset: function(index) { + var element = this.createMetaData(index); + this.getMeta().data.splice(index, 0, element); + this.updateElement(element, index, true); + }, + + buildOrUpdateElements: function() { + var me = this; + var dataset = me.getDataset(); + var data = dataset.data || (dataset.data = []); + + // In order to correctly handle data addition/deletion animation (an thus simulate + // real-time charts), we need to monitor these data modifications and synchronize + // the internal meta data accordingly. + if (me._data !== data) { + if (me._data) { + // This case happens when the user replaced the data array instance. + unlistenArrayEvents(me._data, me); + } + + if (data && Object.isExtensible(data)) { + listenArrayEvents(data, me); + } + me._data = data; + } + + // Re-sync meta data in case the user replaced the data array or if we missed + // any updates and so make sure that we handle number of datapoints changing. + me.resyncElements(); + }, + + /** + * Returns the merged user-supplied and default dataset-level options + * @private + */ + _configure: function() { + var me = this; + me._config = helpers$1.merge({}, [ + me.chart.options.datasets[me._type], + me.getDataset(), + ], { + merger: function(key, target, source) { + if (key !== '_meta' && key !== 'data') { + helpers$1._merger(key, target, source); + } + } + }); + }, + + _update: function(reset) { + var me = this; + me._configure(); + me._cachedDataOpts = null; + me.update(reset); + }, + + update: helpers$1.noop, + + transition: function(easingValue) { + var meta = this.getMeta(); + var elements = meta.data || []; + var ilen = elements.length; + var i = 0; + + for (; i < ilen; ++i) { + elements[i].transition(easingValue); + } + + if (meta.dataset) { + meta.dataset.transition(easingValue); + } + }, + + draw: function() { + var meta = this.getMeta(); + var elements = meta.data || []; + var ilen = elements.length; + var i = 0; + + if (meta.dataset) { + meta.dataset.draw(); + } + + for (; i < ilen; ++i) { + elements[i].draw(); + } + }, + + /** + * Returns a set of predefined style properties that should be used to represent the dataset + * or the data if the index is specified + * @param {number} index - data index + * @return {IStyleInterface} style object + */ + getStyle: function(index) { + var me = this; + var meta = me.getMeta(); + var dataset = meta.dataset; + var style; + + me._configure(); + if (dataset && index === undefined) { + style = me._resolveDatasetElementOptions(dataset || {}); + } else { + index = index || 0; + style = me._resolveDataElementOptions(meta.data[index] || {}, index); + } + + if (style.fill === false || style.fill === null) { + style.backgroundColor = style.borderColor; + } + + return style; + }, + + /** + * @private + */ + _resolveDatasetElementOptions: function(element, hover) { + var me = this; + var chart = me.chart; + var datasetOpts = me._config; + var custom = element.custom || {}; + var options = chart.options.elements[me.datasetElementType.prototype._type] || {}; + var elementOptions = me._datasetElementOptions; + var values = {}; + var i, ilen, key, readKey; + + // Scriptable options + var context = { + chart: chart, + dataset: me.getDataset(), + datasetIndex: me.index, + hover: hover + }; + + for (i = 0, ilen = elementOptions.length; i < ilen; ++i) { + key = elementOptions[i]; + readKey = hover ? 'hover' + key.charAt(0).toUpperCase() + key.slice(1) : key; + values[key] = resolve([ + custom[readKey], + datasetOpts[readKey], + options[readKey] + ], context); + } + + return values; + }, + + /** + * @private + */ + _resolveDataElementOptions: function(element, index) { + var me = this; + var custom = element && element.custom; + var cached = me._cachedDataOpts; + if (cached && !custom) { + return cached; + } + var chart = me.chart; + var datasetOpts = me._config; + var options = chart.options.elements[me.dataElementType.prototype._type] || {}; + var elementOptions = me._dataElementOptions; + var values = {}; + + // Scriptable options + var context = { + chart: chart, + dataIndex: index, + dataset: me.getDataset(), + datasetIndex: me.index + }; + + // `resolve` sets cacheable to `false` if any option is indexed or scripted + var info = {cacheable: !custom}; + + var keys, i, ilen, key; + + custom = custom || {}; + + if (helpers$1.isArray(elementOptions)) { + for (i = 0, ilen = elementOptions.length; i < ilen; ++i) { + key = elementOptions[i]; + values[key] = resolve([ + custom[key], + datasetOpts[key], + options[key] + ], context, index, info); + } + } else { + keys = Object.keys(elementOptions); + for (i = 0, ilen = keys.length; i < ilen; ++i) { + key = keys[i]; + values[key] = resolve([ + custom[key], + datasetOpts[elementOptions[key]], + datasetOpts[key], + options[key] + ], context, index, info); + } + } + + if (info.cacheable) { + me._cachedDataOpts = Object.freeze(values); + } + + return values; + }, + + removeHoverStyle: function(element) { + helpers$1.merge(element._model, element.$previousStyle || {}); + delete element.$previousStyle; + }, + + setHoverStyle: function(element) { + var dataset = this.chart.data.datasets[element._datasetIndex]; + var index = element._index; + var custom = element.custom || {}; + var model = element._model; + var getHoverColor = helpers$1.getHoverColor; + + element.$previousStyle = { + backgroundColor: model.backgroundColor, + borderColor: model.borderColor, + borderWidth: model.borderWidth + }; + + model.backgroundColor = resolve([custom.hoverBackgroundColor, dataset.hoverBackgroundColor, getHoverColor(model.backgroundColor)], undefined, index); + model.borderColor = resolve([custom.hoverBorderColor, dataset.hoverBorderColor, getHoverColor(model.borderColor)], undefined, index); + model.borderWidth = resolve([custom.hoverBorderWidth, dataset.hoverBorderWidth, model.borderWidth], undefined, index); + }, + + /** + * @private + */ + _removeDatasetHoverStyle: function() { + var element = this.getMeta().dataset; + + if (element) { + this.removeHoverStyle(element); + } + }, + + /** + * @private + */ + _setDatasetHoverStyle: function() { + var element = this.getMeta().dataset; + var prev = {}; + var i, ilen, key, keys, hoverOptions, model; + + if (!element) { + return; + } + + model = element._model; + hoverOptions = this._resolveDatasetElementOptions(element, true); + + keys = Object.keys(hoverOptions); + for (i = 0, ilen = keys.length; i < ilen; ++i) { + key = keys[i]; + prev[key] = model[key]; + model[key] = hoverOptions[key]; + } + + element.$previousStyle = prev; + }, + + /** + * @private + */ + resyncElements: function() { + var me = this; + var meta = me.getMeta(); + var data = me.getDataset().data; + var numMeta = meta.data.length; + var numData = data.length; + + if (numData < numMeta) { + meta.data.splice(numData, numMeta - numData); + } else if (numData > numMeta) { + me.insertElements(numMeta, numData - numMeta); + } + }, + + /** + * @private + */ + insertElements: function(start, count) { + for (var i = 0; i < count; ++i) { + this.addElementAndReset(start + i); + } + }, + + /** + * @private + */ + onDataPush: function() { + var count = arguments.length; + this.insertElements(this.getDataset().data.length - count, count); + }, + + /** + * @private + */ + onDataPop: function() { + this.getMeta().data.pop(); + }, + + /** + * @private + */ + onDataShift: function() { + this.getMeta().data.shift(); + }, + + /** + * @private + */ + onDataSplice: function(start, count) { + this.getMeta().data.splice(start, count); + this.insertElements(start, arguments.length - 2); + }, + + /** + * @private + */ + onDataUnshift: function() { + this.insertElements(0, arguments.length); + } +}); + +DatasetController.extend = helpers$1.inherits; + +var core_datasetController = DatasetController; + +var TAU = Math.PI * 2; + +core_defaults._set('global', { + elements: { + arc: { + backgroundColor: core_defaults.global.defaultColor, + borderColor: '#fff', + borderWidth: 2, + borderAlign: 'center' + } + } +}); + +function clipArc(ctx, arc) { + var startAngle = arc.startAngle; + var endAngle = arc.endAngle; + var pixelMargin = arc.pixelMargin; + var angleMargin = pixelMargin / arc.outerRadius; + var x = arc.x; + var y = arc.y; + + // Draw an inner border by cliping the arc and drawing a double-width border + // Enlarge the clipping arc by 0.33 pixels to eliminate glitches between borders + ctx.beginPath(); + ctx.arc(x, y, arc.outerRadius, startAngle - angleMargin, endAngle + angleMargin); + if (arc.innerRadius > pixelMargin) { + angleMargin = pixelMargin / arc.innerRadius; + ctx.arc(x, y, arc.innerRadius - pixelMargin, endAngle + angleMargin, startAngle - angleMargin, true); + } else { + ctx.arc(x, y, pixelMargin, endAngle + Math.PI / 2, startAngle - Math.PI / 2); + } + ctx.closePath(); + ctx.clip(); +} + +function drawFullCircleBorders(ctx, vm, arc, inner) { + var endAngle = arc.endAngle; + var i; + + if (inner) { + arc.endAngle = arc.startAngle + TAU; + clipArc(ctx, arc); + arc.endAngle = endAngle; + if (arc.endAngle === arc.startAngle && arc.fullCircles) { + arc.endAngle += TAU; + arc.fullCircles--; + } + } + + ctx.beginPath(); + ctx.arc(arc.x, arc.y, arc.innerRadius, arc.startAngle + TAU, arc.startAngle, true); + for (i = 0; i < arc.fullCircles; ++i) { + ctx.stroke(); + } + + ctx.beginPath(); + ctx.arc(arc.x, arc.y, vm.outerRadius, arc.startAngle, arc.startAngle + TAU); + for (i = 0; i < arc.fullCircles; ++i) { + ctx.stroke(); + } +} + +function drawBorder(ctx, vm, arc) { + var inner = vm.borderAlign === 'inner'; + + if (inner) { + ctx.lineWidth = vm.borderWidth * 2; + ctx.lineJoin = 'round'; + } else { + ctx.lineWidth = vm.borderWidth; + ctx.lineJoin = 'bevel'; + } + + if (arc.fullCircles) { + drawFullCircleBorders(ctx, vm, arc, inner); + } + + if (inner) { + clipArc(ctx, arc); + } + + ctx.beginPath(); + ctx.arc(arc.x, arc.y, vm.outerRadius, arc.startAngle, arc.endAngle); + ctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true); + ctx.closePath(); + ctx.stroke(); +} + +var element_arc = core_element.extend({ + _type: 'arc', + + inLabelRange: function(mouseX) { + var vm = this._view; + + if (vm) { + return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2)); + } + return false; + }, + + inRange: function(chartX, chartY) { + var vm = this._view; + + if (vm) { + var pointRelativePosition = helpers$1.getAngleFromPoint(vm, {x: chartX, y: chartY}); + var angle = pointRelativePosition.angle; + var distance = pointRelativePosition.distance; + + // Sanitise angle range + var startAngle = vm.startAngle; + var endAngle = vm.endAngle; + while (endAngle < startAngle) { + endAngle += TAU; + } + while (angle > endAngle) { + angle -= TAU; + } + while (angle < startAngle) { + angle += TAU; + } + + // Check if within the range of the open/close angle + var betweenAngles = (angle >= startAngle && angle <= endAngle); + var withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius); + + return (betweenAngles && withinRadius); + } + return false; + }, + + getCenterPoint: function() { + var vm = this._view; + var halfAngle = (vm.startAngle + vm.endAngle) / 2; + var halfRadius = (vm.innerRadius + vm.outerRadius) / 2; + return { + x: vm.x + Math.cos(halfAngle) * halfRadius, + y: vm.y + Math.sin(halfAngle) * halfRadius + }; + }, + + getArea: function() { + var vm = this._view; + return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2)); + }, + + tooltipPosition: function() { + var vm = this._view; + var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2); + var rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius; + + return { + x: vm.x + (Math.cos(centreAngle) * rangeFromCentre), + y: vm.y + (Math.sin(centreAngle) * rangeFromCentre) + }; + }, + + draw: function() { + var ctx = this._chart.ctx; + var vm = this._view; + var pixelMargin = (vm.borderAlign === 'inner') ? 0.33 : 0; + var arc = { + x: vm.x, + y: vm.y, + innerRadius: vm.innerRadius, + outerRadius: Math.max(vm.outerRadius - pixelMargin, 0), + pixelMargin: pixelMargin, + startAngle: vm.startAngle, + endAngle: vm.endAngle, + fullCircles: Math.floor(vm.circumference / TAU) + }; + var i; + + ctx.save(); + + ctx.fillStyle = vm.backgroundColor; + ctx.strokeStyle = vm.borderColor; + + if (arc.fullCircles) { + arc.endAngle = arc.startAngle + TAU; + ctx.beginPath(); + ctx.arc(arc.x, arc.y, arc.outerRadius, arc.startAngle, arc.endAngle); + ctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true); + ctx.closePath(); + for (i = 0; i < arc.fullCircles; ++i) { + ctx.fill(); + } + arc.endAngle = arc.startAngle + vm.circumference % TAU; + } + + ctx.beginPath(); + ctx.arc(arc.x, arc.y, arc.outerRadius, arc.startAngle, arc.endAngle); + ctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true); + ctx.closePath(); + ctx.fill(); + + if (vm.borderWidth) { + drawBorder(ctx, vm, arc); + } + + ctx.restore(); + } +}); + +var valueOrDefault$1 = helpers$1.valueOrDefault; + +var defaultColor = core_defaults.global.defaultColor; + +core_defaults._set('global', { + elements: { + line: { + tension: 0.4, + backgroundColor: defaultColor, + borderWidth: 3, + borderColor: defaultColor, + borderCapStyle: 'butt', + borderDash: [], + borderDashOffset: 0.0, + borderJoinStyle: 'miter', + capBezierPoints: true, + fill: true, // do we fill in the area between the line and its base axis + } + } +}); + +var element_line = core_element.extend({ + _type: 'line', + + draw: function() { + var me = this; + var vm = me._view; + var ctx = me._chart.ctx; + var spanGaps = vm.spanGaps; + var points = me._children.slice(); // clone array + var globalDefaults = core_defaults.global; + var globalOptionLineElements = globalDefaults.elements.line; + var lastDrawnIndex = -1; + var closePath = me._loop; + var index, previous, currentVM; + + if (!points.length) { + return; + } + + if (me._loop) { + for (index = 0; index < points.length; ++index) { + previous = helpers$1.previousItem(points, index); + // If the line has an open path, shift the point array + if (!points[index]._view.skip && previous._view.skip) { + points = points.slice(index).concat(points.slice(0, index)); + closePath = spanGaps; + break; + } + } + // If the line has a close path, add the first point again + if (closePath) { + points.push(points[0]); + } + } + + ctx.save(); + + // Stroke Line Options + ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle; + + // IE 9 and 10 do not support line dash + if (ctx.setLineDash) { + ctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash); + } + + ctx.lineDashOffset = valueOrDefault$1(vm.borderDashOffset, globalOptionLineElements.borderDashOffset); + ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle; + ctx.lineWidth = valueOrDefault$1(vm.borderWidth, globalOptionLineElements.borderWidth); + ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor; + + // Stroke Line + ctx.beginPath(); + + // First point moves to it's starting position no matter what + currentVM = points[0]._view; + if (!currentVM.skip) { + ctx.moveTo(currentVM.x, currentVM.y); + lastDrawnIndex = 0; + } + + for (index = 1; index < points.length; ++index) { + currentVM = points[index]._view; + previous = lastDrawnIndex === -1 ? helpers$1.previousItem(points, index) : points[lastDrawnIndex]; + + if (!currentVM.skip) { + if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) { + // There was a gap and this is the first point after the gap + ctx.moveTo(currentVM.x, currentVM.y); + } else { + // Line to next point + helpers$1.canvas.lineTo(ctx, previous._view, currentVM); + } + lastDrawnIndex = index; + } + } + + if (closePath) { + ctx.closePath(); + } + + ctx.stroke(); + ctx.restore(); + } +}); + +var valueOrDefault$2 = helpers$1.valueOrDefault; + +var defaultColor$1 = core_defaults.global.defaultColor; + +core_defaults._set('global', { + elements: { + point: { + radius: 3, + pointStyle: 'circle', + backgroundColor: defaultColor$1, + borderColor: defaultColor$1, + borderWidth: 1, + // Hover + hitRadius: 1, + hoverRadius: 4, + hoverBorderWidth: 1 + } + } +}); + +function xRange(mouseX) { + var vm = this._view; + return vm ? (Math.abs(mouseX - vm.x) < vm.radius + vm.hitRadius) : false; +} + +function yRange(mouseY) { + var vm = this._view; + return vm ? (Math.abs(mouseY - vm.y) < vm.radius + vm.hitRadius) : false; +} + +var element_point = core_element.extend({ + _type: 'point', + + inRange: function(mouseX, mouseY) { + var vm = this._view; + return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false; + }, + + inLabelRange: xRange, + inXRange: xRange, + inYRange: yRange, + + getCenterPoint: function() { + var vm = this._view; + return { + x: vm.x, + y: vm.y + }; + }, + + getArea: function() { + return Math.PI * Math.pow(this._view.radius, 2); + }, + + tooltipPosition: function() { + var vm = this._view; + return { + x: vm.x, + y: vm.y, + padding: vm.radius + vm.borderWidth + }; + }, + + draw: function(chartArea) { + var vm = this._view; + var ctx = this._chart.ctx; + var pointStyle = vm.pointStyle; + var rotation = vm.rotation; + var radius = vm.radius; + var x = vm.x; + var y = vm.y; + var globalDefaults = core_defaults.global; + var defaultColor = globalDefaults.defaultColor; // eslint-disable-line no-shadow + + if (vm.skip) { + return; + } + + // Clipping for Points. + if (chartArea === undefined || helpers$1.canvas._isPointInArea(vm, chartArea)) { + ctx.strokeStyle = vm.borderColor || defaultColor; + ctx.lineWidth = valueOrDefault$2(vm.borderWidth, globalDefaults.elements.point.borderWidth); + ctx.fillStyle = vm.backgroundColor || defaultColor; + helpers$1.canvas.drawPoint(ctx, pointStyle, radius, x, y, rotation); + } + } +}); + +var defaultColor$2 = core_defaults.global.defaultColor; + +core_defaults._set('global', { + elements: { + rectangle: { + backgroundColor: defaultColor$2, + borderColor: defaultColor$2, + borderSkipped: 'bottom', + borderWidth: 0 + } + } +}); + +function isVertical(vm) { + return vm && vm.width !== undefined; +} + +/** + * Helper function to get the bounds of the bar regardless of the orientation + * @param bar {Chart.Element.Rectangle} the bar + * @return {Bounds} bounds of the bar + * @private + */ +function getBarBounds(vm) { + var x1, x2, y1, y2, half; + + if (isVertical(vm)) { + half = vm.width / 2; + x1 = vm.x - half; + x2 = vm.x + half; + y1 = Math.min(vm.y, vm.base); + y2 = Math.max(vm.y, vm.base); + } else { + half = vm.height / 2; + x1 = Math.min(vm.x, vm.base); + x2 = Math.max(vm.x, vm.base); + y1 = vm.y - half; + y2 = vm.y + half; + } + + return { + left: x1, + top: y1, + right: x2, + bottom: y2 + }; +} + +function swap(orig, v1, v2) { + return orig === v1 ? v2 : orig === v2 ? v1 : orig; +} + +function parseBorderSkipped(vm) { + var edge = vm.borderSkipped; + var res = {}; + + if (!edge) { + return res; + } + + if (vm.horizontal) { + if (vm.base > vm.x) { + edge = swap(edge, 'left', 'right'); + } + } else if (vm.base < vm.y) { + edge = swap(edge, 'bottom', 'top'); + } + + res[edge] = true; + return res; +} + +function parseBorderWidth(vm, maxW, maxH) { + var value = vm.borderWidth; + var skip = parseBorderSkipped(vm); + var t, r, b, l; + + if (helpers$1.isObject(value)) { + t = +value.top || 0; + r = +value.right || 0; + b = +value.bottom || 0; + l = +value.left || 0; + } else { + t = r = b = l = +value || 0; + } + + return { + t: skip.top || (t < 0) ? 0 : t > maxH ? maxH : t, + r: skip.right || (r < 0) ? 0 : r > maxW ? maxW : r, + b: skip.bottom || (b < 0) ? 0 : b > maxH ? maxH : b, + l: skip.left || (l < 0) ? 0 : l > maxW ? maxW : l + }; +} + +function boundingRects(vm) { + var bounds = getBarBounds(vm); + var width = bounds.right - bounds.left; + var height = bounds.bottom - bounds.top; + var border = parseBorderWidth(vm, width / 2, height / 2); + + return { + outer: { + x: bounds.left, + y: bounds.top, + w: width, + h: height + }, + inner: { + x: bounds.left + border.l, + y: bounds.top + border.t, + w: width - border.l - border.r, + h: height - border.t - border.b + } + }; +} + +function inRange(vm, x, y) { + var skipX = x === null; + var skipY = y === null; + var bounds = !vm || (skipX && skipY) ? false : getBarBounds(vm); + + return bounds + && (skipX || x >= bounds.left && x <= bounds.right) + && (skipY || y >= bounds.top && y <= bounds.bottom); +} + +var element_rectangle = core_element.extend({ + _type: 'rectangle', + + draw: function() { + var ctx = this._chart.ctx; + var vm = this._view; + var rects = boundingRects(vm); + var outer = rects.outer; + var inner = rects.inner; + + ctx.fillStyle = vm.backgroundColor; + ctx.fillRect(outer.x, outer.y, outer.w, outer.h); + + if (outer.w === inner.w && outer.h === inner.h) { + return; + } + + ctx.save(); + ctx.beginPath(); + ctx.rect(outer.x, outer.y, outer.w, outer.h); + ctx.clip(); + ctx.fillStyle = vm.borderColor; + ctx.rect(inner.x, inner.y, inner.w, inner.h); + ctx.fill('evenodd'); + ctx.restore(); + }, + + height: function() { + var vm = this._view; + return vm.base - vm.y; + }, + + inRange: function(mouseX, mouseY) { + return inRange(this._view, mouseX, mouseY); + }, + + inLabelRange: function(mouseX, mouseY) { + var vm = this._view; + return isVertical(vm) + ? inRange(vm, mouseX, null) + : inRange(vm, null, mouseY); + }, + + inXRange: function(mouseX) { + return inRange(this._view, mouseX, null); + }, + + inYRange: function(mouseY) { + return inRange(this._view, null, mouseY); + }, + + getCenterPoint: function() { + var vm = this._view; + var x, y; + if (isVertical(vm)) { + x = vm.x; + y = (vm.y + vm.base) / 2; + } else { + x = (vm.x + vm.base) / 2; + y = vm.y; + } + + return {x: x, y: y}; + }, + + getArea: function() { + var vm = this._view; + + return isVertical(vm) + ? vm.width * Math.abs(vm.y - vm.base) + : vm.height * Math.abs(vm.x - vm.base); + }, + + tooltipPosition: function() { + var vm = this._view; + return { + x: vm.x, + y: vm.y + }; + } +}); + +var elements = {}; +var Arc = element_arc; +var Line = element_line; +var Point = element_point; +var Rectangle = element_rectangle; +elements.Arc = Arc; +elements.Line = Line; +elements.Point = Point; +elements.Rectangle = Rectangle; + +var deprecated = helpers$1._deprecated; +var valueOrDefault$3 = helpers$1.valueOrDefault; + +core_defaults._set('bar', { + hover: { + mode: 'label' + }, + + scales: { + xAxes: [{ + type: 'category', + offset: true, + gridLines: { + offsetGridLines: true + } + }], + + yAxes: [{ + type: 'linear' + }] + } +}); + +core_defaults._set('global', { + datasets: { + bar: { + categoryPercentage: 0.8, + barPercentage: 0.9 + } + } +}); + +/** + * Computes the "optimal" sample size to maintain bars equally sized while preventing overlap. + * @private + */ +function computeMinSampleSize(scale, pixels) { + var min = scale._length; + var prev, curr, i, ilen; + + for (i = 1, ilen = pixels.length; i < ilen; ++i) { + min = Math.min(min, Math.abs(pixels[i] - pixels[i - 1])); + } + + for (i = 0, ilen = scale.getTicks().length; i < ilen; ++i) { + curr = scale.getPixelForTick(i); + min = i > 0 ? Math.min(min, Math.abs(curr - prev)) : min; + prev = curr; + } + + return min; +} + +/** + * Computes an "ideal" category based on the absolute bar thickness or, if undefined or null, + * uses the smallest interval (see computeMinSampleSize) that prevents bar overlapping. This + * mode currently always generates bars equally sized (until we introduce scriptable options?). + * @private + */ +function computeFitCategoryTraits(index, ruler, options) { + var thickness = options.barThickness; + var count = ruler.stackCount; + var curr = ruler.pixels[index]; + var min = helpers$1.isNullOrUndef(thickness) + ? computeMinSampleSize(ruler.scale, ruler.pixels) + : -1; + var size, ratio; + + if (helpers$1.isNullOrUndef(thickness)) { + size = min * options.categoryPercentage; + ratio = options.barPercentage; + } else { + // When bar thickness is enforced, category and bar percentages are ignored. + // Note(SB): we could add support for relative bar thickness (e.g. barThickness: '50%') + // and deprecate barPercentage since this value is ignored when thickness is absolute. + size = thickness * count; + ratio = 1; + } + + return { + chunk: size / count, + ratio: ratio, + start: curr - (size / 2) + }; +} + +/** + * Computes an "optimal" category that globally arranges bars side by side (no gap when + * percentage options are 1), based on the previous and following categories. This mode + * generates bars with different widths when data are not evenly spaced. + * @private + */ +function computeFlexCategoryTraits(index, ruler, options) { + var pixels = ruler.pixels; + var curr = pixels[index]; + var prev = index > 0 ? pixels[index - 1] : null; + var next = index < pixels.length - 1 ? pixels[index + 1] : null; + var percent = options.categoryPercentage; + var start, size; + + if (prev === null) { + // first data: its size is double based on the next point or, + // if it's also the last data, we use the scale size. + prev = curr - (next === null ? ruler.end - ruler.start : next - curr); + } + + if (next === null) { + // last data: its size is also double based on the previous point. + next = curr + curr - prev; + } + + start = curr - (curr - Math.min(prev, next)) / 2 * percent; + size = Math.abs(next - prev) / 2 * percent; + + return { + chunk: size / ruler.stackCount, + ratio: options.barPercentage, + start: start + }; +} + +var controller_bar = core_datasetController.extend({ + + dataElementType: elements.Rectangle, + + /** + * @private + */ + _dataElementOptions: [ + 'backgroundColor', + 'borderColor', + 'borderSkipped', + 'borderWidth', + 'barPercentage', + 'barThickness', + 'categoryPercentage', + 'maxBarThickness', + 'minBarLength' + ], + + initialize: function() { + var me = this; + var meta, scaleOpts; + + core_datasetController.prototype.initialize.apply(me, arguments); + + meta = me.getMeta(); + meta.stack = me.getDataset().stack; + meta.bar = true; + + scaleOpts = me._getIndexScale().options; + deprecated('bar chart', scaleOpts.barPercentage, 'scales.[x/y]Axes.barPercentage', 'dataset.barPercentage'); + deprecated('bar chart', scaleOpts.barThickness, 'scales.[x/y]Axes.barThickness', 'dataset.barThickness'); + deprecated('bar chart', scaleOpts.categoryPercentage, 'scales.[x/y]Axes.categoryPercentage', 'dataset.categoryPercentage'); + deprecated('bar chart', me._getValueScale().options.minBarLength, 'scales.[x/y]Axes.minBarLength', 'dataset.minBarLength'); + deprecated('bar chart', scaleOpts.maxBarThickness, 'scales.[x/y]Axes.maxBarThickness', 'dataset.maxBarThickness'); + }, + + update: function(reset) { + var me = this; + var rects = me.getMeta().data; + var i, ilen; + + me._ruler = me.getRuler(); + + for (i = 0, ilen = rects.length; i < ilen; ++i) { + me.updateElement(rects[i], i, reset); + } + }, + + updateElement: function(rectangle, index, reset) { + var me = this; + var meta = me.getMeta(); + var dataset = me.getDataset(); + var options = me._resolveDataElementOptions(rectangle, index); + + rectangle._xScale = me.getScaleForId(meta.xAxisID); + rectangle._yScale = me.getScaleForId(meta.yAxisID); + rectangle._datasetIndex = me.index; + rectangle._index = index; + rectangle._model = { + backgroundColor: options.backgroundColor, + borderColor: options.borderColor, + borderSkipped: options.borderSkipped, + borderWidth: options.borderWidth, + datasetLabel: dataset.label, + label: me.chart.data.labels[index] + }; + + if (helpers$1.isArray(dataset.data[index])) { + rectangle._model.borderSkipped = null; + } + + me._updateElementGeometry(rectangle, index, reset, options); + + rectangle.pivot(); + }, + + /** + * @private + */ + _updateElementGeometry: function(rectangle, index, reset, options) { + var me = this; + var model = rectangle._model; + var vscale = me._getValueScale(); + var base = vscale.getBasePixel(); + var horizontal = vscale.isHorizontal(); + var ruler = me._ruler || me.getRuler(); + var vpixels = me.calculateBarValuePixels(me.index, index, options); + var ipixels = me.calculateBarIndexPixels(me.index, index, ruler, options); + + model.horizontal = horizontal; + model.base = reset ? base : vpixels.base; + model.x = horizontal ? reset ? base : vpixels.head : ipixels.center; + model.y = horizontal ? ipixels.center : reset ? base : vpixels.head; + model.height = horizontal ? ipixels.size : undefined; + model.width = horizontal ? undefined : ipixels.size; + }, + + /** + * Returns the stacks based on groups and bar visibility. + * @param {number} [last] - The dataset index + * @returns {string[]} The list of stack IDs + * @private + */ + _getStacks: function(last) { + var me = this; + var scale = me._getIndexScale(); + var metasets = scale._getMatchingVisibleMetas(me._type); + var stacked = scale.options.stacked; + var ilen = metasets.length; + var stacks = []; + var i, meta; + + for (i = 0; i < ilen; ++i) { + meta = metasets[i]; + // stacked | meta.stack + // | found | not found | undefined + // false | x | x | x + // true | | x | + // undefined | | x | x + if (stacked === false || stacks.indexOf(meta.stack) === -1 || + (stacked === undefined && meta.stack === undefined)) { + stacks.push(meta.stack); + } + if (meta.index === last) { + break; + } + } + + return stacks; + }, + + /** + * Returns the effective number of stacks based on groups and bar visibility. + * @private + */ + getStackCount: function() { + return this._getStacks().length; + }, + + /** + * Returns the stack index for the given dataset based on groups and bar visibility. + * @param {number} [datasetIndex] - The dataset index + * @param {string} [name] - The stack name to find + * @returns {number} The stack index + * @private + */ + getStackIndex: function(datasetIndex, name) { + var stacks = this._getStacks(datasetIndex); + var index = (name !== undefined) + ? stacks.indexOf(name) + : -1; // indexOf returns -1 if element is not present + + return (index === -1) + ? stacks.length - 1 + : index; + }, + + /** + * @private + */ + getRuler: function() { + var me = this; + var scale = me._getIndexScale(); + var pixels = []; + var i, ilen; + + for (i = 0, ilen = me.getMeta().data.length; i < ilen; ++i) { + pixels.push(scale.getPixelForValue(null, i, me.index)); + } + + return { + pixels: pixels, + start: scale._startPixel, + end: scale._endPixel, + stackCount: me.getStackCount(), + scale: scale + }; + }, + + /** + * Note: pixel values are not clamped to the scale area. + * @private + */ + calculateBarValuePixels: function(datasetIndex, index, options) { + var me = this; + var chart = me.chart; + var scale = me._getValueScale(); + var isHorizontal = scale.isHorizontal(); + var datasets = chart.data.datasets; + var metasets = scale._getMatchingVisibleMetas(me._type); + var value = scale._parseValue(datasets[datasetIndex].data[index]); + var minBarLength = options.minBarLength; + var stacked = scale.options.stacked; + var stack = me.getMeta().stack; + var start = value.start === undefined ? 0 : value.max >= 0 && value.min >= 0 ? value.min : value.max; + var length = value.start === undefined ? value.end : value.max >= 0 && value.min >= 0 ? value.max - value.min : value.min - value.max; + var ilen = metasets.length; + var i, imeta, ivalue, base, head, size, stackLength; + + if (stacked || (stacked === undefined && stack !== undefined)) { + for (i = 0; i < ilen; ++i) { + imeta = metasets[i]; + + if (imeta.index === datasetIndex) { + break; + } + + if (imeta.stack === stack) { + stackLength = scale._parseValue(datasets[imeta.index].data[index]); + ivalue = stackLength.start === undefined ? stackLength.end : stackLength.min >= 0 && stackLength.max >= 0 ? stackLength.max : stackLength.min; + + if ((value.min < 0 && ivalue < 0) || (value.max >= 0 && ivalue > 0)) { + start += ivalue; + } + } + } + } + + base = scale.getPixelForValue(start); + head = scale.getPixelForValue(start + length); + size = head - base; + + if (minBarLength !== undefined && Math.abs(size) < minBarLength) { + size = minBarLength; + if (length >= 0 && !isHorizontal || length < 0 && isHorizontal) { + head = base - minBarLength; + } else { + head = base + minBarLength; + } + } + + return { + size: size, + base: base, + head: head, + center: head + size / 2 + }; + }, + + /** + * @private + */ + calculateBarIndexPixels: function(datasetIndex, index, ruler, options) { + var me = this; + var range = options.barThickness === 'flex' + ? computeFlexCategoryTraits(index, ruler, options) + : computeFitCategoryTraits(index, ruler, options); + + var stackIndex = me.getStackIndex(datasetIndex, me.getMeta().stack); + var center = range.start + (range.chunk * stackIndex) + (range.chunk / 2); + var size = Math.min( + valueOrDefault$3(options.maxBarThickness, Infinity), + range.chunk * range.ratio); + + return { + base: center - size / 2, + head: center + size / 2, + center: center, + size: size + }; + }, + + draw: function() { + var me = this; + var chart = me.chart; + var scale = me._getValueScale(); + var rects = me.getMeta().data; + var dataset = me.getDataset(); + var ilen = rects.length; + var i = 0; + + helpers$1.canvas.clipArea(chart.ctx, chart.chartArea); + + for (; i < ilen; ++i) { + var val = scale._parseValue(dataset.data[i]); + if (!isNaN(val.min) && !isNaN(val.max)) { + rects[i].draw(); + } + } + + helpers$1.canvas.unclipArea(chart.ctx); + }, + + /** + * @private + */ + _resolveDataElementOptions: function() { + var me = this; + var values = helpers$1.extend({}, core_datasetController.prototype._resolveDataElementOptions.apply(me, arguments)); + var indexOpts = me._getIndexScale().options; + var valueOpts = me._getValueScale().options; + + values.barPercentage = valueOrDefault$3(indexOpts.barPercentage, values.barPercentage); + values.barThickness = valueOrDefault$3(indexOpts.barThickness, values.barThickness); + values.categoryPercentage = valueOrDefault$3(indexOpts.categoryPercentage, values.categoryPercentage); + values.maxBarThickness = valueOrDefault$3(indexOpts.maxBarThickness, values.maxBarThickness); + values.minBarLength = valueOrDefault$3(valueOpts.minBarLength, values.minBarLength); + + return values; + } + +}); + +var valueOrDefault$4 = helpers$1.valueOrDefault; +var resolve$1 = helpers$1.options.resolve; + +core_defaults._set('bubble', { + hover: { + mode: 'single' + }, + + scales: { + xAxes: [{ + type: 'linear', // bubble should probably use a linear scale by default + position: 'bottom', + id: 'x-axis-0' // need an ID so datasets can reference the scale + }], + yAxes: [{ + type: 'linear', + position: 'left', + id: 'y-axis-0' + }] + }, + + tooltips: { + callbacks: { + title: function() { + // Title doesn't make sense for scatter since we format the data as a point + return ''; + }, + label: function(item, data) { + var datasetLabel = data.datasets[item.datasetIndex].label || ''; + var dataPoint = data.datasets[item.datasetIndex].data[item.index]; + return datasetLabel + ': (' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.r + ')'; + } + } + } +}); + +var controller_bubble = core_datasetController.extend({ + /** + * @protected + */ + dataElementType: elements.Point, + + /** + * @private + */ + _dataElementOptions: [ + 'backgroundColor', + 'borderColor', + 'borderWidth', + 'hoverBackgroundColor', + 'hoverBorderColor', + 'hoverBorderWidth', + 'hoverRadius', + 'hitRadius', + 'pointStyle', + 'rotation' + ], + + /** + * @protected + */ + update: function(reset) { + var me = this; + var meta = me.getMeta(); + var points = meta.data; + + // Update Points + helpers$1.each(points, function(point, index) { + me.updateElement(point, index, reset); + }); + }, + + /** + * @protected + */ + updateElement: function(point, index, reset) { + var me = this; + var meta = me.getMeta(); + var custom = point.custom || {}; + var xScale = me.getScaleForId(meta.xAxisID); + var yScale = me.getScaleForId(meta.yAxisID); + var options = me._resolveDataElementOptions(point, index); + var data = me.getDataset().data[index]; + var dsIndex = me.index; + + var x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex); + var y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex); + + point._xScale = xScale; + point._yScale = yScale; + point._options = options; + point._datasetIndex = dsIndex; + point._index = index; + point._model = { + backgroundColor: options.backgroundColor, + borderColor: options.borderColor, + borderWidth: options.borderWidth, + hitRadius: options.hitRadius, + pointStyle: options.pointStyle, + rotation: options.rotation, + radius: reset ? 0 : options.radius, + skip: custom.skip || isNaN(x) || isNaN(y), + x: x, + y: y, + }; + + point.pivot(); + }, + + /** + * @protected + */ + setHoverStyle: function(point) { + var model = point._model; + var options = point._options; + var getHoverColor = helpers$1.getHoverColor; + + point.$previousStyle = { + backgroundColor: model.backgroundColor, + borderColor: model.borderColor, + borderWidth: model.borderWidth, + radius: model.radius + }; + + model.backgroundColor = valueOrDefault$4(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); + model.borderColor = valueOrDefault$4(options.hoverBorderColor, getHoverColor(options.borderColor)); + model.borderWidth = valueOrDefault$4(options.hoverBorderWidth, options.borderWidth); + model.radius = options.radius + options.hoverRadius; + }, + + /** + * @private + */ + _resolveDataElementOptions: function(point, index) { + var me = this; + var chart = me.chart; + var dataset = me.getDataset(); + var custom = point.custom || {}; + var data = dataset.data[index] || {}; + var values = core_datasetController.prototype._resolveDataElementOptions.apply(me, arguments); + + // Scriptable options + var context = { + chart: chart, + dataIndex: index, + dataset: dataset, + datasetIndex: me.index + }; + + // In case values were cached (and thus frozen), we need to clone the values + if (me._cachedDataOpts === values) { + values = helpers$1.extend({}, values); + } + + // Custom radius resolution + values.radius = resolve$1([ + custom.radius, + data.r, + me._config.radius, + chart.options.elements.point.radius + ], context, index); + + return values; + } +}); + +var valueOrDefault$5 = helpers$1.valueOrDefault; + +var PI$1 = Math.PI; +var DOUBLE_PI$1 = PI$1 * 2; +var HALF_PI$1 = PI$1 / 2; + +core_defaults._set('doughnut', { + animation: { + // Boolean - Whether we animate the rotation of the Doughnut + animateRotate: true, + // Boolean - Whether we animate scaling the Doughnut from the centre + animateScale: false + }, + hover: { + mode: 'single' + }, + legendCallback: function(chart) { + var list = document.createElement('ul'); + var data = chart.data; + var datasets = data.datasets; + var labels = data.labels; + var i, ilen, listItem, listItemSpan; + + list.setAttribute('class', chart.id + '-legend'); + if (datasets.length) { + for (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) { + listItem = list.appendChild(document.createElement('li')); + listItemSpan = listItem.appendChild(document.createElement('span')); + listItemSpan.style.backgroundColor = datasets[0].backgroundColor[i]; + if (labels[i]) { + listItem.appendChild(document.createTextNode(labels[i])); + } + } + } + + return list.outerHTML; + }, + legend: { + labels: { + generateLabels: function(chart) { + var data = chart.data; + if (data.labels.length && data.datasets.length) { + return data.labels.map(function(label, i) { + var meta = chart.getDatasetMeta(0); + var style = meta.controller.getStyle(i); + + return { + text: label, + fillStyle: style.backgroundColor, + strokeStyle: style.borderColor, + lineWidth: style.borderWidth, + hidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden, + + // Extra data used for toggling the correct item + index: i + }; + }); + } + return []; + } + }, + + onClick: function(e, legendItem) { + var index = legendItem.index; + var chart = this.chart; + var i, ilen, meta; + + for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { + meta = chart.getDatasetMeta(i); + // toggle visibility of index if exists + if (meta.data[index]) { + meta.data[index].hidden = !meta.data[index].hidden; + } + } + + chart.update(); + } + }, + + // The percentage of the chart that we cut out of the middle. + cutoutPercentage: 50, + + // The rotation of the chart, where the first data arc begins. + rotation: -HALF_PI$1, + + // The total circumference of the chart. + circumference: DOUBLE_PI$1, + + // Need to override these to give a nice default + tooltips: { + callbacks: { + title: function() { + return ''; + }, + label: function(tooltipItem, data) { + var dataLabel = data.labels[tooltipItem.index]; + var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; + + if (helpers$1.isArray(dataLabel)) { + // show value on first line of multiline label + // need to clone because we are changing the value + dataLabel = dataLabel.slice(); + dataLabel[0] += value; + } else { + dataLabel += value; + } + + return dataLabel; + } + } + } +}); + +var controller_doughnut = core_datasetController.extend({ + + dataElementType: elements.Arc, + + linkScales: helpers$1.noop, + + /** + * @private + */ + _dataElementOptions: [ + 'backgroundColor', + 'borderColor', + 'borderWidth', + 'borderAlign', + 'hoverBackgroundColor', + 'hoverBorderColor', + 'hoverBorderWidth', + ], + + // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly + getRingIndex: function(datasetIndex) { + var ringIndex = 0; + + for (var j = 0; j < datasetIndex; ++j) { + if (this.chart.isDatasetVisible(j)) { + ++ringIndex; + } + } + + return ringIndex; + }, + + update: function(reset) { + var me = this; + var chart = me.chart; + var chartArea = chart.chartArea; + var opts = chart.options; + var ratioX = 1; + var ratioY = 1; + var offsetX = 0; + var offsetY = 0; + var meta = me.getMeta(); + var arcs = meta.data; + var cutout = opts.cutoutPercentage / 100 || 0; + var circumference = opts.circumference; + var chartWeight = me._getRingWeight(me.index); + var maxWidth, maxHeight, i, ilen; + + // If the chart's circumference isn't a full circle, calculate size as a ratio of the width/height of the arc + if (circumference < DOUBLE_PI$1) { + var startAngle = opts.rotation % DOUBLE_PI$1; + startAngle += startAngle >= PI$1 ? -DOUBLE_PI$1 : startAngle < -PI$1 ? DOUBLE_PI$1 : 0; + var endAngle = startAngle + circumference; + var startX = Math.cos(startAngle); + var startY = Math.sin(startAngle); + var endX = Math.cos(endAngle); + var endY = Math.sin(endAngle); + var contains0 = (startAngle <= 0 && endAngle >= 0) || endAngle >= DOUBLE_PI$1; + var contains90 = (startAngle <= HALF_PI$1 && endAngle >= HALF_PI$1) || endAngle >= DOUBLE_PI$1 + HALF_PI$1; + var contains180 = startAngle === -PI$1 || endAngle >= PI$1; + var contains270 = (startAngle <= -HALF_PI$1 && endAngle >= -HALF_PI$1) || endAngle >= PI$1 + HALF_PI$1; + var minX = contains180 ? -1 : Math.min(startX, startX * cutout, endX, endX * cutout); + var minY = contains270 ? -1 : Math.min(startY, startY * cutout, endY, endY * cutout); + var maxX = contains0 ? 1 : Math.max(startX, startX * cutout, endX, endX * cutout); + var maxY = contains90 ? 1 : Math.max(startY, startY * cutout, endY, endY * cutout); + ratioX = (maxX - minX) / 2; + ratioY = (maxY - minY) / 2; + offsetX = -(maxX + minX) / 2; + offsetY = -(maxY + minY) / 2; + } + + for (i = 0, ilen = arcs.length; i < ilen; ++i) { + arcs[i]._options = me._resolveDataElementOptions(arcs[i], i); + } + + chart.borderWidth = me.getMaxBorderWidth(); + maxWidth = (chartArea.right - chartArea.left - chart.borderWidth) / ratioX; + maxHeight = (chartArea.bottom - chartArea.top - chart.borderWidth) / ratioY; + chart.outerRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0); + chart.innerRadius = Math.max(chart.outerRadius * cutout, 0); + chart.radiusLength = (chart.outerRadius - chart.innerRadius) / (me._getVisibleDatasetWeightTotal() || 1); + chart.offsetX = offsetX * chart.outerRadius; + chart.offsetY = offsetY * chart.outerRadius; + + meta.total = me.calculateTotal(); + + me.outerRadius = chart.outerRadius - chart.radiusLength * me._getRingWeightOffset(me.index); + me.innerRadius = Math.max(me.outerRadius - chart.radiusLength * chartWeight, 0); + + for (i = 0, ilen = arcs.length; i < ilen; ++i) { + me.updateElement(arcs[i], i, reset); + } + }, + + updateElement: function(arc, index, reset) { + var me = this; + var chart = me.chart; + var chartArea = chart.chartArea; + var opts = chart.options; + var animationOpts = opts.animation; + var centerX = (chartArea.left + chartArea.right) / 2; + var centerY = (chartArea.top + chartArea.bottom) / 2; + var startAngle = opts.rotation; // non reset case handled later + var endAngle = opts.rotation; // non reset case handled later + var dataset = me.getDataset(); + var circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / DOUBLE_PI$1); + var innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius; + var outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius; + var options = arc._options || {}; + + helpers$1.extend(arc, { + // Utility + _datasetIndex: me.index, + _index: index, + + // Desired view properties + _model: { + backgroundColor: options.backgroundColor, + borderColor: options.borderColor, + borderWidth: options.borderWidth, + borderAlign: options.borderAlign, + x: centerX + chart.offsetX, + y: centerY + chart.offsetY, + startAngle: startAngle, + endAngle: endAngle, + circumference: circumference, + outerRadius: outerRadius, + innerRadius: innerRadius, + label: helpers$1.valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index]) + } + }); + + var model = arc._model; + + // Set correct angles if not resetting + if (!reset || !animationOpts.animateRotate) { + if (index === 0) { + model.startAngle = opts.rotation; + } else { + model.startAngle = me.getMeta().data[index - 1]._model.endAngle; + } + + model.endAngle = model.startAngle + model.circumference; + } + + arc.pivot(); + }, + + calculateTotal: function() { + var dataset = this.getDataset(); + var meta = this.getMeta(); + var total = 0; + var value; + + helpers$1.each(meta.data, function(element, index) { + value = dataset.data[index]; + if (!isNaN(value) && !element.hidden) { + total += Math.abs(value); + } + }); + + /* if (total === 0) { + total = NaN; + }*/ + + return total; + }, + + calculateCircumference: function(value) { + var total = this.getMeta().total; + if (total > 0 && !isNaN(value)) { + return DOUBLE_PI$1 * (Math.abs(value) / total); + } + return 0; + }, + + // gets the max border or hover width to properly scale pie charts + getMaxBorderWidth: function(arcs) { + var me = this; + var max = 0; + var chart = me.chart; + var i, ilen, meta, arc, controller, options, borderWidth, hoverWidth; + + if (!arcs) { + // Find the outmost visible dataset + for (i = 0, ilen = chart.data.datasets.length; i < ilen; ++i) { + if (chart.isDatasetVisible(i)) { + meta = chart.getDatasetMeta(i); + arcs = meta.data; + if (i !== me.index) { + controller = meta.controller; + } + break; + } + } + } + + if (!arcs) { + return 0; + } + + for (i = 0, ilen = arcs.length; i < ilen; ++i) { + arc = arcs[i]; + if (controller) { + controller._configure(); + options = controller._resolveDataElementOptions(arc, i); + } else { + options = arc._options; + } + if (options.borderAlign !== 'inner') { + borderWidth = options.borderWidth; + hoverWidth = options.hoverBorderWidth; + + max = borderWidth > max ? borderWidth : max; + max = hoverWidth > max ? hoverWidth : max; + } + } + return max; + }, + + /** + * @protected + */ + setHoverStyle: function(arc) { + var model = arc._model; + var options = arc._options; + var getHoverColor = helpers$1.getHoverColor; + + arc.$previousStyle = { + backgroundColor: model.backgroundColor, + borderColor: model.borderColor, + borderWidth: model.borderWidth, + }; + + model.backgroundColor = valueOrDefault$5(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); + model.borderColor = valueOrDefault$5(options.hoverBorderColor, getHoverColor(options.borderColor)); + model.borderWidth = valueOrDefault$5(options.hoverBorderWidth, options.borderWidth); + }, + + /** + * Get radius length offset of the dataset in relation to the visible datasets weights. This allows determining the inner and outer radius correctly + * @private + */ + _getRingWeightOffset: function(datasetIndex) { + var ringWeightOffset = 0; + + for (var i = 0; i < datasetIndex; ++i) { + if (this.chart.isDatasetVisible(i)) { + ringWeightOffset += this._getRingWeight(i); + } + } + + return ringWeightOffset; + }, + + /** + * @private + */ + _getRingWeight: function(dataSetIndex) { + return Math.max(valueOrDefault$5(this.chart.data.datasets[dataSetIndex].weight, 1), 0); + }, + + /** + * Returns the sum of all visibile data set weights. This value can be 0. + * @private + */ + _getVisibleDatasetWeightTotal: function() { + return this._getRingWeightOffset(this.chart.data.datasets.length); + } +}); + +core_defaults._set('horizontalBar', { + hover: { + mode: 'index', + axis: 'y' + }, + + scales: { + xAxes: [{ + type: 'linear', + position: 'bottom' + }], + + yAxes: [{ + type: 'category', + position: 'left', + offset: true, + gridLines: { + offsetGridLines: true + } + }] + }, + + elements: { + rectangle: { + borderSkipped: 'left' + } + }, + + tooltips: { + mode: 'index', + axis: 'y' + } +}); + +core_defaults._set('global', { + datasets: { + horizontalBar: { + categoryPercentage: 0.8, + barPercentage: 0.9 + } + } +}); + +var controller_horizontalBar = controller_bar.extend({ + /** + * @private + */ + _getValueScaleId: function() { + return this.getMeta().xAxisID; + }, + + /** + * @private + */ + _getIndexScaleId: function() { + return this.getMeta().yAxisID; + } +}); + +var valueOrDefault$6 = helpers$1.valueOrDefault; +var resolve$2 = helpers$1.options.resolve; +var isPointInArea = helpers$1.canvas._isPointInArea; + +core_defaults._set('line', { + showLines: true, + spanGaps: false, + + hover: { + mode: 'label' + }, + + scales: { + xAxes: [{ + type: 'category', + id: 'x-axis-0' + }], + yAxes: [{ + type: 'linear', + id: 'y-axis-0' + }] + } +}); + +function scaleClip(scale, halfBorderWidth) { + var tickOpts = scale && scale.options.ticks || {}; + var reverse = tickOpts.reverse; + var min = tickOpts.min === undefined ? halfBorderWidth : 0; + var max = tickOpts.max === undefined ? halfBorderWidth : 0; + return { + start: reverse ? max : min, + end: reverse ? min : max + }; +} + +function defaultClip(xScale, yScale, borderWidth) { + var halfBorderWidth = borderWidth / 2; + var x = scaleClip(xScale, halfBorderWidth); + var y = scaleClip(yScale, halfBorderWidth); + + return { + top: y.end, + right: x.end, + bottom: y.start, + left: x.start + }; +} + +function toClip(value) { + var t, r, b, l; + + if (helpers$1.isObject(value)) { + t = value.top; + r = value.right; + b = value.bottom; + l = value.left; + } else { + t = r = b = l = value; + } + + return { + top: t, + right: r, + bottom: b, + left: l + }; +} + + +var controller_line = core_datasetController.extend({ + + datasetElementType: elements.Line, + + dataElementType: elements.Point, + + /** + * @private + */ + _datasetElementOptions: [ + 'backgroundColor', + 'borderCapStyle', + 'borderColor', + 'borderDash', + 'borderDashOffset', + 'borderJoinStyle', + 'borderWidth', + 'cubicInterpolationMode', + 'fill' + ], + + /** + * @private + */ + _dataElementOptions: { + backgroundColor: 'pointBackgroundColor', + borderColor: 'pointBorderColor', + borderWidth: 'pointBorderWidth', + hitRadius: 'pointHitRadius', + hoverBackgroundColor: 'pointHoverBackgroundColor', + hoverBorderColor: 'pointHoverBorderColor', + hoverBorderWidth: 'pointHoverBorderWidth', + hoverRadius: 'pointHoverRadius', + pointStyle: 'pointStyle', + radius: 'pointRadius', + rotation: 'pointRotation' + }, + + update: function(reset) { + var me = this; + var meta = me.getMeta(); + var line = meta.dataset; + var points = meta.data || []; + var options = me.chart.options; + var config = me._config; + var showLine = me._showLine = valueOrDefault$6(config.showLine, options.showLines); + var i, ilen; + + me._xScale = me.getScaleForId(meta.xAxisID); + me._yScale = me.getScaleForId(meta.yAxisID); + + // Update Line + if (showLine) { + // Compatibility: If the properties are defined with only the old name, use those values + if (config.tension !== undefined && config.lineTension === undefined) { + config.lineTension = config.tension; + } + + // Utility + line._scale = me._yScale; + line._datasetIndex = me.index; + // Data + line._children = points; + // Model + line._model = me._resolveDatasetElementOptions(line); + + line.pivot(); + } + + // Update Points + for (i = 0, ilen = points.length; i < ilen; ++i) { + me.updateElement(points[i], i, reset); + } + + if (showLine && line._model.tension !== 0) { + me.updateBezierControlPoints(); + } + + // Now pivot the point for animation + for (i = 0, ilen = points.length; i < ilen; ++i) { + points[i].pivot(); + } + }, + + updateElement: function(point, index, reset) { + var me = this; + var meta = me.getMeta(); + var custom = point.custom || {}; + var dataset = me.getDataset(); + var datasetIndex = me.index; + var value = dataset.data[index]; + var xScale = me._xScale; + var yScale = me._yScale; + var lineModel = meta.dataset._model; + var x, y; + + var options = me._resolveDataElementOptions(point, index); + + x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex); + y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex); + + // Utility + point._xScale = xScale; + point._yScale = yScale; + point._options = options; + point._datasetIndex = datasetIndex; + point._index = index; + + // Desired view properties + point._model = { + x: x, + y: y, + skip: custom.skip || isNaN(x) || isNaN(y), + // Appearance + radius: options.radius, + pointStyle: options.pointStyle, + rotation: options.rotation, + backgroundColor: options.backgroundColor, + borderColor: options.borderColor, + borderWidth: options.borderWidth, + tension: valueOrDefault$6(custom.tension, lineModel ? lineModel.tension : 0), + steppedLine: lineModel ? lineModel.steppedLine : false, + // Tooltip + hitRadius: options.hitRadius + }; + }, + + /** + * @private + */ + _resolveDatasetElementOptions: function(element) { + var me = this; + var config = me._config; + var custom = element.custom || {}; + var options = me.chart.options; + var lineOptions = options.elements.line; + var values = core_datasetController.prototype._resolveDatasetElementOptions.apply(me, arguments); + + // The default behavior of lines is to break at null values, according + // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158 + // This option gives lines the ability to span gaps + values.spanGaps = valueOrDefault$6(config.spanGaps, options.spanGaps); + values.tension = valueOrDefault$6(config.lineTension, lineOptions.tension); + values.steppedLine = resolve$2([custom.steppedLine, config.steppedLine, lineOptions.stepped]); + values.clip = toClip(valueOrDefault$6(config.clip, defaultClip(me._xScale, me._yScale, values.borderWidth))); + + return values; + }, + + calculatePointY: function(value, index, datasetIndex) { + var me = this; + var chart = me.chart; + var yScale = me._yScale; + var sumPos = 0; + var sumNeg = 0; + var i, ds, dsMeta, stackedRightValue, rightValue, metasets, ilen; + + if (yScale.options.stacked) { + rightValue = +yScale.getRightValue(value); + metasets = chart._getSortedVisibleDatasetMetas(); + ilen = metasets.length; + + for (i = 0; i < ilen; ++i) { + dsMeta = metasets[i]; + if (dsMeta.index === datasetIndex) { + break; + } + + ds = chart.data.datasets[dsMeta.index]; + if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id) { + stackedRightValue = +yScale.getRightValue(ds.data[index]); + if (stackedRightValue < 0) { + sumNeg += stackedRightValue || 0; + } else { + sumPos += stackedRightValue || 0; + } + } + } + + if (rightValue < 0) { + return yScale.getPixelForValue(sumNeg + rightValue); + } + return yScale.getPixelForValue(sumPos + rightValue); + } + return yScale.getPixelForValue(value); + }, + + updateBezierControlPoints: function() { + var me = this; + var chart = me.chart; + var meta = me.getMeta(); + var lineModel = meta.dataset._model; + var area = chart.chartArea; + var points = meta.data || []; + var i, ilen, model, controlPoints; + + // Only consider points that are drawn in case the spanGaps option is used + if (lineModel.spanGaps) { + points = points.filter(function(pt) { + return !pt._model.skip; + }); + } + + function capControlPoint(pt, min, max) { + return Math.max(Math.min(pt, max), min); + } + + if (lineModel.cubicInterpolationMode === 'monotone') { + helpers$1.splineCurveMonotone(points); + } else { + for (i = 0, ilen = points.length; i < ilen; ++i) { + model = points[i]._model; + controlPoints = helpers$1.splineCurve( + helpers$1.previousItem(points, i)._model, + model, + helpers$1.nextItem(points, i)._model, + lineModel.tension + ); + model.controlPointPreviousX = controlPoints.previous.x; + model.controlPointPreviousY = controlPoints.previous.y; + model.controlPointNextX = controlPoints.next.x; + model.controlPointNextY = controlPoints.next.y; + } + } + + if (chart.options.elements.line.capBezierPoints) { + for (i = 0, ilen = points.length; i < ilen; ++i) { + model = points[i]._model; + if (isPointInArea(model, area)) { + if (i > 0 && isPointInArea(points[i - 1]._model, area)) { + model.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right); + model.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom); + } + if (i < points.length - 1 && isPointInArea(points[i + 1]._model, area)) { + model.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right); + model.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom); + } + } + } + } + }, + + draw: function() { + var me = this; + var chart = me.chart; + var meta = me.getMeta(); + var points = meta.data || []; + var area = chart.chartArea; + var canvas = chart.canvas; + var i = 0; + var ilen = points.length; + var clip; + + if (me._showLine) { + clip = meta.dataset._model.clip; + + helpers$1.canvas.clipArea(chart.ctx, { + left: clip.left === false ? 0 : area.left - clip.left, + right: clip.right === false ? canvas.width : area.right + clip.right, + top: clip.top === false ? 0 : area.top - clip.top, + bottom: clip.bottom === false ? canvas.height : area.bottom + clip.bottom + }); + + meta.dataset.draw(); + + helpers$1.canvas.unclipArea(chart.ctx); + } + + // Draw the points + for (; i < ilen; ++i) { + points[i].draw(area); + } + }, + + /** + * @protected + */ + setHoverStyle: function(point) { + var model = point._model; + var options = point._options; + var getHoverColor = helpers$1.getHoverColor; + + point.$previousStyle = { + backgroundColor: model.backgroundColor, + borderColor: model.borderColor, + borderWidth: model.borderWidth, + radius: model.radius + }; + + model.backgroundColor = valueOrDefault$6(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); + model.borderColor = valueOrDefault$6(options.hoverBorderColor, getHoverColor(options.borderColor)); + model.borderWidth = valueOrDefault$6(options.hoverBorderWidth, options.borderWidth); + model.radius = valueOrDefault$6(options.hoverRadius, options.radius); + }, +}); + +var resolve$3 = helpers$1.options.resolve; + +core_defaults._set('polarArea', { + scale: { + type: 'radialLinear', + angleLines: { + display: false + }, + gridLines: { + circular: true + }, + pointLabels: { + display: false + }, + ticks: { + beginAtZero: true + } + }, + + // Boolean - Whether to animate the rotation of the chart + animation: { + animateRotate: true, + animateScale: true + }, + + startAngle: -0.5 * Math.PI, + legendCallback: function(chart) { + var list = document.createElement('ul'); + var data = chart.data; + var datasets = data.datasets; + var labels = data.labels; + var i, ilen, listItem, listItemSpan; + + list.setAttribute('class', chart.id + '-legend'); + if (datasets.length) { + for (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) { + listItem = list.appendChild(document.createElement('li')); + listItemSpan = listItem.appendChild(document.createElement('span')); + listItemSpan.style.backgroundColor = datasets[0].backgroundColor[i]; + if (labels[i]) { + listItem.appendChild(document.createTextNode(labels[i])); + } + } + } + + return list.outerHTML; + }, + legend: { + labels: { + generateLabels: function(chart) { + var data = chart.data; + if (data.labels.length && data.datasets.length) { + return data.labels.map(function(label, i) { + var meta = chart.getDatasetMeta(0); + var style = meta.controller.getStyle(i); + + return { + text: label, + fillStyle: style.backgroundColor, + strokeStyle: style.borderColor, + lineWidth: style.borderWidth, + hidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden, + + // Extra data used for toggling the correct item + index: i + }; + }); + } + return []; + } + }, + + onClick: function(e, legendItem) { + var index = legendItem.index; + var chart = this.chart; + var i, ilen, meta; + + for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { + meta = chart.getDatasetMeta(i); + meta.data[index].hidden = !meta.data[index].hidden; + } + + chart.update(); + } + }, + + // Need to override these to give a nice default + tooltips: { + callbacks: { + title: function() { + return ''; + }, + label: function(item, data) { + return data.labels[item.index] + ': ' + item.yLabel; + } + } + } +}); + +var controller_polarArea = core_datasetController.extend({ + + dataElementType: elements.Arc, + + linkScales: helpers$1.noop, + + /** + * @private + */ + _dataElementOptions: [ + 'backgroundColor', + 'borderColor', + 'borderWidth', + 'borderAlign', + 'hoverBackgroundColor', + 'hoverBorderColor', + 'hoverBorderWidth', + ], + + /** + * @private + */ + _getIndexScaleId: function() { + return this.chart.scale.id; + }, + + /** + * @private + */ + _getValueScaleId: function() { + return this.chart.scale.id; + }, + + update: function(reset) { + var me = this; + var dataset = me.getDataset(); + var meta = me.getMeta(); + var start = me.chart.options.startAngle || 0; + var starts = me._starts = []; + var angles = me._angles = []; + var arcs = meta.data; + var i, ilen, angle; + + me._updateRadius(); + + meta.count = me.countVisibleElements(); + + for (i = 0, ilen = dataset.data.length; i < ilen; i++) { + starts[i] = start; + angle = me._computeAngle(i); + angles[i] = angle; + start += angle; + } + + for (i = 0, ilen = arcs.length; i < ilen; ++i) { + arcs[i]._options = me._resolveDataElementOptions(arcs[i], i); + me.updateElement(arcs[i], i, reset); + } + }, + + /** + * @private + */ + _updateRadius: function() { + var me = this; + var chart = me.chart; + var chartArea = chart.chartArea; + var opts = chart.options; + var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top); + + chart.outerRadius = Math.max(minSize / 2, 0); + chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0); + chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount(); + + me.outerRadius = chart.outerRadius - (chart.radiusLength * me.index); + me.innerRadius = me.outerRadius - chart.radiusLength; + }, + + updateElement: function(arc, index, reset) { + var me = this; + var chart = me.chart; + var dataset = me.getDataset(); + var opts = chart.options; + var animationOpts = opts.animation; + var scale = chart.scale; + var labels = chart.data.labels; + + var centerX = scale.xCenter; + var centerY = scale.yCenter; + + // var negHalfPI = -0.5 * Math.PI; + var datasetStartAngle = opts.startAngle; + var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); + var startAngle = me._starts[index]; + var endAngle = startAngle + (arc.hidden ? 0 : me._angles[index]); + + var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); + var options = arc._options || {}; + + helpers$1.extend(arc, { + // Utility + _datasetIndex: me.index, + _index: index, + _scale: scale, + + // Desired view properties + _model: { + backgroundColor: options.backgroundColor, + borderColor: options.borderColor, + borderWidth: options.borderWidth, + borderAlign: options.borderAlign, + x: centerX, + y: centerY, + innerRadius: 0, + outerRadius: reset ? resetRadius : distance, + startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle, + endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle, + label: helpers$1.valueAtIndexOrDefault(labels, index, labels[index]) + } + }); + + arc.pivot(); + }, + + countVisibleElements: function() { + var dataset = this.getDataset(); + var meta = this.getMeta(); + var count = 0; + + helpers$1.each(meta.data, function(element, index) { + if (!isNaN(dataset.data[index]) && !element.hidden) { + count++; + } + }); + + return count; + }, + + /** + * @protected + */ + setHoverStyle: function(arc) { + var model = arc._model; + var options = arc._options; + var getHoverColor = helpers$1.getHoverColor; + var valueOrDefault = helpers$1.valueOrDefault; + + arc.$previousStyle = { + backgroundColor: model.backgroundColor, + borderColor: model.borderColor, + borderWidth: model.borderWidth, + }; + + model.backgroundColor = valueOrDefault(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); + model.borderColor = valueOrDefault(options.hoverBorderColor, getHoverColor(options.borderColor)); + model.borderWidth = valueOrDefault(options.hoverBorderWidth, options.borderWidth); + }, + + /** + * @private + */ + _computeAngle: function(index) { + var me = this; + var count = this.getMeta().count; + var dataset = me.getDataset(); + var meta = me.getMeta(); + + if (isNaN(dataset.data[index]) || meta.data[index].hidden) { + return 0; + } + + // Scriptable options + var context = { + chart: me.chart, + dataIndex: index, + dataset: dataset, + datasetIndex: me.index + }; + + return resolve$3([ + me.chart.options.elements.arc.angle, + (2 * Math.PI) / count + ], context, index); + } +}); + +core_defaults._set('pie', helpers$1.clone(core_defaults.doughnut)); +core_defaults._set('pie', { + cutoutPercentage: 0 +}); + +// Pie charts are Doughnut chart with different defaults +var controller_pie = controller_doughnut; + +var valueOrDefault$7 = helpers$1.valueOrDefault; + +core_defaults._set('radar', { + spanGaps: false, + scale: { + type: 'radialLinear' + }, + elements: { + line: { + fill: 'start', + tension: 0 // no bezier in radar + } + } +}); + +var controller_radar = core_datasetController.extend({ + datasetElementType: elements.Line, + + dataElementType: elements.Point, + + linkScales: helpers$1.noop, + + /** + * @private + */ + _datasetElementOptions: [ + 'backgroundColor', + 'borderWidth', + 'borderColor', + 'borderCapStyle', + 'borderDash', + 'borderDashOffset', + 'borderJoinStyle', + 'fill' + ], + + /** + * @private + */ + _dataElementOptions: { + backgroundColor: 'pointBackgroundColor', + borderColor: 'pointBorderColor', + borderWidth: 'pointBorderWidth', + hitRadius: 'pointHitRadius', + hoverBackgroundColor: 'pointHoverBackgroundColor', + hoverBorderColor: 'pointHoverBorderColor', + hoverBorderWidth: 'pointHoverBorderWidth', + hoverRadius: 'pointHoverRadius', + pointStyle: 'pointStyle', + radius: 'pointRadius', + rotation: 'pointRotation' + }, + + /** + * @private + */ + _getIndexScaleId: function() { + return this.chart.scale.id; + }, + + /** + * @private + */ + _getValueScaleId: function() { + return this.chart.scale.id; + }, + + update: function(reset) { + var me = this; + var meta = me.getMeta(); + var line = meta.dataset; + var points = meta.data || []; + var scale = me.chart.scale; + var config = me._config; + var i, ilen; + + // Compatibility: If the properties are defined with only the old name, use those values + if (config.tension !== undefined && config.lineTension === undefined) { + config.lineTension = config.tension; + } + + // Utility + line._scale = scale; + line._datasetIndex = me.index; + // Data + line._children = points; + line._loop = true; + // Model + line._model = me._resolveDatasetElementOptions(line); + + line.pivot(); + + // Update Points + for (i = 0, ilen = points.length; i < ilen; ++i) { + me.updateElement(points[i], i, reset); + } + + // Update bezier control points + me.updateBezierControlPoints(); + + // Now pivot the point for animation + for (i = 0, ilen = points.length; i < ilen; ++i) { + points[i].pivot(); + } + }, + + updateElement: function(point, index, reset) { + var me = this; + var custom = point.custom || {}; + var dataset = me.getDataset(); + var scale = me.chart.scale; + var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]); + var options = me._resolveDataElementOptions(point, index); + var lineModel = me.getMeta().dataset._model; + var x = reset ? scale.xCenter : pointPosition.x; + var y = reset ? scale.yCenter : pointPosition.y; + + // Utility + point._scale = scale; + point._options = options; + point._datasetIndex = me.index; + point._index = index; + + // Desired view properties + point._model = { + x: x, // value not used in dataset scale, but we want a consistent API between scales + y: y, + skip: custom.skip || isNaN(x) || isNaN(y), + // Appearance + radius: options.radius, + pointStyle: options.pointStyle, + rotation: options.rotation, + backgroundColor: options.backgroundColor, + borderColor: options.borderColor, + borderWidth: options.borderWidth, + tension: valueOrDefault$7(custom.tension, lineModel ? lineModel.tension : 0), + + // Tooltip + hitRadius: options.hitRadius + }; + }, + + /** + * @private + */ + _resolveDatasetElementOptions: function() { + var me = this; + var config = me._config; + var options = me.chart.options; + var values = core_datasetController.prototype._resolveDatasetElementOptions.apply(me, arguments); + + values.spanGaps = valueOrDefault$7(config.spanGaps, options.spanGaps); + values.tension = valueOrDefault$7(config.lineTension, options.elements.line.tension); + + return values; + }, + + updateBezierControlPoints: function() { + var me = this; + var meta = me.getMeta(); + var area = me.chart.chartArea; + var points = meta.data || []; + var i, ilen, model, controlPoints; + + // Only consider points that are drawn in case the spanGaps option is used + if (meta.dataset._model.spanGaps) { + points = points.filter(function(pt) { + return !pt._model.skip; + }); + } + + function capControlPoint(pt, min, max) { + return Math.max(Math.min(pt, max), min); + } + + for (i = 0, ilen = points.length; i < ilen; ++i) { + model = points[i]._model; + controlPoints = helpers$1.splineCurve( + helpers$1.previousItem(points, i, true)._model, + model, + helpers$1.nextItem(points, i, true)._model, + model.tension + ); + + // Prevent the bezier going outside of the bounds of the graph + model.controlPointPreviousX = capControlPoint(controlPoints.previous.x, area.left, area.right); + model.controlPointPreviousY = capControlPoint(controlPoints.previous.y, area.top, area.bottom); + model.controlPointNextX = capControlPoint(controlPoints.next.x, area.left, area.right); + model.controlPointNextY = capControlPoint(controlPoints.next.y, area.top, area.bottom); + } + }, + + setHoverStyle: function(point) { + var model = point._model; + var options = point._options; + var getHoverColor = helpers$1.getHoverColor; + + point.$previousStyle = { + backgroundColor: model.backgroundColor, + borderColor: model.borderColor, + borderWidth: model.borderWidth, + radius: model.radius + }; + + model.backgroundColor = valueOrDefault$7(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); + model.borderColor = valueOrDefault$7(options.hoverBorderColor, getHoverColor(options.borderColor)); + model.borderWidth = valueOrDefault$7(options.hoverBorderWidth, options.borderWidth); + model.radius = valueOrDefault$7(options.hoverRadius, options.radius); + } +}); + +core_defaults._set('scatter', { + hover: { + mode: 'single' + }, + + scales: { + xAxes: [{ + id: 'x-axis-1', // need an ID so datasets can reference the scale + type: 'linear', // scatter should not use a category axis + position: 'bottom' + }], + yAxes: [{ + id: 'y-axis-1', + type: 'linear', + position: 'left' + }] + }, + + tooltips: { + callbacks: { + title: function() { + return ''; // doesn't make sense for scatter since data are formatted as a point + }, + label: function(item) { + return '(' + item.xLabel + ', ' + item.yLabel + ')'; + } + } + } +}); + +core_defaults._set('global', { + datasets: { + scatter: { + showLine: false + } + } +}); + +// Scatter charts use line controllers +var controller_scatter = controller_line; + +// NOTE export a map in which the key represents the controller type, not +// the class, and so must be CamelCase in order to be correctly retrieved +// by the controller in core.controller.js (`controllers[meta.type]`). + +var controllers = { + bar: controller_bar, + bubble: controller_bubble, + doughnut: controller_doughnut, + horizontalBar: controller_horizontalBar, + line: controller_line, + polarArea: controller_polarArea, + pie: controller_pie, + radar: controller_radar, + scatter: controller_scatter +}; + +/** + * Helper function to get relative position for an event + * @param {Event|IEvent} event - The event to get the position for + * @param {Chart} chart - The chart + * @returns {object} the event position + */ +function getRelativePosition(e, chart) { + if (e.native) { + return { + x: e.x, + y: e.y + }; + } + + return helpers$1.getRelativePosition(e, chart); +} + +/** + * Helper function to traverse all of the visible elements in the chart + * @param {Chart} chart - the chart + * @param {function} handler - the callback to execute for each visible item + */ +function parseVisibleItems(chart, handler) { + var metasets = chart._getSortedVisibleDatasetMetas(); + var metadata, i, j, ilen, jlen, element; + + for (i = 0, ilen = metasets.length; i < ilen; ++i) { + metadata = metasets[i].data; + for (j = 0, jlen = metadata.length; j < jlen; ++j) { + element = metadata[j]; + if (!element._view.skip) { + handler(element); + } + } + } +} + +/** + * Helper function to get the items that intersect the event position + * @param {ChartElement[]} items - elements to filter + * @param {object} position - the point to be nearest to + * @return {ChartElement[]} the nearest items + */ +function getIntersectItems(chart, position) { + var elements = []; + + parseVisibleItems(chart, function(element) { + if (element.inRange(position.x, position.y)) { + elements.push(element); + } + }); + + return elements; +} + +/** + * Helper function to get the items nearest to the event position considering all visible items in teh chart + * @param {Chart} chart - the chart to look at elements from + * @param {object} position - the point to be nearest to + * @param {boolean} intersect - if true, only consider items that intersect the position + * @param {function} distanceMetric - function to provide the distance between points + * @return {ChartElement[]} the nearest items + */ +function getNearestItems(chart, position, intersect, distanceMetric) { + var minDistance = Number.POSITIVE_INFINITY; + var nearestItems = []; + + parseVisibleItems(chart, function(element) { + if (intersect && !element.inRange(position.x, position.y)) { + return; + } + + var center = element.getCenterPoint(); + var distance = distanceMetric(position, center); + if (distance < minDistance) { + nearestItems = [element]; + minDistance = distance; + } else if (distance === minDistance) { + // Can have multiple items at the same distance in which case we sort by size + nearestItems.push(element); + } + }); + + return nearestItems; +} + +/** + * Get a distance metric function for two points based on the + * axis mode setting + * @param {string} axis - the axis mode. x|y|xy + */ +function getDistanceMetricForAxis(axis) { + var useX = axis.indexOf('x') !== -1; + var useY = axis.indexOf('y') !== -1; + + return function(pt1, pt2) { + var deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0; + var deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0; + return Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)); + }; +} + +function indexMode(chart, e, options) { + var position = getRelativePosition(e, chart); + // Default axis for index mode is 'x' to match old behaviour + options.axis = options.axis || 'x'; + var distanceMetric = getDistanceMetricForAxis(options.axis); + var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); + var elements = []; + + if (!items.length) { + return []; + } + + chart._getSortedVisibleDatasetMetas().forEach(function(meta) { + var element = meta.data[items[0]._index]; + + // don't count items that are skipped (null data) + if (element && !element._view.skip) { + elements.push(element); + } + }); + + return elements; +} + +/** + * @interface IInteractionOptions + */ +/** + * If true, only consider items that intersect the point + * @name IInterfaceOptions#boolean + * @type Boolean + */ + +/** + * Contains interaction related functions + * @namespace Chart.Interaction + */ +var core_interaction = { + // Helper function for different modes + modes: { + single: function(chart, e) { + var position = getRelativePosition(e, chart); + var elements = []; + + parseVisibleItems(chart, function(element) { + if (element.inRange(position.x, position.y)) { + elements.push(element); + return elements; + } + }); + + return elements.slice(0, 1); + }, + + /** + * @function Chart.Interaction.modes.label + * @deprecated since version 2.4.0 + * @todo remove at version 3 + * @private + */ + label: indexMode, + + /** + * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something + * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item + * @function Chart.Interaction.modes.index + * @since v2.4.0 + * @param {Chart} chart - the chart we are returning items from + * @param {Event} e - the event we are find things at + * @param {IInteractionOptions} options - options to use during interaction + * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned + */ + index: indexMode, + + /** + * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something + * If the options.intersect is false, we find the nearest item and return the items in that dataset + * @function Chart.Interaction.modes.dataset + * @param {Chart} chart - the chart we are returning items from + * @param {Event} e - the event we are find things at + * @param {IInteractionOptions} options - options to use during interaction + * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned + */ + dataset: function(chart, e, options) { + var position = getRelativePosition(e, chart); + options.axis = options.axis || 'xy'; + var distanceMetric = getDistanceMetricForAxis(options.axis); + var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric); + + if (items.length > 0) { + items = chart.getDatasetMeta(items[0]._datasetIndex).data; + } + + return items; + }, + + /** + * @function Chart.Interaction.modes.x-axis + * @deprecated since version 2.4.0. Use index mode and intersect == true + * @todo remove at version 3 + * @private + */ + 'x-axis': function(chart, e) { + return indexMode(chart, e, {intersect: false}); + }, + + /** + * Point mode returns all elements that hit test based on the event position + * of the event + * @function Chart.Interaction.modes.intersect + * @param {Chart} chart - the chart we are returning items from + * @param {Event} e - the event we are find things at + * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned + */ + point: function(chart, e) { + var position = getRelativePosition(e, chart); + return getIntersectItems(chart, position); + }, + + /** + * nearest mode returns the element closest to the point + * @function Chart.Interaction.modes.intersect + * @param {Chart} chart - the chart we are returning items from + * @param {Event} e - the event we are find things at + * @param {IInteractionOptions} options - options to use + * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned + */ + nearest: function(chart, e, options) { + var position = getRelativePosition(e, chart); + options.axis = options.axis || 'xy'; + var distanceMetric = getDistanceMetricForAxis(options.axis); + return getNearestItems(chart, position, options.intersect, distanceMetric); + }, + + /** + * x mode returns the elements that hit-test at the current x coordinate + * @function Chart.Interaction.modes.x + * @param {Chart} chart - the chart we are returning items from + * @param {Event} e - the event we are find things at + * @param {IInteractionOptions} options - options to use + * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned + */ + x: function(chart, e, options) { + var position = getRelativePosition(e, chart); + var items = []; + var intersectsItem = false; + + parseVisibleItems(chart, function(element) { + if (element.inXRange(position.x)) { + items.push(element); + } + + if (element.inRange(position.x, position.y)) { + intersectsItem = true; + } + }); + + // If we want to trigger on an intersect and we don't have any items + // that intersect the position, return nothing + if (options.intersect && !intersectsItem) { + items = []; + } + return items; + }, + + /** + * y mode returns the elements that hit-test at the current y coordinate + * @function Chart.Interaction.modes.y + * @param {Chart} chart - the chart we are returning items from + * @param {Event} e - the event we are find things at + * @param {IInteractionOptions} options - options to use + * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned + */ + y: function(chart, e, options) { + var position = getRelativePosition(e, chart); + var items = []; + var intersectsItem = false; + + parseVisibleItems(chart, function(element) { + if (element.inYRange(position.y)) { + items.push(element); + } + + if (element.inRange(position.x, position.y)) { + intersectsItem = true; + } + }); + + // If we want to trigger on an intersect and we don't have any items + // that intersect the position, return nothing + if (options.intersect && !intersectsItem) { + items = []; + } + return items; + } + } +}; + +var extend = helpers$1.extend; + +function filterByPosition(array, position) { + return helpers$1.where(array, function(v) { + return v.pos === position; + }); +} + +function sortByWeight(array, reverse) { + return array.sort(function(a, b) { + var v0 = reverse ? b : a; + var v1 = reverse ? a : b; + return v0.weight === v1.weight ? + v0.index - v1.index : + v0.weight - v1.weight; + }); +} + +function wrapBoxes(boxes) { + var layoutBoxes = []; + var i, ilen, box; + + for (i = 0, ilen = (boxes || []).length; i < ilen; ++i) { + box = boxes[i]; + layoutBoxes.push({ + index: i, + box: box, + pos: box.position, + horizontal: box.isHorizontal(), + weight: box.weight + }); + } + return layoutBoxes; +} + +function setLayoutDims(layouts, params) { + var i, ilen, layout; + for (i = 0, ilen = layouts.length; i < ilen; ++i) { + layout = layouts[i]; + // store width used instead of chartArea.w in fitBoxes + layout.width = layout.horizontal + ? layout.box.fullWidth && params.availableWidth + : params.vBoxMaxWidth; + // store height used instead of chartArea.h in fitBoxes + layout.height = layout.horizontal && params.hBoxMaxHeight; + } +} + +function buildLayoutBoxes(boxes) { + var layoutBoxes = wrapBoxes(boxes); + var left = sortByWeight(filterByPosition(layoutBoxes, 'left'), true); + var right = sortByWeight(filterByPosition(layoutBoxes, 'right')); + var top = sortByWeight(filterByPosition(layoutBoxes, 'top'), true); + var bottom = sortByWeight(filterByPosition(layoutBoxes, 'bottom')); + + return { + leftAndTop: left.concat(top), + rightAndBottom: right.concat(bottom), + chartArea: filterByPosition(layoutBoxes, 'chartArea'), + vertical: left.concat(right), + horizontal: top.concat(bottom) + }; +} + +function getCombinedMax(maxPadding, chartArea, a, b) { + return Math.max(maxPadding[a], chartArea[a]) + Math.max(maxPadding[b], chartArea[b]); +} + +function updateDims(chartArea, params, layout) { + var box = layout.box; + var maxPadding = chartArea.maxPadding; + var newWidth, newHeight; + + if (layout.size) { + // this layout was already counted for, lets first reduce old size + chartArea[layout.pos] -= layout.size; + } + layout.size = layout.horizontal ? box.height : box.width; + chartArea[layout.pos] += layout.size; + + if (box.getPadding) { + var boxPadding = box.getPadding(); + maxPadding.top = Math.max(maxPadding.top, boxPadding.top); + maxPadding.left = Math.max(maxPadding.left, boxPadding.left); + maxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom); + maxPadding.right = Math.max(maxPadding.right, boxPadding.right); + } + + newWidth = params.outerWidth - getCombinedMax(maxPadding, chartArea, 'left', 'right'); + newHeight = params.outerHeight - getCombinedMax(maxPadding, chartArea, 'top', 'bottom'); + + if (newWidth !== chartArea.w || newHeight !== chartArea.h) { + chartArea.w = newWidth; + chartArea.h = newHeight; + + // return true if chart area changed in layout's direction + return layout.horizontal ? newWidth !== chartArea.w : newHeight !== chartArea.h; + } +} + +function handleMaxPadding(chartArea) { + var maxPadding = chartArea.maxPadding; + + function updatePos(pos) { + var change = Math.max(maxPadding[pos] - chartArea[pos], 0); + chartArea[pos] += change; + return change; + } + chartArea.y += updatePos('top'); + chartArea.x += updatePos('left'); + updatePos('right'); + updatePos('bottom'); +} + +function getMargins(horizontal, chartArea) { + var maxPadding = chartArea.maxPadding; + + function marginForPositions(positions) { + var margin = {left: 0, top: 0, right: 0, bottom: 0}; + positions.forEach(function(pos) { + margin[pos] = Math.max(chartArea[pos], maxPadding[pos]); + }); + return margin; + } + + return horizontal + ? marginForPositions(['left', 'right']) + : marginForPositions(['top', 'bottom']); +} + +function fitBoxes(boxes, chartArea, params) { + var refitBoxes = []; + var i, ilen, layout, box, refit, changed; + + for (i = 0, ilen = boxes.length; i < ilen; ++i) { + layout = boxes[i]; + box = layout.box; + + box.update( + layout.width || chartArea.w, + layout.height || chartArea.h, + getMargins(layout.horizontal, chartArea) + ); + if (updateDims(chartArea, params, layout)) { + changed = true; + if (refitBoxes.length) { + // Dimensions changed and there were non full width boxes before this + // -> we have to refit those + refit = true; + } + } + if (!box.fullWidth) { // fullWidth boxes don't need to be re-fitted in any case + refitBoxes.push(layout); + } + } + + return refit ? fitBoxes(refitBoxes, chartArea, params) || changed : changed; +} + +function placeBoxes(boxes, chartArea, params) { + var userPadding = params.padding; + var x = chartArea.x; + var y = chartArea.y; + var i, ilen, layout, box; + + for (i = 0, ilen = boxes.length; i < ilen; ++i) { + layout = boxes[i]; + box = layout.box; + if (layout.horizontal) { + box.left = box.fullWidth ? userPadding.left : chartArea.left; + box.right = box.fullWidth ? params.outerWidth - userPadding.right : chartArea.left + chartArea.w; + box.top = y; + box.bottom = y + box.height; + box.width = box.right - box.left; + y = box.bottom; + } else { + box.left = x; + box.right = x + box.width; + box.top = chartArea.top; + box.bottom = chartArea.top + chartArea.h; + box.height = box.bottom - box.top; + x = box.right; + } + } + + chartArea.x = x; + chartArea.y = y; +} + +core_defaults._set('global', { + layout: { + padding: { + top: 0, + right: 0, + bottom: 0, + left: 0 + } + } +}); + +/** + * @interface ILayoutItem + * @prop {string} position - The position of the item in the chart layout. Possible values are + * 'left', 'top', 'right', 'bottom', and 'chartArea' + * @prop {number} weight - The weight used to sort the item. Higher weights are further away from the chart area + * @prop {boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down + * @prop {function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom) + * @prop {function} update - Takes two parameters: width and height. Returns size of item + * @prop {function} getPadding - Returns an object with padding on the edges + * @prop {number} width - Width of item. Must be valid after update() + * @prop {number} height - Height of item. Must be valid after update() + * @prop {number} left - Left edge of the item. Set by layout system and cannot be used in update + * @prop {number} top - Top edge of the item. Set by layout system and cannot be used in update + * @prop {number} right - Right edge of the item. Set by layout system and cannot be used in update + * @prop {number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update + */ + +// The layout service is very self explanatory. It's responsible for the layout within a chart. +// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need +// It is this service's responsibility of carrying out that layout. +var core_layouts = { + defaults: {}, + + /** + * Register a box to a chart. + * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title. + * @param {Chart} chart - the chart to use + * @param {ILayoutItem} item - the item to add to be layed out + */ + addBox: function(chart, item) { + if (!chart.boxes) { + chart.boxes = []; + } + + // initialize item with default values + item.fullWidth = item.fullWidth || false; + item.position = item.position || 'top'; + item.weight = item.weight || 0; + item._layers = item._layers || function() { + return [{ + z: 0, + draw: function() { + item.draw.apply(item, arguments); + } + }]; + }; + + chart.boxes.push(item); + }, + + /** + * Remove a layoutItem from a chart + * @param {Chart} chart - the chart to remove the box from + * @param {ILayoutItem} layoutItem - the item to remove from the layout + */ + removeBox: function(chart, layoutItem) { + var index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1; + if (index !== -1) { + chart.boxes.splice(index, 1); + } + }, + + /** + * Sets (or updates) options on the given `item`. + * @param {Chart} chart - the chart in which the item lives (or will be added to) + * @param {ILayoutItem} item - the item to configure with the given options + * @param {object} options - the new item options. + */ + configure: function(chart, item, options) { + var props = ['fullWidth', 'position', 'weight']; + var ilen = props.length; + var i = 0; + var prop; + + for (; i < ilen; ++i) { + prop = props[i]; + if (options.hasOwnProperty(prop)) { + item[prop] = options[prop]; + } + } + }, + + /** + * Fits boxes of the given chart into the given size by having each box measure itself + * then running a fitting algorithm + * @param {Chart} chart - the chart + * @param {number} width - the width to fit into + * @param {number} height - the height to fit into + */ + update: function(chart, width, height) { + if (!chart) { + return; + } + + var layoutOptions = chart.options.layout || {}; + var padding = helpers$1.options.toPadding(layoutOptions.padding); + + var availableWidth = width - padding.width; + var availableHeight = height - padding.height; + var boxes = buildLayoutBoxes(chart.boxes); + var verticalBoxes = boxes.vertical; + var horizontalBoxes = boxes.horizontal; + + // Essentially we now have any number of boxes on each of the 4 sides. + // Our canvas looks like the following. + // The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and + // B1 is the bottom axis + // There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays + // These locations are single-box locations only, when trying to register a chartArea location that is already taken, + // an error will be thrown. + // + // |----------------------------------------------------| + // | T1 (Full Width) | + // |----------------------------------------------------| + // | | | T2 | | + // | |----|-------------------------------------|----| + // | | | C1 | | C2 | | + // | | |----| |----| | + // | | | | | + // | L1 | L2 | ChartArea (C0) | R1 | + // | | | | | + // | | |----| |----| | + // | | | C3 | | C4 | | + // | |----|-------------------------------------|----| + // | | | B1 | | + // |----------------------------------------------------| + // | B2 (Full Width) | + // |----------------------------------------------------| + // + + var params = Object.freeze({ + outerWidth: width, + outerHeight: height, + padding: padding, + availableWidth: availableWidth, + vBoxMaxWidth: availableWidth / 2 / verticalBoxes.length, + hBoxMaxHeight: availableHeight / 2 + }); + var chartArea = extend({ + maxPadding: extend({}, padding), + w: availableWidth, + h: availableHeight, + x: padding.left, + y: padding.top + }, padding); + + setLayoutDims(verticalBoxes.concat(horizontalBoxes), params); + + // First fit vertical boxes + fitBoxes(verticalBoxes, chartArea, params); + + // Then fit horizontal boxes + if (fitBoxes(horizontalBoxes, chartArea, params)) { + // if the area changed, re-fit vertical boxes + fitBoxes(verticalBoxes, chartArea, params); + } + + handleMaxPadding(chartArea); + + // Finally place the boxes to correct coordinates + placeBoxes(boxes.leftAndTop, chartArea, params); + + // Move to opposite side of chart + chartArea.x += chartArea.w; + chartArea.y += chartArea.h; + + placeBoxes(boxes.rightAndBottom, chartArea, params); + + chart.chartArea = { + left: chartArea.left, + top: chartArea.top, + right: chartArea.left + chartArea.w, + bottom: chartArea.top + chartArea.h + }; + + // Finally update boxes in chartArea (radial scale for example) + helpers$1.each(boxes.chartArea, function(layout) { + var box = layout.box; + extend(box, chart.chartArea); + box.update(chartArea.w, chartArea.h); + }); + } +}; + +/** + * Platform fallback implementation (minimal). + * @see https://github.com/chartjs/Chart.js/pull/4591#issuecomment-319575939 + */ + +var platform_basic = { + acquireContext: function(item) { + if (item && item.canvas) { + // Support for any object associated to a canvas (including a context2d) + item = item.canvas; + } + + return item && item.getContext('2d') || null; + } +}; + +var platform_dom = "/*\n * DOM element rendering detection\n * https://davidwalsh.name/detect-node-insertion\n */\n@keyframes chartjs-render-animation {\n\tfrom { opacity: 0.99; }\n\tto { opacity: 1; }\n}\n\n.chartjs-render-monitor {\n\tanimation: chartjs-render-animation 0.001s;\n}\n\n/*\n * DOM element resizing detection\n * https://github.com/marcj/css-element-queries\n */\n.chartjs-size-monitor,\n.chartjs-size-monitor-expand,\n.chartjs-size-monitor-shrink {\n\tposition: absolute;\n\tdirection: ltr;\n\tleft: 0;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\toverflow: hidden;\n\tpointer-events: none;\n\tvisibility: hidden;\n\tz-index: -1;\n}\n\n.chartjs-size-monitor-expand > div {\n\tposition: absolute;\n\twidth: 1000000px;\n\theight: 1000000px;\n\tleft: 0;\n\ttop: 0;\n}\n\n.chartjs-size-monitor-shrink > div {\n\tposition: absolute;\n\twidth: 200%;\n\theight: 200%;\n\tleft: 0;\n\ttop: 0;\n}\n"; + +var platform_dom$1 = /*#__PURE__*/Object.freeze({ +__proto__: null, +'default': platform_dom +}); + +var stylesheet = getCjsExportFromNamespace(platform_dom$1); + +var EXPANDO_KEY = '$chartjs'; +var CSS_PREFIX = 'chartjs-'; +var CSS_SIZE_MONITOR = CSS_PREFIX + 'size-monitor'; +var CSS_RENDER_MONITOR = CSS_PREFIX + 'render-monitor'; +var CSS_RENDER_ANIMATION = CSS_PREFIX + 'render-animation'; +var ANIMATION_START_EVENTS = ['animationstart', 'webkitAnimationStart']; + +/** + * DOM event types -> Chart.js event types. + * Note: only events with different types are mapped. + * @see https://developer.mozilla.org/en-US/docs/Web/Events + */ +var EVENT_TYPES = { + touchstart: 'mousedown', + touchmove: 'mousemove', + touchend: 'mouseup', + pointerenter: 'mouseenter', + pointerdown: 'mousedown', + pointermove: 'mousemove', + pointerup: 'mouseup', + pointerleave: 'mouseout', + pointerout: 'mouseout' +}; + +/** + * The "used" size is the final value of a dimension property after all calculations have + * been performed. This method uses the computed style of `element` but returns undefined + * if the computed style is not expressed in pixels. That can happen in some cases where + * `element` has a size relative to its parent and this last one is not yet displayed, + * for example because of `display: none` on a parent node. + * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value + * @returns {number} Size in pixels or undefined if unknown. + */ +function readUsedSize(element, property) { + var value = helpers$1.getStyle(element, property); + var matches = value && value.match(/^(\d+)(\.\d+)?px$/); + return matches ? Number(matches[1]) : undefined; +} + +/** + * Initializes the canvas style and render size without modifying the canvas display size, + * since responsiveness is handled by the controller.resize() method. The config is used + * to determine the aspect ratio to apply in case no explicit height has been specified. + */ +function initCanvas(canvas, config) { + var style = canvas.style; + + // NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it + // returns null or '' if no explicit value has been set to the canvas attribute. + var renderHeight = canvas.getAttribute('height'); + var renderWidth = canvas.getAttribute('width'); + + // Chart.js modifies some canvas values that we want to restore on destroy + canvas[EXPANDO_KEY] = { + initial: { + height: renderHeight, + width: renderWidth, + style: { + display: style.display, + height: style.height, + width: style.width + } + } + }; + + // Force canvas to display as block to avoid extra space caused by inline + // elements, which would interfere with the responsive resize process. + // https://github.com/chartjs/Chart.js/issues/2538 + style.display = style.display || 'block'; + + if (renderWidth === null || renderWidth === '') { + var displayWidth = readUsedSize(canvas, 'width'); + if (displayWidth !== undefined) { + canvas.width = displayWidth; + } + } + + if (renderHeight === null || renderHeight === '') { + if (canvas.style.height === '') { + // If no explicit render height and style height, let's apply the aspect ratio, + // which one can be specified by the user but also by charts as default option + // (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2. + canvas.height = canvas.width / (config.options.aspectRatio || 2); + } else { + var displayHeight = readUsedSize(canvas, 'height'); + if (displayWidth !== undefined) { + canvas.height = displayHeight; + } + } + } + + return canvas; +} + +/** + * Detects support for options object argument in addEventListener. + * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support + * @private + */ +var supportsEventListenerOptions = (function() { + var supports = false; + try { + var options = Object.defineProperty({}, 'passive', { + // eslint-disable-next-line getter-return + get: function() { + supports = true; + } + }); + window.addEventListener('e', null, options); + } catch (e) { + // continue regardless of error + } + return supports; +}()); + +// Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events. +// https://github.com/chartjs/Chart.js/issues/4287 +var eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false; + +function addListener(node, type, listener) { + node.addEventListener(type, listener, eventListenerOptions); +} + +function removeListener(node, type, listener) { + node.removeEventListener(type, listener, eventListenerOptions); +} + +function createEvent(type, chart, x, y, nativeEvent) { + return { + type: type, + chart: chart, + native: nativeEvent || null, + x: x !== undefined ? x : null, + y: y !== undefined ? y : null, + }; +} + +function fromNativeEvent(event, chart) { + var type = EVENT_TYPES[event.type] || event.type; + var pos = helpers$1.getRelativePosition(event, chart); + return createEvent(type, chart, pos.x, pos.y, event); +} + +function throttled(fn, thisArg) { + var ticking = false; + var args = []; + + return function() { + args = Array.prototype.slice.call(arguments); + thisArg = thisArg || this; + + if (!ticking) { + ticking = true; + helpers$1.requestAnimFrame.call(window, function() { + ticking = false; + fn.apply(thisArg, args); + }); + } + }; +} + +function createDiv(cls) { + var el = document.createElement('div'); + el.className = cls || ''; + return el; +} + +// Implementation based on https://github.com/marcj/css-element-queries +function createResizer(handler) { + var maxSize = 1000000; + + // NOTE(SB) Don't use innerHTML because it could be considered unsafe. + // https://github.com/chartjs/Chart.js/issues/5902 + var resizer = createDiv(CSS_SIZE_MONITOR); + var expand = createDiv(CSS_SIZE_MONITOR + '-expand'); + var shrink = createDiv(CSS_SIZE_MONITOR + '-shrink'); + + expand.appendChild(createDiv()); + shrink.appendChild(createDiv()); + + resizer.appendChild(expand); + resizer.appendChild(shrink); + resizer._reset = function() { + expand.scrollLeft = maxSize; + expand.scrollTop = maxSize; + shrink.scrollLeft = maxSize; + shrink.scrollTop = maxSize; + }; + + var onScroll = function() { + resizer._reset(); + handler(); + }; + + addListener(expand, 'scroll', onScroll.bind(expand, 'expand')); + addListener(shrink, 'scroll', onScroll.bind(shrink, 'shrink')); + + return resizer; +} + +// https://davidwalsh.name/detect-node-insertion +function watchForRender(node, handler) { + var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {}); + var proxy = expando.renderProxy = function(e) { + if (e.animationName === CSS_RENDER_ANIMATION) { + handler(); + } + }; + + helpers$1.each(ANIMATION_START_EVENTS, function(type) { + addListener(node, type, proxy); + }); + + // #4737: Chrome might skip the CSS animation when the CSS_RENDER_MONITOR class + // is removed then added back immediately (same animation frame?). Accessing the + // `offsetParent` property will force a reflow and re-evaluate the CSS animation. + // https://gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics + // https://github.com/chartjs/Chart.js/issues/4737 + expando.reflow = !!node.offsetParent; + + node.classList.add(CSS_RENDER_MONITOR); +} + +function unwatchForRender(node) { + var expando = node[EXPANDO_KEY] || {}; + var proxy = expando.renderProxy; + + if (proxy) { + helpers$1.each(ANIMATION_START_EVENTS, function(type) { + removeListener(node, type, proxy); + }); + + delete expando.renderProxy; + } + + node.classList.remove(CSS_RENDER_MONITOR); +} + +function addResizeListener(node, listener, chart) { + var expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {}); + + // Let's keep track of this added resizer and thus avoid DOM query when removing it. + var resizer = expando.resizer = createResizer(throttled(function() { + if (expando.resizer) { + var container = chart.options.maintainAspectRatio && node.parentNode; + var w = container ? container.clientWidth : 0; + listener(createEvent('resize', chart)); + if (container && container.clientWidth < w && chart.canvas) { + // If the container size shrank during chart resize, let's assume + // scrollbar appeared. So we resize again with the scrollbar visible - + // effectively making chart smaller and the scrollbar hidden again. + // Because we are inside `throttled`, and currently `ticking`, scroll + // events are ignored during this whole 2 resize process. + // If we assumed wrong and something else happened, we are resizing + // twice in a frame (potential performance issue) + listener(createEvent('resize', chart)); + } + } + })); + + // The resizer needs to be attached to the node parent, so we first need to be + // sure that `node` is attached to the DOM before injecting the resizer element. + watchForRender(node, function() { + if (expando.resizer) { + var container = node.parentNode; + if (container && container !== resizer.parentNode) { + container.insertBefore(resizer, container.firstChild); + } + + // The container size might have changed, let's reset the resizer state. + resizer._reset(); + } + }); +} + +function removeResizeListener(node) { + var expando = node[EXPANDO_KEY] || {}; + var resizer = expando.resizer; + + delete expando.resizer; + unwatchForRender(node); + + if (resizer && resizer.parentNode) { + resizer.parentNode.removeChild(resizer); + } +} + +/** + * Injects CSS styles inline if the styles are not already present. + * @param {HTMLDocument|ShadowRoot} rootNode - the node to contain the '; $out .= '
    '; + if ($languagecodeselected) { - $shortcode = strtolower(substr($languagecodeselected, -2)); + // Convert $languagecodeselected into a long language code + if (strlen($languagecodeselected) == 2) { + $languagecodeselected = (empty($arrayofspecialmainlanguages[$languagecodeselected]) ? $languagecodeselected.'_'.strtoupper($languagecodeselected) : $arrayofspecialmainlanguages[$languagecodeselected]); + } + + $countrycode = strtolower(substr($languagecodeselected, -2)); $label = $weblangs->trans("Language_".$languagecodeselected); - if ($shortcode == 'us') $label = preg_replace('/\s*\(.*\)/', '', $label); - $out .= '
  • '.$label; + if ($countrycode == 'us') $label = preg_replace('/\s*\(.*\)/', '', $label); + $out .= '
  • '.$label.''; $out .= ''; $out .= '
  • '; } @@ -1288,11 +1418,17 @@ class Website extends CommonObject { foreach ($languagecodes as $languagecode) { + // Convert $languagecode into a long language code + if (strlen($languagecode) == 2) { + $languagecode = (empty($arrayofspecialmainlanguages[$languagecode]) ? $languagecode.'_'.strtoupper($languagecode) : $arrayofspecialmainlanguages[$languagecode]); + } + if ($languagecode == $languagecodeselected) continue; // Already output - $shortcode = strtolower(substr($languagecode, -2)); + + $countrycode = strtolower(substr($languagecode, -2)); $label = $weblangs->trans("Language_".$languagecode); - if ($shortcode == 'us') $label = preg_replace('/\s*\(.*\)/', '', $label); - $out .= '
  • '.$label; + if ($countrycode == 'us') $label = preg_replace('/\s*\(.*\)/', '', $label); + $out .= '
  • '.$label.''; if (empty($i) && empty($languagecodeselected)) $out .= ''; $out .= '
  • '; $i++; diff --git a/htdocs/website/class/websitepage.class.php b/htdocs/website/class/websitepage.class.php index e260ddea3a3..ece8cff7e3a 100644 --- a/htdocs/website/class/websitepage.class.php +++ b/htdocs/website/class/websitepage.class.php @@ -158,6 +158,9 @@ class WebsitePage extends CommonObject $this->keywords = dol_trunc($this->keywords, 255, 'right', 'utf-8', 1); if ($this->aliasalt) $this->aliasalt = ','.preg_replace('/,+$/', '', preg_replace('/^,+/', '', $this->aliasalt)).','; // content in database must be ',xxx,...,yyy,' + // Remove spaces and be sure we have main language only + $this->lang = preg_replace('/[_-].*$/', '', trim($this->lang)); // en_US or en-US -> en + return $this->createCommon($user, $notrigger); } @@ -306,6 +309,8 @@ class WebsitePage extends CommonObject foreach ($filter as $key => $value) { if ($key == 't.rowid' || $key == 't.fk_website') { $sqlwhere[] = $key.'='.$value; + } elseif ($key == 'lang' || $key == 't.lang') { + $sqlwhere[] = $key." = '".$this->db->escape(substr($value, 0, 2))."'"; } else { $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\''; } @@ -364,6 +369,59 @@ class WebsitePage extends CommonObject } } + /** + * Count objects in the database. + * + * @param string $websiteid Web site + * @param array $filter Filter array + * @param string $filtermode Filter mode (AND or OR) + * @return int int <0 if KO, array of pages if OK + */ + public function countAll($websiteid, array $filter = array(), $filtermode = 'AND') + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $result = 0; + + $sql = 'SELECT COUNT(t.rowid) as nb'; + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; + $sql .= ' WHERE t.fk_website = '.$websiteid; + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + if ($key == 't.rowid' || $key == 't.fk_website') { + $sqlwhere[] = $key.'='.$value; + } elseif ($key == 'lang' || $key == 't.lang') { + $sqlwhere[] = $key." = '".$this->db->escape(substr($value, 0, 2))."'"; + } else { + $sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\''; + } + } + } + if (count($sqlwhere) > 0) { + $sql .= ' AND ('.implode(' '.$filtermode.' ', $sqlwhere).')'; + } + + $resql = $this->db->query($sql); + if ($resql) { + $obj = $this->db->fetch_object($resql); + if ($obj) { + $result = $obj->nb; + } + + $this->db->free($resql); + + return $result; + } else { + $this->error = 'Error '.$this->db->lasterror(); + $this->errors[] = $this->error; + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + + return -1; + } + } + /** * Update object into database * @@ -377,6 +435,22 @@ class WebsitePage extends CommonObject $this->keywords = dol_trunc($this->keywords, 255, 'right', 'utf-8', 1); if ($this->aliasalt) $this->aliasalt = ','.preg_replace('/,+$/', '', preg_replace('/^,+/', '', $this->aliasalt)).','; // content in database must be ',xxx,...,yyy,' + // Remove spaces and be sure we have main language only + $this->lang = preg_replace('/[_-].*$/', '', trim($this->lang)); // en_US or en-US -> en + + if ($this->fk_page > 0) { + if (empty($this->lang)) { + $this->error = "ErrorLanguageMandatoryIfPageSetAsTranslationOfAnother"; + return -1; + } + $tmppage = new WebsitePage($this->db); + $tmppage->fetch($this->fk_page); + if ($tmppage->lang == $this->lang) { + $this->error = "ErrorLanguageOfTranslatedPageIsSameThanThisPage"; + return -1; + } + } + return $this->updateCommon($user, $notrigger); } @@ -513,7 +587,8 @@ class WebsitePage extends CommonObject $label .= '
    '; $label .= ''.$langs->trans('Ref').': '.$this->ref.'
    '; $label .= ''.$langs->trans('ID').': '.$this->id.'
    '; - $label .= ''.$langs->trans('Title').': '.$this->title; + $label .= ''.$langs->trans('Title').': '.$this->title.'
    '; + $label .= ''.$langs->trans('Language').': '.$this->lang; $url = DOL_URL_ROOT.'/website/index.php?websiteid='.$this->fk_website.'&pageid='.$this->id; diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 3d523a6d48c..ed8a863d0a7 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2016-2020 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 @@ -24,7 +24,7 @@ define('NOSCANPOSTFORINJECTION', 1); define('NOSTYLECHECK', 1); define('USEDOLIBARREDITOR', 1); -define('FORCE_CKEDITOR', 1); // We need CKEditor, even if module is off. +define('FORCE_CKEDITOR', 1); // We need CKEditor, even if module is off. //header('X-XSS-Protection:0'); // Disable XSS filtering protection of some browsers (note: use of Content-Security-Policy is more efficient). Disabled as deprecated. @@ -40,53 +40,53 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php'; require_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php'; -$langs->loadLangs(array("admin","other","website","errors")); +$langs->loadLangs(array("admin", "other", "website", "errors")); -if (! $user->rights->website->read) accessforbidden(); +if (!$user->rights->website->read) accessforbidden(); -$conf->dol_hide_leftmenu = 1; // Force hide of left menu. +$conf->dol_hide_leftmenu = 1; // Force hide of left menu. -$error=0; -$websiteid=GETPOST('websiteid', 'int'); -$websitekey=GETPOST('website', 'alpha'); -$page=GETPOST('page', 'alpha'); -$pageid=GETPOST('pageid', 'int'); -$pageref=GETPOST('pageref', 'aZ09'); -$action=GETPOST('action', 'aZ09'); -$confirm=GETPOST('confirm', 'alpha'); -$cancel=GETPOST('cancel', 'alpha'); -$contextpage= GETPOST('contextpage', 'aZ')?GETPOST('contextpage', 'aZ'):'bomlist'; // To manage different context of search -$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page -$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') +$error = 0; +$websiteid = GETPOST('websiteid', 'int'); +$websitekey = GETPOST('website', 'alpha'); +$page = GETPOST('page', 'alpha'); +$pageid = GETPOST('pageid', 'int'); +$pageref = GETPOST('pageref', 'aZ09'); +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm', 'alpha'); +$cancel = GETPOST('cancel', 'alpha'); +$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'bomlist'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page +$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') -$type_container=GETPOST('WEBSITE_TYPE_CONTAINER', 'alpha'); +$type_container = GETPOST('WEBSITE_TYPE_CONTAINER', 'alpha'); $section_dir = GETPOST('section_dir', 'alpha'); $file_manager = GETPOST('file_manager', 'alpha'); $replacesite = GETPOST('replacesite', 'alpha'); -if (GETPOST('deletesite', 'alpha')) { $action='deletesite'; } -if (GETPOST('delete', 'alpha')) { $action='delete'; } -if (GETPOST('preview', 'alpha')) $action='preview'; -if (GETPOST('createsite', 'alpha')) { $action='createsite'; } -if (GETPOST('createcontainer', 'alpha')) { $action='createcontainer'; } -if (GETPOST('editcss', 'alpha')) { $action='editcss'; } -if (GETPOST('editmenu', 'alpha')) { $action='editmenu'; } -if (GETPOST('setashome', 'alpha')) { $action='setashome'; } -if (GETPOST('editmeta', 'alpha')) { $action='editmeta'; } -if (GETPOST('editsource', 'alpha')) { $action='editsource'; } -if (GETPOST('editcontent', 'alpha')) { $action='editcontent'; } -if (GETPOST('exportsite', 'alpha')) { $action='exportsite'; } -if (GETPOST('importsite', 'alpha')) { $action='importsite'; } -if (GETPOST('createfromclone', 'alpha')) { $action='createfromclone'; } -if (GETPOST('createpagefromclone', 'alpha')) { $action='createpagefromclone'; } -if (empty($action) && $file_manager) $action='file_manager'; -if (empty($action) && $replacesite) $action='replacesite'; +if (GETPOST('deletesite', 'alpha')) { $action = 'deletesite'; } +if (GETPOST('delete', 'alpha')) { $action = 'delete'; } +if (GETPOST('preview', 'alpha')) $action = 'preview'; +if (GETPOST('createsite', 'alpha')) { $action = 'createsite'; } +if (GETPOST('createcontainer', 'alpha')) { $action = 'createcontainer'; } +if (GETPOST('editcss', 'alpha')) { $action = 'editcss'; } +if (GETPOST('editmenu', 'alpha')) { $action = 'editmenu'; } +if (GETPOST('setashome', 'alpha')) { $action = 'setashome'; } +if (GETPOST('editmeta', 'alpha')) { $action = 'editmeta'; } +if (GETPOST('editsource', 'alpha')) { $action = 'editsource'; } +if (GETPOST('editcontent', 'alpha')) { $action = 'editcontent'; } +if (GETPOST('exportsite', 'alpha')) { $action = 'exportsite'; } +if (GETPOST('importsite', 'alpha')) { $action = 'importsite'; } +if (GETPOST('createfromclone', 'alpha')) { $action = 'createfromclone'; } +if (GETPOST('createpagefromclone', 'alpha')) { $action = 'createpagefromclone'; } +if (empty($action) && $file_manager) $action = 'file_manager'; +if (empty($action) && $replacesite) $action = 'replacesite'; if (GETPOST('refreshsite') || GETPOST('refreshsite_x') || GETPOST('refreshsite.x')) $pageid = 0; // Load variable for pagination -$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit; +$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); $sortorder = GETPOST("sortorder", 'alpha'); $page = GETPOST("page", 'int'); @@ -267,9 +267,9 @@ $manifestjsoncontentdefault .= '{ */ // Protections -if (GETPOST('refreshsite') || GETPOST('refreshsite_x') || GETPOST('refreshsite.x') || GETPOST('refreshpage') || GETPOST('refreshpage_x') || GETPOST('refreshpage.x')) +if (GETPOST('refreshsite') || GETPOST('refreshsite_x') || GETPOST('refreshsite.x') || GETPOST('refreshpage') || GETPOST('refreshpage_x') || GETPOST('refreshpage.x')) { - $action = 'preview'; // To avoid to make an action on another page or another site when we click on button to select another site or page. + $action = 'preview'; // To avoid to make an action on another page or another site when we click on button to select another site or page. } if (GETPOST('refreshsite', 'alpha') || GETPOST('refreshsite.x', 'alpha') || GETPOST('refreshsite_x', 'alpha')) // If we change the site, we reset the pageid and cancel addsite action. { @@ -279,20 +279,20 @@ if (GETPOST('refreshsite', 'alpha') || GETPOST('refreshsite.x', 'alpha') || GETP $pageid = $object->fk_default_home; if (empty($pageid)) { - $array=$objectpage->fetchAll($object->id, 'ASC,ASC', 'type_container,pageurl'); - if (! is_array($array) && $array < 0) dol_print_error('', $objectpage->error, $objectpage->errors); - $atleastonepage=(is_array($array) && count($array) > 0); + $array = $objectpage->fetchAll($object->id, 'ASC,ASC', 'type_container,pageurl'); + if (!is_array($array) && $array < 0) dol_print_error('', $objectpage->error, $objectpage->errors); + $atleastonepage = (is_array($array) && count($array) > 0); - $firstpageid=0; $homepageid=0; - foreach($array as $key => $valpage) + $firstpageid = 0; $homepageid = 0; + foreach ($array as $key => $valpage) { - if (empty($firstpageid)) $firstpageid=$valpage->id; - if ($object->fk_default_home && $key == $object->fk_default_home) $homepageid=$valpage->id; + if (empty($firstpageid)) $firstpageid = $valpage->id; + if ($object->fk_default_home && $key == $object->fk_default_home) $homepageid = $valpage->id; } - $pageid=($homepageid?$homepageid:$firstpageid); // We choose home page and if not defined yet, we take first page + $pageid = ($homepageid ? $homepageid : $firstpageid); // We choose home page and if not defined yet, we take first page } } -if (GETPOST('refreshpage', 'alpha') && ! in_array($action, array('updatecss'))) $action='preview'; +if (GETPOST('refreshpage', 'alpha') && !in_array($action, array('updatecss'))) $action = 'preview'; // Cancel if ($cancel) @@ -396,9 +396,16 @@ if ($action == 'addsite') if (!$error) { + $arrayotherlang=explode(',', GETPOST('WEBSITE_OTHERLANG', 'alphanohtml')); + foreach($arrayotherlang as $key => $val) { + $arrayotherlang[$key] = substr(trim($val), 0, 2); // Kept short language code only + } + $tmpobject = new Website($db); $tmpobject->ref = GETPOST('WEBSITE_REF', 'alpha'); - $tmpobject->description = GETPOST('WEBSITE_DESCRIPTION', 'alpha'); + $tmpobject->description = GETPOST('WEBSITE_DESCRIPTION', 'alphanohtml'); + $tmpobject->lang = GETPOST('WEBSITE_LANG', 'aZ09'); + $tmpobject->otherlang = join(',', $arrayotherlang); $tmpobject->virtualhost = GETPOST('virtualhost', 'alpha'); $result = $tmpobject->create($user); @@ -777,14 +784,15 @@ if ($action == 'addcontainer') } else { - $objectpage->title = GETPOST('WEBSITE_TITLE', 'alpha'); - $objectpage->type_container = GETPOST('WEBSITE_TYPE_CONTAINER', 'alpha'); + $objectpage->title = GETPOST('WEBSITE_TITLE', 'alphanohtml'); + $objectpage->type_container = GETPOST('WEBSITE_TYPE_CONTAINER', 'aZ09'); $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME', 'alpha'); - $objectpage->aliasalt = GETPOST('WEBSITE_ALIASALT', 'alpha'); - $objectpage->description = GETPOST('WEBSITE_DESCRIPTION', 'alpha'); - $objectpage->image = GETPOST('WEBSITE_IMAGE', 'alpha'); - $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS', 'alpha'); + $objectpage->aliasalt = GETPOST('WEBSITE_ALIASALT', 'alphanohtml'); + $objectpage->description = GETPOST('WEBSITE_DESCRIPTION', 'alphanohtml'); $objectpage->lang = GETPOST('WEBSITE_LANG', 'aZ09'); + $objectpage->otherlang = GETPOST('WEBSITE_OTHERLANG', 'aZ09comma'); + $objectpage->image = GETPOST('WEBSITE_IMAGE', 'alpha'); + $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS', 'alphanohtml'); $objectpage->htmlheader = GETPOST('htmlheader', 'none'); $substitutionarray = array(); @@ -841,6 +849,13 @@ if ($action == 'addcontainer') { $error++; setEventMessages($object->error, $object->errors, 'errors'); + } else { + $filetpl = $pathofwebsite.'/page'.$pageid.'.tpl.php'; + + // Generate the index.php page to be the home page + $result = dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper); + + if ($result <= 0) setEventMessages('Failed to write file '.$fileindex, null, 'errors'); } } } @@ -857,7 +872,7 @@ if ($action == 'addcontainer') $result = dolSavePageAlias($filealias, $object, $objectpage); if (!$result) { - setEventMessages('Failed to write file '.$filealias, null, 'errors'); + setEventMessages('Failed to write file '.basename($filealias), null, 'errors'); } // Save page of content @@ -1035,7 +1050,7 @@ if ($action == 'delete') } } -// Update css +// Update css Update site properties if ($action == 'updatecss') { // If we tried to reload another site/page, we stay on editcss mode. @@ -1059,7 +1074,14 @@ if ($action == 'updatecss') if (!$error) { + $arrayotherlang=explode(',', GETPOST('WEBSITE_OTHERLANG', 'alphanohtml')); + foreach($arrayotherlang as $key => $val) { + $arrayotherlang[$key] = substr(trim($val), 0, 2); // Kept short language code only + } + $object->virtualhost = GETPOST('virtualhost', 'alpha'); + $object->lang = GETPOST('WEBSITE_LANG', 'aZ09'); + $object->otherlang = join(',', $arrayotherlang); $object->use_manifest = GETPOST('use_manifest', 'alpha'); $result = $object->update($user); @@ -1312,8 +1334,9 @@ if ($action == 'setashome') { $db->commit(); + $filetpl = $pathofwebsite.'/page'.$pageid.'.tpl.php'; + // Generate the index.php page to be the home page - //------------------------------------------------- $result = dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper); if ($result) setEventMessages($langs->trans("Saved"), null, 'mesgs'); @@ -1403,14 +1426,15 @@ if ($action == 'updatemeta') { $objectpage->old_object = clone $objectpage; - $objectpage->title = GETPOST('WEBSITE_TITLE', 'alpha'); - $objectpage->type_container = GETPOST('WEBSITE_TYPE_CONTAINER', 'alpha'); + $objectpage->title = GETPOST('WEBSITE_TITLE', 'alphanohtml'); + $objectpage->type_container = GETPOST('WEBSITE_TYPE_CONTAINER', 'alphanohtml'); $objectpage->pageurl = GETPOST('WEBSITE_PAGENAME', 'alpha'); $objectpage->aliasalt = GETPOST('WEBSITE_ALIASALT', 'alpha'); - $objectpage->description = GETPOST('WEBSITE_DESCRIPTION', 'alpha'); - $objectpage->image = GETPOST('WEBSITE_IMAGE', 'alpha'); - $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS', 'alpha'); $objectpage->lang = GETPOST('WEBSITE_LANG', 'aZ09'); + $objectpage->otherlang = GETPOST('WEBSITE_OTHERLANG', 'aZ09comma'); + $objectpage->description = GETPOST('WEBSITE_DESCRIPTION', 'alphanohtml'); + $objectpage->image = GETPOST('WEBSITE_IMAGE', 'alpha'); + $objectpage->keywords = GETPOST('WEBSITE_KEYWORDS', 'alphanohtml'); $objectpage->htmlheader = trim(GETPOST('htmlheader', 'none')); $objectpage->fk_page = (GETPOST('pageidfortranslation', 'int') > 0 ? GETPOST('pageidfortranslation', 'int') : 0); @@ -1493,8 +1517,9 @@ if ($action == 'updatemeta') { if (trim($tmpaliasalt)) { - $result = dolSavePageAlias($pathofwebsite.'/'.trim($tmpaliasalt).'.php', $object, $objectpage); - if (!$result) setEventMessages('Failed to write file '.$pathofwebsite.'/'.trim($tmpaliasalt).'.php', null, 'errors'); + $filealias = $pathofwebsite.'/'.trim($tmpaliasalt).'.php'; + $result = dolSavePageAlias($filealias, $object, $objectpage); + if (!$result) setEventMessages('Failed to write file '.basename($filealias), null, 'errors'); } } } @@ -1750,7 +1775,7 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf // Save page alias $result = dolSavePageAlias($filealias, $object, $objectpage); - if (!$result) setEventMessages('Failed to write file '.$filealias, null, 'errors'); + if (!$result) setEventMessages('Failed to write file '.basename($filealias), null, 'errors'); // Save page content $result = dolSavePageContent($filetpl, $object, $objectpage); @@ -2026,8 +2051,8 @@ if ($action != 'preview' && $action != 'editcontent' && $action != 'editsource') if (!GETPOST('hide_websitemenu')) { - $disabled=''; - if (empty($user->rights->website->write)) $disabled=' disabled="disabled"'; + $disabled = ''; + if (empty($user->rights->website->write)) $disabled = ' disabled="disabled"'; //var_dump($objectpage);exit; print '
    '; @@ -2071,19 +2096,19 @@ if (!GETPOST('hide_websitemenu')) if ($websitekey) { - $virtualurl=''; - $dataroot=DOL_DATA_ROOT.'/website/'.$websitekey; - if (! empty($object->virtualhost)) $virtualurl=$object->virtualhost; + $virtualurl = ''; + $dataroot = DOL_DATA_ROOT.'/website/'.$websitekey; + if (!empty($object->virtualhost)) $virtualurl = $object->virtualhost; } - $array=array(); + $array = array(); if ($object->id > 0) { - $array=$objectpage->fetchAll($object->id, 'ASC,ASC', 'type_container,pageurl'); + $array = $objectpage->fetchAll($object->id, 'ASC,ASC', 'type_container,pageurl'); $object->lines = $array; } - if (! is_array($array) && $array < 0) dol_print_error('', $objectpage->error, $objectpage->errors); - $atleastonepage=(is_array($array) && count($array) > 0); + if (!is_array($array) && $array < 0) dol_print_error('', $objectpage->error, $objectpage->errors); + $atleastonepage = (is_array($array) && count($array) > 0); if ($websitekey && $websitekey != '-1' && ($action == 'preview' || $action == 'createfromclone' || $action == 'createpagefromclone' || $action == 'deletesite')) { @@ -2170,7 +2195,26 @@ if (!GETPOST('hide_websitemenu')) $htmltext .= '
    '; $htmltext .= '
    '.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT); $htmltext .= '
    '.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT.'/website
    '.DOL_DATA_ROOT.'/medias'); - $htmltext .= '
    '; + + $examplewithapache = ''."\n"; + $examplewithapache .= 'AllowOverride FileInfo Options + Options -Indexes -MultiViews -FollowSymLinks -ExecCGI + Require all granted + + + AllowOverride FileInfo Options + Options -Indexes -MultiViews +FollowSymLinks -ExecCGI + Require all granted + + + AllowOverride FileInfo Options + Options -Indexes -MultiViews -FollowSymLinks -ExecCGI + Require all granted + '; + + $htmltext .= '
    '.$langs->trans("ExampleToUseInApacheVirtualHostConfig").':
    '; + $htmltext .= '
    '.dol_nl2br(dol_escape_htmltag($examplewithapache, 1, 1)).'
    '; + $htmltext .= '
    '; $htmltext .= $langs->trans("YouCanAlsoTestWithPHPS", $dataroot); $htmltext .= '
    '; @@ -2346,7 +2390,7 @@ if (!GETPOST('hide_websitemenu')) if (! isEditingEnabled || forceenable) { console.log("Enable inline edit"); - jQuery(\'section[contenteditable="true"]\').each(function(idx){ + jQuery(\'section[contenteditable="true"],div[contenteditable="true"]\').each(function(idx){ var idtouse = $(this).attr(\'id\'); console.log("Enable inline edit for "+idtouse); CKEDITOR.inline(idtouse, { @@ -2375,7 +2419,9 @@ if (!GETPOST('hide_websitemenu')) print $langs->trans("EditInLine"); print ''; - if ($websitepage->grabbed_from) + //$disableeditinline = $websitepage->grabbed_from; + $disableeditinline = 0; + if ($disableeditinline) { //print ''; print ''.img_picto($langs->trans("OnlyEditionOfSourceForGrabbedContent"), 'switch_off', '', false, 0, 0, '', 'nomarginleft').''; @@ -2396,12 +2442,6 @@ if (!GETPOST('hide_websitemenu')) print '
    '; print '
    '; print $langs->trans("ShowSubcontainers"); - /*if ($websitepage->grabbed_from) - { - print ''.img_picto($langs->trans("OnlyEditionOfSourceForGrabbedContent"),'switch_off','',false,0,0,'','nomarginleft').''; - } - else - {*/ if (empty($conf->global->WEBSITE_SUBCONTAINERSINLINE)) { print ''.img_picto($langs->trans("ShowSubContainersOnOff", $langs->transnoentitiesnoconv("Off")), 'switch_off', '', false, 0, 0, '', 'nomarginleft').''; @@ -2446,16 +2486,19 @@ if (!GETPOST('hide_websitemenu')) $htmltext .= '
    '.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("ReadPerm"), DOL_DOCUMENT_ROOT); $htmltext .= '
    '.$langs->trans("CheckVirtualHostPerms", $langs->transnoentitiesnoconv("WritePerm"), DOL_DATA_ROOT.'/website
    '.DOL_DATA_ROOT.'/medias'); - print ''; + print ''; - print '
    '; + /*print '
    '; print ''; $htmltext = $langs->trans("PageNameAliasHelp", $langs->transnoentitiesnoconv("EditPageMeta")); print $form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'helppagealias'); - print '
    '; + print '
    ';*/ + /* $urlext = $virtualurl.'/'.$pagealias.'.php'; $urlint = $urlwithroot.'/public/website/index.php?website='.$websitekey; @@ -2464,6 +2507,7 @@ if (!GETPOST('hide_websitemenu')) print ''; print $form->textwithpicto('', $htmltext, 1, 'preview_ext'); print ''; + */ //print ''; // TODO Add js to save alias like we save virtual host name and use dynamic virtual host for url of id=previewpageext @@ -2685,12 +2729,30 @@ if ($action == 'editcss') print ''; // Website - print ''; + // Main language + print ''; + print ''; + + // Other languages + print ''; + print ''; + // VirtualHost print '
    '; + print '
    '; print $langs->trans('WebSite'); print ''; print $websitekey; print '
    '; + $htmltext=''; + print $form->textwithpicto($langs->trans('MainLanguage'), $htmltext, 1, 'help', '', 0, 2, 'WEBSITE_LANG'); + print ''; + print $formadmin->select_language((GETPOSTISSET('WEBSITE_LANG') ? GETPOST('WEBSITE_LANG', 'aZ09comma') : ($object->lang ? $object->lang : '0')), 'WEBSITE_LANG', 0, null, 1, 0, 0, 'minwidth300', 2, 0, 0, array(), 1); + print '
    '; + $htmltext = ''; + print $form->textwithpicto($langs->trans('OtherLanguages'), $htmltext, 1, 'help', '', 0, 2, 'WEBSITE_OTHERLANG'); + print ''; + print ''; + print '
    '; @@ -2816,19 +2878,35 @@ if ($action == 'createsite') print ''; + $siteref = $sitedesc = $sitelang = $siteotherlang = ''; if (GETPOST('WEBSITE_REF')) $siteref = GETPOST('WEBSITE_REF', 'alpha'); if (GETPOST('WEBSITE_DESCRIPTION')) $sitedesc = GETPOST('WEBSITE_DESCRIPTION', 'alpha'); + if (GETPOST('WEBSITE_LANG')) $sitelang = GETPOST('WEBSITE_LANG', 'aZ09'); + if (GETPOST('WEBSITE_OTHERLANG')) $siteotherlang = GETPOST('WEBSITE_OTHERLANG', 'aZ09comma'); print ''; + + print ''; print ''; + + print ''; print ''; // Translation of @@ -3380,7 +3476,7 @@ if ($action == 'replacesite' || $action == 'replacesiteconfirm') { print ''; print ''; print '
    '; print $langs->trans('Ref'); print ''; - print ''; + print ''; + print '
    '; + print $langs->trans('MainLanguage'); + print ''; + $shortlangcode = preg_replace('/[_-].*$/', '', trim($langs->defaultlang)); + print $formadmin->select_language((GETPOSTISSET('WEBSITE_LANG') ? GETPOST('WEBSITE_LANG', 'aZ09comma') : $shortlangcode), 'WEBSITE_LANG', 0, null, 1, 0, 0, 'minwidth300', 2, 0, 0, array(), 1); print '
    '; print $langs->trans('Description'); print ''; - print ''; + print ''; + print '
    '; + print $langs->trans('OtherLanguages'); + print ''; + print ''; print '
    '; @@ -3057,7 +3135,25 @@ if ($action == 'editmeta' || $action == 'createcontainer') print '
    '; print $langs->trans('Language'); print ''; - print $formadmin->select_language($pagelang ? $pagelang : $langs->defaultlang, 'WEBSITE_LANG', 0, null, '1', 0, 0, 'minwidth200'); + $onlykeys = array(); + if ($object->lang) $onlykeys[$object->lang] = $object->lang; + else $onlykeys[$langs->defaultlang] = $langs->defaultlang; + if ($object->otherlang) { + $tmparray = explode(',', $object->otherlang); + foreach ($tmparray as $key) { + $tmpkey = trim($key); + if (strlen($key) == 2) { + $tmpkey = strtolower($key); + } + $onlykeys[$tmpkey] = $tmpkey; + } + } + if (empty($object->lang) && empty($object->otherlang)) { + $onlykeys = null; // We keep full list of languages + } + print $formadmin->select_language($pagelang ? $pagelang : '', 'WEBSITE_LANG', 0, null, '1', 0, 0, 'minwidth200', 0, 0, 0, $onlykeys, 1); + $htmltext = $langs->trans("AvailableLanguagesAreDefinedIntoWebsiteProperties"); + print $form->textwithpicto('', $htmltext); print '
    '.$langs->trans("Container").' - '; - print $langs->trans($answerrecord->type_container); // TODO Use label of container + print $langs->trans($answerrecord->type_container); // TODO Use label of container print ''; print $answerrecord->getNomUrl(1); @@ -3417,7 +3513,7 @@ if ($action == 'replacesite' || $action == 'replacesiteconfirm') 'website_readme'=>'WEBSITE_README', 'website_manifestjson'=>'WEBSITE_MANIFEST_JSON' ); - if (! empty($translateofrecordtype[$answerrecord['type']])) { + if (!empty($translateofrecordtype[$answerrecord['type']])) { print $langs->trans($translateofrecordtype[$answerrecord['type']]); } else { print $answerrecord['type']; diff --git a/scripts/website/migrate_news_joomla2dolibarr.php b/scripts/website/migrate_news_joomla2dolibarr.php new file mode 100755 index 00000000000..a4ad5b89dd5 --- /dev/null +++ b/scripts/website/migrate_news_joomla2dolibarr.php @@ -0,0 +1,93 @@ +#!/usr/bin/env php + + * + * 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 scripts/website/migrate_newsèjoomla2dolibarr.php + * \ingroup scripts + * \brief Migrate news from a Joomla databse into a Dolibarr website + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path = __DIR__ . '/'; + +// Test if batch mode +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute " . $script_file . " from command line, you must use PHP for CLI mode.\n"; + exit(- 1); +} + +@set_time_limit(0); // No timeout for this script +define('EVEN_IF_ONLY_LOGIN_ALLOWED', 1); // Set this define to 0 if you want to lock your script when dolibarr setup is "locked to admin user only". + +$error = 0; + +if (empty($argv[3]) || ! in_array($argv[1], array('test','confirm'))) { + print "Usage: $script_file (test|confirm) website login:pass@serverjoomla/tableprefix/databasejoomla\n"; + print "\n"; + print "Load joomla news and create them into Dolibarr database (if they don't alreay exist).\n"; + exit(- 1); +} + +$mode = $argv[1]; +$website = $argv[2]; +$joomlaserverinfo = $argv[3]; + +require $path . "../../htdocs/master.inc.php"; + +$langs->load('main'); + +$joomlaserverinfoarray = preg_split('/(:|@|\/)/', $joomlaserverinfo); +$joomlalogin = $joomlaserverinfoarray[0]; +$joomlapass = $joomlaserverinfoarray[1]; +$joomlahost = $joomlaserverinfoarray[2]; +$joomlaprefix = $joomlaserverinfoarray[3]; +$joomladatabase = $joomlaserverinfoarray[4]; +$joomlaport = 3306; + + +$dbjoomla=getDoliDBInstance('mysqli', $joomlahost, $joomlalogin, $joomlapass, $joomladatabase, $joomlaport); +if ($dbjoomla->error) +{ + dol_print_error($dbjoomla, "host=".$joomlahost.", port=".$joomlaport.", user=".$joomlalogin.", databasename=".$joomladatabase.", ".$dbjoomla->error); + exit(-1); +} + +$sql = 'SELECT id, title, alias, created, introtext, `fulltext` FROM '.$joomlaprefix.'_content WHERE 1 = 1'; +$resql = $dbjoomla->query($sql); + +if (! $resql) { + dol_print_error($dbjoomla); + exit; +} + +while ($obj = $dbjoomla->fetch_object($resql)) { + $i = 0; + if ($obj) { + $i++; + $id = $obj->id; + $title = $obj->title; + $alias = $obj->alias; + $description = dol_string_nohtmltag($obj->introtext); + $hmtltext = $obj->fulltext; + + print $i.' '.$id.' '.$title."\n"; + } +} + +exit($error); diff --git a/test/README b/test/README index 3e13bbbec70..2c53e31daee 100644 --- a/test/README +++ b/test/README @@ -3,6 +3,10 @@ README (English) This directory contains unit tests and docs for Dolibarr quality analysis. +- PHPUnit - https://phpunit.de +- PHP_CodeSniffer - https://pear.php.net/package/PHP_CodeSniffer/ +- PHP Depend - https://pdepend.org/ + PHPUNIT ------- diff --git a/test/phpunit/CodingPhpTest.php b/test/phpunit/CodingPhpTest.php index e7f232e1049..733071c0f58 100644 --- a/test/phpunit/CodingPhpTest.php +++ b/test/phpunit/CodingPhpTest.php @@ -158,6 +158,19 @@ class CodingPhpTest extends PHPUnit\Framework\TestCase $filecontent=file_get_contents($file['fullname']); + $ok=true; + $matches=array(); + // Check string ='".$this->xxx with xxx that is not 'escape'. It means we forget a db->escape when forging sql request. + preg_match_all('/'.preg_quote('get_class($this)."::".__METHOD__', '/').'/', $filecontent, $matches, PREG_SET_ORDER); + foreach($matches as $key => $val) + { + $ok=false; + break; + } + //print __METHOD__." Result for checking we don't have non escaped string in sql requests for file ".$file."\n"; + $this->assertTrue($ok, 'Found string get_class($this)."::".__METHOD__ that must be replaced with __METHOD__ only in '.$file['fullname']); + //exit; + $ok=true; $matches=array(); // Check string ='".$this->xxx with xxx that is not 'escape'. It means we forget a db->escape when forging sql request. diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 12126d9cf40..dff6b3a7d06 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -679,6 +679,26 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase $this->assertFalse($result); } + /** + * testDolAsciiCheck + * + * @return void + */ + public function testDolAsciiCheck() + { + // True + $result=ascii_check('azerty'); + $this->assertTrue($result); + + $result=ascii_check('é'); + $this->assertFalse($result); + + $file=dirname(__FILE__).'/textutf8.txt'; + $filecontent=file_get_contents($file); + $result=ascii_check($filecontent); + $this->assertFalse($result); + } + /** * testDolTrunc * diff --git a/test/phpunit/HolidayTest.php b/test/phpunit/HolidayTest.php index fbd4a846024..cd5a9f28138 100644 --- a/test/phpunit/HolidayTest.php +++ b/test/phpunit/HolidayTest.php @@ -247,21 +247,17 @@ class HolidayTest extends PHPUnit\Framework\TestCase $langs=$this->savlangs; $db=$this->savdb; - //$localobject->fetch($localobject->id); + $result = $localobject->fetchUsers(true, true, ''); + $this->assertNotEquals($result, -1); - /* - $result=$localobject->getNomUrl(1); - print __METHOD__." id=".$localobject->id." result=".$result."\n"; - $this->assertNotEquals($result, ''); + $result = $localobject->fetchUsers(true, false, ''); + $this->assertNotEquals($result, -1); - $result=$localobject->getFullAddress(1); - print __METHOD__." id=".$localobject->id." result=".$result."\n"; - $this->assertContains("New address\nNew zip New town\nBelgium", $result); + $result = $localobject->fetchUsers(false, true, ''); + $this->assertNotEquals($result, -1); - $localobject->info($localobject->id); - print __METHOD__." localobject->date_creation=".$localobject->date_creation."\n"; - $this->assertNotEquals($localobject->date_creation, ''); - */ + $result = $localobject->fetchUsers(false, false, ''); + $this->assertNotEquals($result, -1); return $localobject->id; } diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 36f29685e29..4130426d806 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -187,28 +187,28 @@ class SecurityTest extends PHPUnit\Framework\TestCase print __METHOD__." result=".$result."\n"; $this->assertEquals($result, $_GET["param2"]); - $result=GETPOST("param3", 'alpha'); // Must return '' as there is a forbidden char " + $result=GETPOST("param3", 'alpha'); // Must return string sanitized from char " print __METHOD__." result=".$result."\n"; - $this->assertEquals($result, ''); + $this->assertEquals($result, 'a/b#e(pr)qq-rr\cc'); - $result=GETPOST("param4", 'alpha'); // Must return '' as there is a forbidden char ../ + $result=GETPOST("param4", 'alpha'); // Must return string sanitized from ../ print __METHOD__." result=".$result."\n"; - $this->assertEquals($result, ''); + $this->assertEquals($result, 'dir'); // Test aZ09 - $result=GETPOST("param1", 'aZ09'); // Must return '' as there is a forbidden char ../ + $result=GETPOST("param1", 'aZ09'); print __METHOD__." result=".$result."\n"; $this->assertEquals($result, $_GET["param1"]); - $result=GETPOST("param2", 'aZ09'); // Must return '' as there is a forbidden char ../ + $result=GETPOST("param2", 'aZ09'); // Must return '' as string contains car not in aZ09 definition print __METHOD__." result=".$result."\n"; $this->assertEquals($result, ''); - $result=GETPOST("param3", 'aZ09'); // Must return '' as there is a forbidden char ../ + $result=GETPOST("param3", 'aZ09'); // Must return '' as string contains car not in aZ09 definition print __METHOD__." result=".$result."\n"; $this->assertEquals($result, ''); - $result=GETPOST("param4", 'aZ09'); // Must return '' as there is a forbidden char ../ + $result=GETPOST("param4", 'aZ09'); // Must return '' as string contains car not in aZ09 definition print __METHOD__." result=".$result."\n"; $this->assertEquals($result, ''); diff --git a/test/selenium/README b/test/selenium/README new file mode 100644 index 00000000000..1d0b7ad44d1 --- /dev/null +++ b/test/selenium/README @@ -0,0 +1,11 @@ +README (English) +-------------------------------- + +This directory contains test files for Selenium. + +Selenium is a tool for automatic testing of web applications. + +https://www.selenium.dev/ + + + diff --git a/test/test_serialize.php b/test/test_serialize.php new file mode 100644 index 00000000000..873698e95c2 --- /dev/null +++ b/test/test_serialize.php @@ -0,0 +1,50 @@ +#!/usr/bin/env php +aaa = 'aaa'; +$object->bbb = 'bbb'; +$object->thirdparty = new stdClass(); +$tmp = new Societe($db); +$tmp->name = 'MyBigCompany'; +foreach ($tmp as $key=>$value) +{ + if (!in_array($key, array( + 'name', 'name_alias', 'ref_ext', 'address', 'zip', 'town', 'state_code', 'country_code' + ))) continue; // Discard if not into a dedicated list + if (!is_object($value)) $object->thirdparty->{$key} = $value; +} + + +// Show information +print "\n"; +print "*** PHP Version : ".PHP_VERSION." - Dolibarr Version : ".DOL_VERSION."\n"; + +print "*** print_r() of object used to generate the key to hash for blockedlog on the object sample:\n"; +print print_r($object, true); +print "*** We build hash(256) of this string:\n"; +print hash('sha256', print_r($object, true)); +print "\n"; + +print "*** When it is serialized() to store in db, we got:\n"; +print serialize($object); +print "\n"; + +print "*** And when it is print_r(unserialized()) to reuse it:\n"; +print print_r(unserialize(serialize($object)), true); +print "*** We build hash(256) of this string:\n"; +print hash('sha256', print_r(unserialize(serialize($object)), true)); +print "\n"; + +print "\n"; + +//print print_r(unserialize(serialize($object)));