Merge branch 'productinstock' of github.com-melina:altairis-melina/dolibarr into productinstock

This commit is contained in:
melina 2022-04-29 10:44:15 +02:00
commit 407efccd55
4177 changed files with 165295 additions and 132717 deletions

View File

@ -26,8 +26,9 @@ Default **language here is english**. So please prepare your contributions in en
1. [Fork](https://help.github.com/articles/fork-a-repo) the [GitHub repository](https://github.com/Dolibarr/dolibarr). 1. [Fork](https://help.github.com/articles/fork-a-repo) the [GitHub repository](https://github.com/Dolibarr/dolibarr).
2. Clone your fork. 2. Clone your fork.
3. Choose a branch(See the [Branches](#branches) section below). 3. Choose a branch(See the [Branches](#branches) section below).
4. Commit and push your changes. 4. Read our developer documentation on the [Dolibarr Wiki](https://wiki.dolibarr.org/index.php?title=Developer_documentation).
5. [Make a pull request](https://help.github.com/articles/creating-a-pull-request). 5. Commit and push your changes.
6. [Make a pull request](https://help.github.com/articles/creating-a-pull-request).
<span id="branches" name="branches"></span> <span id="branches" name="branches"></span>
### Branches ### Branches

View File

@ -1,35 +0,0 @@
---
name: Bug report
about: Create a report to help us fix something that is broken
title: ''
labels: Bug
assignees: ''
---
# Instructions
*This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report.*
*Please:*
- *replace the bracket enclosed texts with meaningful information*
- *remove any unused sub-section*
# Bug
[*Short description*]
## Environment
- **Version**: [*Affected Dolibarr version(s)*]
- **OS**: [*Server OS type and version*]
- **Web server**: [*Webserver type and version*]
- **PHP**: [*PHP version*]
- **Database**: [*Database type and version*]
- **URL(s)**: [*Affected URL(s)*]
## Expected and actual behavior
[*Verbose description*]
## Steps to reproduce the behavior
[*Verbose description*]
## [Attached files](https://help.github.com/articles/issue-attachments) (Screenshots, screencasts, dolibarr.log, debugging informations…)
[*Files*]

71
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@ -0,0 +1,71 @@
name: Bug report
description: Create a report to help us fix something that is broken
labels: ["Bug"]
body:
- type: markdown
attributes:
value: |
This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report.
- type: textarea
id: bug
attributes:
label: Bug
description: Please give a short description of the bug
validations:
required: true
- type: input
id: environment-version
attributes:
label: Environment Version
description: Affected Dolibarr version(s)
- type: input
id: environment-os
attributes:
label: Environment OS
description: Server OS type and version
- type: input
id: environment-webserver
attributes:
label: Environment Web server
description: Webserver type and version
- type: input
id: environment-php
attributes:
label: Environment PHP
description: PHP version
- type: input
id: environment-database
attributes:
label: Environment Database
description: Database type and version
- type: input
id: environment-urls
attributes:
label: Environment URL(s)
description: Affected URL(s)
- type: textarea
id: expected-behaviour
attributes:
label: Expected and actual behavior
description: Verbose description
- type: textarea
id: reproduce
attributes:
label: Steps to reproduce the behavior
description: Verbose description
- type: textarea
id: files
attributes:
label: Attached files
description: Screenshots, screencasts, dolibarr.log, debugging informations

View File

@ -1,27 +0,0 @@
---
name: Feature request
about: Suggest a new idea for this project
title: ''
labels: Feature request
assignees: ''
---
# Instructions
*This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report.*
*Please:*
- *replace the bracket enclosed texts with meaningful information*
- *remove any unused sub-section*
# Feature Request
[*Short description*]
## Use case
[*Verbose description*]
## Suggested implementation
[*Verbose description*]
## Suggested steps
[*List of tasks to achieve goal*]

View File

@ -0,0 +1,35 @@
name: Feature request
description: Suggest a new idea for this project
labels: ["Feature request"]
body:
- type: markdown
attributes:
value: |
This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report.
- type: textarea
id: feature-request
attributes:
label: Feature Request
description: Short description
validations:
required: true
- type: textarea
id: use-case
attributes:
label: Use case
description: Verbose description
- type: textarea
id: suggested-implementation
attributes:
label: Suggested implementation
description: Verbose description
- type: textarea
id: suggested-steps
attributes:
label: Suggested steps
description: List of tasks to achieve goal

View File

@ -50,14 +50,14 @@ jobs:
env: DB=postgresql env: DB=postgresql
- stage: PHP 5.6-7.4 - stage: PHP 5.6-7.4
if: type = pull_request OR type = push if: type = pull_request OR type = push
php: '7.4' php: '7.4.22'
env: DB=mysql env: DB=mysql
- stage: PHP Dev - stage: PHP Dev
if: type = push AND branch = develop if: type = push AND branch = develop
php: nightly php: nightly
env: DB=mysql env: DB=mysql
- stage: PHP Dev - stage: PHP Dev
if: type = push AND branch = 14.0 if: type = push AND branch = 15.0
php: nightly php: nightly
env: DB=mysql env: DB=mysql
@ -106,7 +106,7 @@ install:
php-parallel-lint/php-console-highlighter ^0 \ php-parallel-lint/php-console-highlighter ^0 \
squizlabs/php_codesniffer ^3 squizlabs/php_codesniffer ^3
fi fi
if [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ]; then if [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ] || [ "$TRAVIS_PHP_VERSION" = '7.4.22' ]; then
composer -n require phpunit/phpunit ^7 \ composer -n require phpunit/phpunit ^7 \
php-parallel-lint/php-parallel-lint ^1.2 \ php-parallel-lint/php-parallel-lint ^1.2 \
php-parallel-lint/php-console-highlighter ^0 \ php-parallel-lint/php-console-highlighter ^0 \
@ -241,7 +241,7 @@ before_script:
# enable php-fpm # enable php-fpm
- sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf - sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
- | - |
if [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] || [ "$TRAVIS_PHP_VERSION" = '7.2' ] || [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then if [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] || [ "$TRAVIS_PHP_VERSION" = '7.2' ] || [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ] || [ "$TRAVIS_PHP_VERSION" = '7.4.22' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then
# Copy the included pool # Copy the included pool
sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf
fi fi
@ -276,7 +276,7 @@ script:
set -e set -e
#parallel-lint --exclude htdocs/includes --blame . #parallel-lint --exclude htdocs/includes --blame .
# Exclusions are defined in the ruleset.xml file # Exclusions are defined in the ruleset.xml file
if [ "$TRAVIS_PHP_VERSION" = "7.4" ]; then if [ "$TRAVIS_PHP_VERSION" = "7.4.22" ]; then
parallel-lint -e php --exclude dev/tools/test/namespacemig --exclude htdocs/includes/composer --exclude htdocs/includes/myclabs --exclude htdocs/includes/phpspec --exclude dev/initdata/dbf/includes \ parallel-lint -e php --exclude dev/tools/test/namespacemig --exclude htdocs/includes/composer --exclude htdocs/includes/myclabs --exclude htdocs/includes/phpspec --exclude dev/initdata/dbf/includes \
--exclude htdocs/includes/sabre --exclude htdocs/includes/phpoffice/PhpSpreadsheet --exclude htdocs/includes/sebastian \ --exclude htdocs/includes/sabre --exclude htdocs/includes/phpoffice/PhpSpreadsheet --exclude htdocs/includes/sebastian \
--exclude htdocs/includes/squizlabs/php_codesniffer --exclude htdocs/includes/jakub-onderka --exclude htdocs/includes/php-parallel-lint --exclude htdocs/includes/symfony \ --exclude htdocs/includes/squizlabs/php_codesniffer --exclude htdocs/includes/jakub-onderka --exclude htdocs/includes/php-parallel-lint --exclude htdocs/includes/symfony \
@ -291,7 +291,7 @@ script:
# Ensure we catch errors # Ensure we catch errors
set -e set -e
# Exclusions are defined in the ruleset.xml file # Exclusions are defined in the ruleset.xml file
if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_PHP_VERSION" = "7.4" ]; then if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_PHP_VERSION" = "7.4.22" ]; then
phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .; phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .;
fi fi
set +e set +e
@ -411,6 +411,12 @@ script:
php upgrade.php 13.0.0 14.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade13001400.log php upgrade.php 13.0.0 14.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade13001400.log
php upgrade2.php 13.0.0 14.0.0 > $TRAVIS_BUILD_DIR/upgrade13001400-2.log php upgrade2.php 13.0.0 14.0.0 > $TRAVIS_BUILD_DIR/upgrade13001400-2.log
php step5.php 13.0.0 14.0.0 > $TRAVIS_BUILD_DIR/upgrade13001400-3.log php step5.php 13.0.0 14.0.0 > $TRAVIS_BUILD_DIR/upgrade13001400-3.log
php upgrade.php 14.0.0 15.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade14001500.log
php upgrade2.php 14.0.0 15.0.0 > $TRAVIS_BUILD_DIR/upgrade14001500-2.log
php step5.php 14.0.0 15.0.0 > $TRAVIS_BUILD_DIR/upgrade14001500-3.log
php upgrade.php 15.0.0 16.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade15001600.log
php upgrade2.php 15.0.0 16.0.0 > $TRAVIS_BUILD_DIR/upgrade15001600-2.log
php step5.php 15.0.0 16.0.0 > $TRAVIS_BUILD_DIR/upgrade15001600-3.log
ls -alrt $TRAVIS_BUILD_DIR/ ls -alrt $TRAVIS_BUILD_DIR/
- | - |

View File

@ -28,7 +28,7 @@ CKEditor 4.12.1 LGPL-2.1+ Yes
EvalMath 1.0 BSD Yes Safe math expressions evaluation EvalMath 1.0 BSD Yes Safe math expressions evaluation
Escpos-php 2.2 MIT License Yes Thermal receipt printer library, for use with ESC/POS compatible printers Escpos-php 2.2 MIT License Yes Thermal receipt printer library, for use with ESC/POS compatible printers
GeoIP2 0.2.0 Apache License 2.0 Yes Lib to make geoip convert GeoIP2 0.2.0 Apache License 2.0 Yes Lib to make geoip convert
Mobiledetect 2.8.34 MIT License Yes Detect mobile devices browsers Mobiledetect 2.8.39 MIT License Yes Detect mobile devices browsers
NuSoap 0.9.5 LGPL 2.1+ Yes Library to develop SOAP Web services (not into rpm and deb package) NuSoap 0.9.5 LGPL 2.1+ Yes Library to develop SOAP Web services (not into rpm and deb package)
PEAR Mail_MIME 1.8.9 BSD Yes NuSoap dependency PEAR Mail_MIME 1.8.9 BSD Yes NuSoap dependency
ParseDown 1.6 MIT License Yes Markdown parser ParseDown 1.6 MIT License Yes Markdown parser
@ -48,10 +48,10 @@ TCPDF 6.3.2 LGPL-3+ Yes
TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes FPDI replacement TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes FPDI replacement
JS libraries: JS libraries:
Ace 1.4.8 BSD Yes JS library to get code syntaxique coloration in a textarea. Ace 1.4.14 BSD Yes JS library to get code syntaxique coloration in a textarea.
ChartJS 2.9.4 MIT License Yes JS library for graph ChartJS 3.7.1 MIT License Yes JS library for graph
jQuery 3.5.1 MIT License Yes JS library jQuery 3.6.0 MIT License Yes JS library
jQuery UI 1.12.1 GPL and MIT License Yes JS library plugin UI jQuery UI 1.13.1 GPL and MIT License Yes JS library plugin UI
jQuery select2 4.0.13 GPL and Apache License Yes JS library plugin for sexier multiselect. Warning: 4.0.6+ create troubles without patching css jQuery select2 4.0.13 GPL and Apache License Yes JS library plugin for sexier multiselect. Warning: 4.0.6+ create troubles without patching css
jQuery blockUI 2.70.0 GPL and MIT License Yes JS library plugin blockUI (to use ajax popups) 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 Colorpicker 1.1 MIT License Yes JS library for color picker for a defined list of colors

121
ChangeLog
View File

@ -3,6 +3,67 @@ English Dolibarr ChangeLog
-------------------------------------------------------------- --------------------------------------------------------------
***** ChangeLog for 16.0.0 compared to 15.0.0 *****
For users:
---------------
NEW: PHP 8.0 compatibility
Modules
NEW: Experimental module Event Organization Management
NEW: Experimental module Workstations Management
NEW: Experimental module Partnership Management
For developers:
---------------
NEW: A lot of addition of hooks.
Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
* The default value for MAIN_SECURITY_CSRF_WITH_TOKEN has been set to 2. It means any POST and any GET request that contains the "action" or "massaction"
with a value of a sensitive action must also a valid token parameter (With previous value 1, only POST was concerned). Note: With value 3, any URL
with parameter "action" or "massaction" need the token, whatever is the value of the action.
* verifCond('stringtoevaluate') now return false when string contains a bad syntax content instead of true.
* The deprecated method thirdparty_doc_create() has been removed. You can use the generateDocument() instead.
* All triggers with a name XXX_UPDATE have been rename with name XXX_MODIFY for code consistency purpose.
* Rename build_path_from_id_categ() into buildPathFromId() and set method to private
***** ChangeLog for 15.0.1 compared to 15.0.0 *****
FIX: #19777 #20281
FIX: bad position of extrafields for interventions
FIX: Blocking situation when a payment was deleted in bank.
FIX: creation of the shipment if order contains services
FIX: Drag and drop line of files on join files tab
FIX: Error management on mass action "Approve holiday"
FIX: error with php8
FIX: in case of VAT refund, negative amount must be allowed
FIX: invoice pdf: lines originating from deposits were not detailed anymore
FIX: Invoice - When you create an invoice for a given thirdparty, fk_account is not retrieved from company card
FIX: list of visible type of event was not correctly filtered
FIX: Missing or bad permissions
FIX: Missing the field date start/end in export supplier invoice/order
FIX: On large proposal or invoice, fix n(n+1) sql into a n sql.
FIX: options should not exists on invoices
FIX: payment not completed when using Paypal.
FIX: permission to download files of expense report with readall.
FIX- Preview icon in documents list PDF in the admin page third-party
FIX: shipping list, e.shipping_method_id should be e.fk_shipping_method.
FIX: Show product photo on Supplier order Cornas model.
FIX: User name in ManufacturingOrder
FIX: viewimage.php blocks requests with multicompany from other enties
FIX: #yogosha9048
FIX: #yogosha9054
FIX: #yogosha9095
***** ChangeLog for 15.0.0 compared to 14.0.0 ***** ***** ChangeLog for 15.0.0 compared to 14.0.0 *****
For users: For users:
@ -10,12 +71,12 @@ For users:
NEW: Online proposal signature NEW: Online proposal signature
NEW: Can define some max limit on expense report (per period, per type or expense, ...) NEW: Can define some max limit on expense report (per period, per type or expense, ...)
NEW: Provide a special pages for bookmarks and multicompany for a better use of some mobile applications (like DoliDroid)
NEW: Allow the use of __NEWREF__ to get for example the new reference a draft order will get after validation. NEW: Allow the use of __NEWREF__ to get for example the new reference a draft order will get after validation.
NEW: Add option to disable globaly some notifications emails. NEW: Add option to disable globaly some notifications emails.
NEW: #18326 Workflow: Close order on shipment closing.
NEW: #18401 Add __NEWREF__ subtitute to get new object reference. NEW: #18401 Add __NEWREF__ subtitute to get new object reference.
NEW: #18403 Add __URL_SHIPMENT__ substitute to get the URL of a shipment NEW: #18403 Add __URL_SHIPMENT__ substitute to get the URL of a shipment
NEW: #18689 REST API module: add api key generate / modify right. NEW: #18689 REST API module: add api key generate / modify permission.
NEW: #18663 Make "L'Annuaire des Entreprises" the default provider for SIREN verification for French thirdparties. NEW: #18663 Make "L'Annuaire des Entreprises" the default provider for SIREN verification for French thirdparties.
NEW: #18046 Add tags on ticket/categories NEW: #18046 Add tags on ticket/categories
NEW: #18326 Workflow: Close order on shipment closing. NEW: #18326 Workflow: Close order on shipment closing.
@ -106,6 +167,14 @@ NEW: when multiple order linked to facture, show list into note.
NEW: when we delete several objects with massaction, if somes object has child we must see which objects are concerned and nevertheless delete objects which can be deleted NEW: when we delete several objects with massaction, if somes object has child we must see which objects are concerned and nevertheless delete objects which can be deleted
NEW: Editing a page in website module keep old page with name .back NEW: Editing a page in website module keep old page with name .back
NEW: External backups can be downloaded from the "About info page". NEW: External backups can be downloaded from the "About info page".
NEW: Add massaction to switch status on sale / on purchase of a product.
Modules
NEW: Stable module Knowledge Management
NEW: Experimental module Event Organization Management
NEW: Experimental module Workstations Management
NEW: Development of module Partnership Management
For developers: For developers:
@ -115,6 +184,7 @@ NEW: Introduce method hasRight
NEW: Can use textarea field into a confirm popup. NEW: Can use textarea field into a confirm popup.
NEW: Can use the result_mode of mysqli driver. Save memory for list count NEW: Can use the result_mode of mysqli driver. Save memory for list count
NEW: #18319 REST API - Shipment: Add 'close' action / endpoint / POST method. NEW: #18319 REST API - Shipment: Add 'close' action / endpoint / POST method.
NEW: Add API /approve and /makeOrder for purchase orders.
NEW: add action trigger for member excluded NEW: add action trigger for member excluded
NEW: add option MAIN_IBAN_IS_NEVER_MANDATORY, MAIN_IBAN_NOT_MANDATORY, PROPAL_NOT_BILLABLE, PROPAL_REOPEN_UNSIGNED_ONLY, PROPOSAL_ARE_NOT_BILLABLE, TICKETS_MESSAGE_FORCE_MAIL NEW: add option MAIN_IBAN_IS_NEVER_MANDATORY, MAIN_IBAN_NOT_MANDATORY, PROPAL_NOT_BILLABLE, PROPAL_REOPEN_UNSIGNED_ONLY, PROPOSAL_ARE_NOT_BILLABLE, TICKETS_MESSAGE_FORCE_MAIL
NEW: Add code codebar column on serial/lot structure NEW: Add code codebar column on serial/lot structure
@ -132,10 +202,13 @@ NEW: printFieldListFrom hook call on several lists
NEW: Use lang selector when using a field key 'lang' in modulebuilder NEW: Use lang selector when using a field key 'lang' in modulebuilder
NEW: we need to be able to put more filters on deleteByParentField() function NEW: we need to be able to put more filters on deleteByParentField() function
NEW: make it easier to set the `keyword`, `keywords` and `description` attributes of an ecm file object NEW: make it easier to set the `keyword`, `keywords` and `description` attributes of an ecm file object
NEW: Experimental feature to manage user sessions in database
NEW: Hidden option API_DISABLE_COMPRESSION is now visible in API setup page.
NEW: Add hook printUnderHeaderPDFline on invoice PDF templates (can be used for example to add a barcode or more information on header of invoices).
Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
* ALL EXTERNAL MODULES THAT WERE NOT CORRECTLY DEVELOPPED WILL NOT WORK ON V15 (All modules that forgot to manage the security token field
into forms will be broken. The security token field is expected since Dolibarr v9 but a lot of external modules did not implement it).
* Update hook 'printOriginObjectLine', removed check on product type and special code. Need now reshook. * Update hook 'printOriginObjectLine', removed check on product type and special code. Need now reshook.
* Old deprecated module "SimplePOS" has been completely removed. Use module "TakePOS" is you need a Point Of Sale. * Old deprecated module "SimplePOS" has been completely removed. Use module "TakePOS" is you need a Point Of Sale.
* The method static ActionComm::getActions($db, ...) is no more static. Use $actioncomm->getActions(...) instead (without $db param). * The method static ActionComm::getActions($db, ...) is no more static. Use $actioncomm->getActions(...) instead (without $db param).
@ -143,8 +216,48 @@ Following changes may create regressions for some external modules, but were nec
* Method getDictvalue has been renamed into getDictionaryValue to match camel case rule. * Method getDictvalue has been renamed into getDictionaryValue to match camel case rule.
* To execute shell or command line command, your code must never use method like exec, shell_exec, popen, .. but must use the built-in * To execute shell or command line command, your code must never use method like exec, shell_exec, popen, .. but must use the built-in
method executeCLI() available into core/class/utils.class.php method executeCLI() available into core/class/utils.class.php
* Class file expeditionbatch.class.php renamed to expeditionlinebatch.class.php
* ExpeditionLineBatch::fetchAll is not static anymore and first parameter $db is removed
* ExtraFields->showOutputField parameter 4 'extrafieldsobjectkey' is now required
* CommonObject method add_object_linked now sets targettype to 'mymodule_myobject' instead of 'myobject',
you can use hook 'setLinkedObjectSourceTargetType' to set your usual targettype
***** ChangeLog for 14.0.5 compared to 14.0.4 *****
FIX: 13.0: printFieldListWhere called twice on same query
FIX: 14.0.4 fatal error on cron list.
FIX: #19476
FIX: #19564
FIX: #19651
FIX: Accountancy - SQL error on subledger account search in journal
FIX: apply eldy's suggestion to not overwrite existing extrafields of $line
FIX: Can't close a down payment if paid with credit notes.
FIX: better compatibility with multicompany
FIX: contact card: bad colspan value for separator extrafield in creation/modification form
FIX: discounts are applied both when fetching the best supplier price and when displaying it
FIX: double display for contact categorie on societe create card
FIX: fatal error on cron list.
FIX: holiday list: only mass delete if leave request is not in draft, canceled or refused, like in card
FIX: holiday mass deletion: correct return of record deleted
FIX: Holiday month report
FIX: info tab on customer invoice record not found
FIX: line extrafields are inoperative in dispatch cards even when they exist
FIX: list of categories in stats of supplier invoices
FIX: missing default value for more comprehensive
FIX: multicurrency: fields in discount unitialized when creating deposit
FIX: Navigation on bank transaction list
FIX: Can't edit a bank transaction due to bad permission check.
FIX: Option MAIN_DIRECT_STATUS_UPDATE broken. Ajax on/off not saving value in DB after updating to version >=12
FIX: postgresql compatibility, "" as is not authorized
FIX: printFieldListWhere called twice (at different locations) for the same SQL query, can result in syntax errors
FIX: select too large into addrights (pb of missing parenthesis)
FIX: set optional from post, we can't untick boolean field on product card
FIX: Take into consideration work leave over serveral months
FIX: test if method exist on wrong object
FIX: title for nature of third party in company list
FIX: Urgent onglet contact inaccessible depuis une facture
FIX: wrong syntax of sql request
***** ChangeLog for 14.0.4 compared to 14.0.3 ***** ***** ChangeLog for 14.0.4 compared to 14.0.3 *****

View File

@ -4,6 +4,7 @@
![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/develop.svg) ![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/develop.svg)
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%205.6-8892BF.svg?style=flat-square)](https://php.net/) [![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%205.6-8892BF.svg?style=flat-square)](https://php.net/)
[![GitHub release](https://img.shields.io/github/v/release/Dolibarr/dolibarr)](https://github.com/Dolibarr/dolibarr) [![GitHub release](https://img.shields.io/github/v/release/Dolibarr/dolibarr)](https://github.com/Dolibarr/dolibarr)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5521/badge)](https://bestpractices.coreinfrastructure.org/projects/5521)
Dolibarr ERP & CRM is a modern software package that helps manage your organization's activity (contacts, suppliers, invoices, orders, stocks, agenda…). Dolibarr ERP & CRM is a modern software package that helps manage your organization's activity (contacts, suppliers, invoices, orders, stocks, agenda…).

View File

@ -6,17 +6,18 @@ This file contains some policies about the security reports on Dolibarr ERP CRM
| Version | Supported | | Version | Supported |
| ---------- | ---------------------- | | ---------- | ---------------------- |
| <= 14.0.1 | :x: | | <= 14.0.4 | :x: |
| >= 14.0.2+ | :white_check_mark: except CSRF attacks| | >= 14.0.5+ | :white_check_mark: except CSRF attacks|
| >= develop | :white_check_mark: | | >= develop | :white_check_mark: |
## Reporting a Vulnerability ## Reporting a Vulnerability
To report a vulnerability, please use GitHub security advisory at [https://github.com/Dolibarr/dolibarr/security/advisories/new](https://github.com/Dolibarr/dolibarr/security/advisories/new) (if you have permissions) or alternatively send an email to security@dolibarr.org (for everybody) To report a vulnerability, for a private report, please use GitHub security advisory at [https://github.com/Dolibarr/dolibarr/security/advisories/new](https://github.com/Dolibarr/dolibarr/security/advisories/new) (if you have permissions).
Alternatively send an email to security@dolibarr.org (for everybody)
## Hunting vulnerabilities on Dolibarr ## Hunting vulnerabilities on Dolibarr
We believe that future of software is online SaaS. This means software are more and more critical and no technology is perfect. Working with skilled security researchers is crucial in identifying weaknesses in our technology. We believe that the future of software is online SaaS. This means software are more and more critical and no technology is perfect. Working with skilled security researchers is crucial in identifying weaknesses in our technology.
If you believe you've found a security bug in our service, we are happy to work with you to resolve the issue promptly and ensure you are fairly rewarded for your discovery. If you believe you've found a security bug in our service, we are happy to work with you to resolve the issue promptly and ensure you are fairly rewarded for your discovery.
@ -34,13 +35,13 @@ You can install the web application yourself on your own platform/server so you
## Eligibility and Responsible Disclosure ## Eligibility and Responsible Disclosure
We are happy to thank everyone who submits valid reports which help us improve the security of Dolibarr however, only those that meet the following eligibility requirements will be "validated reports" (if not, we may close the report without any answer): We are happy to thank everyone who submits valid reports which help us improve the security of Dolibarr, however only those that meet the following eligibility requirements will be "validated reports" (if not, we may close the report without any answer):
You must be the first reporter of the vulnerability (duplicate reports are closed). You must be the first reporter of the vulnerability (duplicate reports are closed).
You must send a clear textual description of the report along with steps to reproduce the issue, include attachments such as screenshots or proof of concept code as necessary. You must send a clear textual description of the report along with steps to reproduce the issue, include attachments such as screenshots or proof of concept code as necessary.
You must avoid tests that could cause degradation or interruption of our service (refrain from using automated tools, and limit yourself about requests per second), that's why we recommand to install softwate on your own platform. You must avoid tests that could cause degradation or interruption of our service (refrain from using automated tools, and limit yourself about requests per second), that's why we recommand to install software on your own platform.
You must not leak, manipulate, or destroy any user data of third parties to find your vulnerability. You must not leak, manipulate, or destroy any user data of third parties to find your vulnerability.
@ -55,7 +56,7 @@ ONLY vulnerabilities discovered, when the following setup on test platform is us
* The module DebugBar and ModuleBuilder must NOT be enabled (by default, these modules are not enabled. They are developer tools) * The module DebugBar and ModuleBuilder must NOT be enabled (by default, these modules are not enabled. They are developer tools)
* ONLY security reports on modules provided by default and with the "stable" status are valid (troubles into "experimental", "developement" or external modules are not valid vulnerabilities). * ONLY security reports on modules provided by default and with the "stable" status are valid (troubles into "experimental", "developement" or external modules are not valid vulnerabilities).
* The root of web server must link to htdocs and the documents directory must be outside of the web server root (this is the default when using the default installer but may differs with external installer). * The root of web server must link to htdocs and the documents directory must be outside of the web server root (this is the default when using the default installer but may differs with external installer).
* The web server setup must be done so only the documents directory is in write mode. The root directory called htdocs must be readonly. * The web server setup must be done so that only the documents directory is in write mode. The root directory called htdocs must be read-only.
* CSRF attacks are accepted but double check that you have set MAIN_SECURITY_CSRF_WITH_TOKEN to value 3. * CSRF attacks are accepted but double check that you have set MAIN_SECURITY_CSRF_WITH_TOKEN to value 3.
* Ability for a high level user to edit web site pages into the CMS by including HTML or Javascript is an expected feature. Vulnerabilities into the website module are validated only if HTML or Javascript injection can be done by a non allowed user. * Ability for a high level user to edit web site pages into the CMS by including HTML or Javascript is an expected feature. Vulnerabilities into the website module are validated only if HTML or Javascript injection can be done by a non allowed user.
@ -66,7 +67,7 @@ Scope is the web application (back office) and the APIs.
* Remote code execution (RCE) * Remote code execution (RCE)
* Local files access and manipulation (LFI, RFI, XXE, SSRF, XSPA) * Local files access and manipulation (LFI, RFI, XXE, SSRF, XSPA)
* Code injections (HTML, JS, SQL, PHP, ...) * Code injections (HTML, JS, SQL, PHP, ...)
* Cross-Site Scripting (XSS), except from setup page of module "External web site" (allowing any content here, editable by admin user only, is accepted on purpose or into module "Web site" when permission to edit website content is allowed). * Cross-Site Scripting (XSS), except from setup page of module "External web site" (allowing any content here, editable by admin user only, is accepted on purpose) and except into module "Web site" when permission to edit website content is allowed (injecting any data in this case is allowed too).
* Cross-Site Requests Forgery (CSRF) with real security impact (when using GET URLs, CSRF are qualified only for creating, updating or deleting data from pages restricted to admin users) * Cross-Site Requests Forgery (CSRF) with real security impact (when using GET URLs, CSRF are qualified only for creating, updating or deleting data from pages restricted to admin users)
* Open redirect * Open redirect
* Broken authentication & session management * Broken authentication & session management

View File

@ -39,15 +39,13 @@ RUN chmod +x /usr/local/bin/docker-run.sh
RUN pecl install xdebug && docker-php-ext-enable xdebug RUN pecl install xdebug && docker-php-ext-enable xdebug
RUN echo 'zend_extension="/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so"' >> ${PHP_INI_DIR}/php.ini RUN echo 'zend_extension="/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so"' >> ${PHP_INI_DIR}/php.ini
RUN echo 'xdebug.remote_autostart=1' >> ${PHP_INI_DIR}/php.ini RUN echo 'xdebug.mode=debug' >> ${PHP_INI_DIR}/php.ini
RUN echo 'xdebug.remote_enable=1' >> ${PHP_INI_DIR}/php.ini RUN echo 'xdebug.start_with_request=yes' >> ${PHP_INI_DIR}/php.ini
RUN echo 'xdebug.default_enable=1' >> ${PHP_INI_DIR}/php.ini RUN echo 'xdebug.client_host=host.docker.internal' >> ${PHP_INI_DIR}/php.ini
#RUN echo 'xdebug.remote_host=docker.host' >> ${PHP_INI_DIR}/php.ini RUN echo 'xdebug.client_port=9003' >> ${PHP_INI_DIR}/php.ini
RUN echo 'xdebug.remote_port=9000' >> ${PHP_INI_DIR}/php.ini RUN echo 'xdebug.discover_client_host=true' >> ${PHP_INI_DIR}/php.ini
RUN echo 'xdebug.remote_connect_back=1' >> ${PHP_INI_DIR}/php.ini #RUN echo 'xdebug.log="/tmp/xdebug.log"' >> ${PHP_INI_DIR}/php.ini
RUN echo 'xdebug.profiler_enable=0' >> ${PHP_INI_DIR}/php.ini RUN echo 'xdebug.idekey="netbeans-xdebug"' >> ${PHP_INI_DIR}/php.ini
RUN echo 'xdebug.remote_log="/tmp/xdebug.log"' >> ${PHP_INI_DIR}/php.ini
#RUN echo 'localhost docker.host' >> /etc/hosts
# set up sendmail config, to use maildev # set up sendmail config, to use maildev
RUN echo "account default" > /etc/msmtprc RUN echo "account default" > /etc/msmtprc

View File

@ -48,6 +48,7 @@ services:
- external-pod - external-pod
extra_hosts: extra_hosts:
- "localhost.localdomain:127.0.0.1" - "localhost.localdomain:127.0.0.1"
- "host.docker.internal:host-gateway"
mail: mail:
image: maildev/maildev image: maildev/maildev

View File

@ -1,6 +1,7 @@
README (English) README (English)
################################################## ##################################################
Building PAD files Building PAD files
http://pad.asp-software.org/padgen.php
################################################## ##################################################
This directory contains files and docs used to build This directory contains files and docs used to build

View File

@ -30,7 +30,7 @@ return "Regis Houssin";
# script_dolibarr_versions() # script_dolibarr_versions()
sub script_dolibarr_versions sub script_dolibarr_versions
{ {
return ( "12.0.3", "11.0.5", "10.0.7", "9.0.4", "8.0.6", "7.0.5" ); return ( "14.0.5", "13.0.5", "12.0.5", "11.0.5", "10.0.7", "9.0.4", "8.0.6", "7.0.5" );
} }
sub script_dolibarr_release sub script_dolibarr_release
@ -400,6 +400,8 @@ sub script_dolibarr_check_latest
{ {
local ($ver) = @_; local ($ver) = @_;
local @vers = &osdn_package_versions("dolibarr", local @vers = &osdn_package_versions("dolibarr",
$ver >= 14.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 13.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 12.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" : $ver >= 12.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 11.0 ? "dolibarr\\-(11\\.0\\.[0-9\\.]+)\\.tgz" : $ver >= 11.0 ? "dolibarr\\-(11\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 10.0 ? "dolibarr\\-(10\\.0\\.[0-9\\.]+)\\.tgz" : $ver >= 10.0 ? "dolibarr\\-(10\\.0\\.[0-9\\.]+)\\.tgz" :

View File

@ -166,7 +166,6 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/blockedlog %_datadir/dolibarr/htdocs/blockedlog
%_datadir/dolibarr/htdocs/bookmarks %_datadir/dolibarr/htdocs/bookmarks
%_datadir/dolibarr/htdocs/bom %_datadir/dolibarr/htdocs/bom
%_datadir/dolibarr/htdocs/cashdesk
%_datadir/dolibarr/htdocs/categories %_datadir/dolibarr/htdocs/categories
%_datadir/dolibarr/htdocs/collab %_datadir/dolibarr/htdocs/collab
%_datadir/dolibarr/htdocs/comm %_datadir/dolibarr/htdocs/comm

View File

@ -247,7 +247,6 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/blockedlog %_datadir/dolibarr/htdocs/blockedlog
%_datadir/dolibarr/htdocs/bookmarks %_datadir/dolibarr/htdocs/bookmarks
%_datadir/dolibarr/htdocs/bom %_datadir/dolibarr/htdocs/bom
%_datadir/dolibarr/htdocs/cashdesk
%_datadir/dolibarr/htdocs/categories %_datadir/dolibarr/htdocs/categories
%_datadir/dolibarr/htdocs/collab %_datadir/dolibarr/htdocs/collab
%_datadir/dolibarr/htdocs/comm %_datadir/dolibarr/htdocs/comm

View File

@ -163,7 +163,6 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/blockedlog %_datadir/dolibarr/htdocs/blockedlog
%_datadir/dolibarr/htdocs/bookmarks %_datadir/dolibarr/htdocs/bookmarks
%_datadir/dolibarr/htdocs/bom %_datadir/dolibarr/htdocs/bom
%_datadir/dolibarr/htdocs/cashdesk
%_datadir/dolibarr/htdocs/categories %_datadir/dolibarr/htdocs/categories
%_datadir/dolibarr/htdocs/collab %_datadir/dolibarr/htdocs/collab
%_datadir/dolibarr/htdocs/comm %_datadir/dolibarr/htdocs/comm

View File

@ -174,7 +174,6 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/blockedlog %_datadir/dolibarr/htdocs/blockedlog
%_datadir/dolibarr/htdocs/bookmarks %_datadir/dolibarr/htdocs/bookmarks
%_datadir/dolibarr/htdocs/bom %_datadir/dolibarr/htdocs/bom
%_datadir/dolibarr/htdocs/cashdesk
%_datadir/dolibarr/htdocs/categories %_datadir/dolibarr/htdocs/categories
%_datadir/dolibarr/htdocs/collab %_datadir/dolibarr/htdocs/collab
%_datadir/dolibarr/htdocs/comm %_datadir/dolibarr/htdocs/comm

View File

@ -28,7 +28,7 @@
"ext-curl" : "*", "ext-curl" : "*",
"ckeditor/ckeditor" : "4.12.1", "ckeditor/ckeditor" : "4.12.1",
"mike42/escpos-php" : "2.2", "mike42/escpos-php" : "2.2",
"mobiledetect/mobiledetectlib" : "2.8.34", "mobiledetect/mobiledetectlib" : "2.8.39",
"phpoffice/phpexcel" : "1.8.2", "phpoffice/phpexcel" : "1.8.2",
"restler/framework" : "3.0.0-RC6", "restler/framework" : "3.0.0-RC6",
"tecnickcom/tcpdf" : "6.3.2", "tecnickcom/tcpdf" : "6.3.2",

2349
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -111,6 +111,10 @@ with
// DOL CHANGE If we keep this, the image is not visible on pages after the first one. // DOL CHANGE If we keep this, the image is not visible on pages after the first one.
//var_dump($file.' '.(!@TCPDF_STATIC::file_exists($file))); //var_dump($file.' '.(!@TCPDF_STATIC::file_exists($file)));
//return false; //return false;
$tfile = str_replace(' ', '%20', $file);
if (@TCPDF_STATIC::file_exists($tfile)) {
$file = $tfile;
}
} }
* Replace in tcpdf.php * Replace in tcpdf.php
@ -205,6 +209,8 @@ with
with with
foreach ($value[1] as $k => $v) { foreach ($value[1] as $k => $v) {
JSGANTT: JSGANTT:
-------- --------
* Replace in function JSGantt.taskLink * Replace in function JSGantt.taskLink
@ -233,11 +239,13 @@ JCROP:
* Remove analytics tag into file index.html * Remove analytics tag into file index.html
JQUERYFILETREE: JQUERYFILETREE:
--------------- ---------------
* Remove directory htdocs/includes/jquery/plugins/jqueryFileTree/connectors * Remove directory htdocs/includes/jquery/plugins/jqueryFileTree/connectors
RESTLER: RESTLER:
-------- --------

View File

@ -5,4 +5,4 @@ This directory contains samples of code to use Dolibarr business classes to buil
external interfaces that need to read/update data from/into Dolibarr. external interfaces that need to read/update data from/into Dolibarr.
You can also have a look at the Dolibarr doxygen doc that describes all files and classes: You can also have a look at the Dolibarr doxygen doc that describes all files and classes:
http://www.dolibarr.org/html_doxygen/index.html https://doxygen.dolibarr.org/

View File

@ -15,7 +15,7 @@
"npm": ">=5.6.0" "npm": ">=5.6.0"
}, },
"dependencies": { "dependencies": {
"zapier-platform-core": "11.0.1" "zapier-platform-core": "11.3.1"
}, },
"devDependencies": { "devDependencies": {
"mocha": "^5.2.0", "mocha": "^5.2.0",

View File

@ -132,7 +132,7 @@ then
fichtemp=`tempfile 2>/dev/null` || fichtemp=/tmp/test$$ fichtemp=`tempfile 2>/dev/null` || fichtemp=/tmp/test$$
trap "rm -f $fichtemp" 0 1 2 5 15 trap "rm -f $fichtemp" 0 1 2 5 15
$DIALOG --title "Init Dolibarr with demo values" --clear \ $DIALOG --title "Init Dolibarr with demo values" --clear \
--inputbox "Password for Mysql user login :" 16 55 2> $fichtemp --passwordbox "Password for Mysql user login :" 16 55 2> $fichtemp
valret=$? valret=$?
@ -153,7 +153,7 @@ then
# ---------------------------- confirmation # ---------------------------- confirmation
DIALOG=${DIALOG=dialog} DIALOG=${DIALOG=dialog}
$DIALOG --title "Init Dolibarr with demo values" --clear \ $DIALOG --title "Init Dolibarr with demo values" --clear \
--yesno "Do you confirm ? \n Dump file : '$dumpfile' \n Dump dir : '$mydir' \n Document dir : '$documentdir' \n Mysql database : '$base' \n Mysql port : '$port' \n Mysql login: '$admin' \n Mysql password : '$passwd'" 15 55 --yesno "Do you confirm ? \n Dump file : '$dumpfile' \n Dump dir : '$mydir' \n Document dir : '$documentdir' \n Mysql database : '$base' \n Mysql port : '$port' \n Mysql login: '$admin' \n Mysql password : --hidden--" 15 55
case $? in case $? in
0) echo "Ok, start process...";; 0) echo "Ok, start process...";;

File diff suppressed because one or more lines are too long

View File

@ -116,7 +116,7 @@ then
fichtemp=`tempfile 2>/dev/null` || fichtemp=/tmp/test$$ fichtemp=`tempfile 2>/dev/null` || fichtemp=/tmp/test$$
trap "rm -f $fichtemp" 0 1 2 5 15 trap "rm -f $fichtemp" 0 1 2 5 15
$DIALOG --title "Save Dolibarr with demo values" --clear \ $DIALOG --title "Save Dolibarr with demo values" --clear \
--inputbox "Password for Mysql root login :" 16 55 2> $fichtemp --passwordbox "Password for Mysql root login :" 16 55 2> $fichtemp
valret=$? valret=$?
@ -150,7 +150,7 @@ then
# ---------------------------- confirmation # ---------------------------- confirmation
DIALOG=${DIALOG=dialog} DIALOG=${DIALOG=dialog}
$DIALOG --title "Save Dolibarr with demo values" --clear \ $DIALOG --title "Save Dolibarr with demo values" --clear \
--yesno "Do you confirm ? \n Dump file : '$dumpfile' \n Dump dir : '$mydir' \n Mysql database : '$base' \n Mysql port : '$port' \n Mysql login: '$admin' \n Mysql password : '$passwd'" 15 55 --yesno "Do you confirm ? \n Dump file : '$dumpfile' \n Dump dir : '$mydir' \n Mysql database : '$base' \n Mysql port : '$port' \n Mysql login: '$admin' \n Mysql password : --hidden--" 15 55
case $? in case $? in
0) echo "Ok, start process...";; 0) echo "Ok, start process...";;

View File

@ -0,0 +1,17 @@
List of QR Code format we found on some invoices
------------------------------------------------
* For SEPA QR payment Code format (Europe)
------------------------------------------
https://en.wikipedia.org/wiki/EPC_QR_code#Generators
* For ZATCA QR Code format (Saudi Arabia). Used when INVOICE_ADD_ZATCA_QR_CODE is set
-------------------------------------------------------------------------------------
https://www.pwc.com/m1/en/services/tax/me-tax-legal-news/2021/saudi-arabia-guide-to-develop-compliant-qr-code-for-simplified-einvoices.html
https://www.tecklenborgh.com/post/ksa-zatca-publishes-guide-on-how-to-develop-a-fatoora-compliant-qr-code
Method to encode/decode ZATCA string is available in test/phpunit/BarcodeTest.php

View File

@ -1,3 +1,5 @@
Address format
https://bitboost.com/ref/international-address-formats.html#Formats https://bitboost.com/ref/international-address-formats.html#Formats
https://www.upu.int/en/Postal-Solutions/Programmes-Services/Addressing-Solutions https://www.upu.int/en/Postal-Solutions/Programmes-Services/Addressing-Solutions

View File

@ -16,57 +16,57 @@ Voici la liste des codes pays ou systeme :
EN EN
== ==
Meaning of the numbers. Meaning of the numbers:
- 2 digits for the country code or system code - first 2-3 digits for the country code or system code
- 5 digits for the company identifier - 5 digits for the company identifier
- 5 digits for item identifier - 5 digits for item identifier
- 1 digit for checksum - 1 digit for checksum
This rule has been twisted many times to improve the use of the available numbers. This rule has been twisted many times to improve the use of the available numbers.
Here is the list of country codes or system:
Here is the list of country codes or system:
List List
==== ====
00 <EFBFBD> 13 UCC (Etats-Unis et Canada) 00 - 13 UCC (U.S.A / États-Unis & Canada)
20 <EFBFBD> 29 Codification interne en magasin 20 - 29 Flag for internal numbering / Codification interne en magasin
30 <EFBFBD> 37 GENCOD-EAN France 30 - 37 GENCOD-EAN France
380 BCCI (Bulgarie) 380 BCCI (Bulgaria)
383 SANA (Slovenie) 383 SANA (Slovenia)
385 CRO-EAN (Croatie) 385 CRO-EAN (Croatia)
387 EAN-BIH (Bosnie-Herzegovine) 387 EAN-BIH (Bosnia-Herzegovina)
400 <20> 440 CCG (Allemagne) 400-440 CCG (Allemagne/Germany)
45 + 49 Distribution Code Center <20> DCC (Japon) 45 + 49 Distribution Code Center - DCC (Japan)
460 <20> 469 UNISCAN - EAN Russie (Federation de Russie) 460-469 UNISCAN - EAN Russia (Federation de Russie)
471 CAN (Taiwan) 471 CAN Taiwan
474 EAN Estonie 474 EAN Estonia
475 EAN Lettonie 475 EAN Latvia
476 EAN Azerba<62> djan 476 EAN Azerbaijan
477 EAN Lituanie 477 EAN Lithuania
478 EAN Ouzbekistan 478 EAN Uzbekistan
479 EAN Sri Lanka 479 EAN Sri Lanka
480 PANC (Philippines) 480 PANC Philippines
481 EAN Bielorussie 481 EAN Belarus
482 EAN Ukraine 482 EAN Ukraine
484 EAN Moldavie 484 EAN Moldova
485 EAN Armenie 485 EAN Armenia
486 EAN Georgie 486 EAN Georgia
487 EAN Kazakhstan 487 EAN Kazakhstan
489 HKANA (Hong Kong) 489 HKANA Hong Kong
50 E Centre UK 50 E Centre UK - United Kingdom
520 HELLCAN-EAN HELLAS (Grece) 520 HELLCAN-EAN HELLAS (Grece)
528 EAN Liban 528 EAN Liban
529 EAN Chypre 529 EAN Chypre
531 EAN-MAC (FYR Mac<EFBFBD>donie) 531 EAN-MAC (FYR Macedonie)
535 EAN Malte 535 EAN Malte
539 EAN Irlande 539 EAN Irlande
54 ICODIF/EAN Belgique. Luxembourg 54 ICODIF/EAN Belgique. Luxembourg
560 CODIPOR (Portugal) 560 CODIPOR (Portugal)
569 EAN Islande 569 EAN Islande
57 EAN Danemark 57 EAN Danemark
590 EAN Pologne 590 EAN Pologne
594 EAN Roumanie 594 EAN Roumanie
599 H.A.P.M.H. (Hongrie) 599 H.A.P.M.H. (Hongrie)

View File

@ -1,8 +1,12 @@
# File of all ISO-4217 currencies codes # File of all ISO-4217 currencies codes
# http://en.wikipedia.org/wiki/ISO_4217
# http://fx.sauder.ubc.ca/currency_table.html for symbols for 2 letter code
# #
# Code,Name,Nb decimals # https://en.wikipedia.org/wiki/ISO_4217
# https://en.wikipedia.org/wiki/Currency_symbol for symbols for 2 letter code
#
# Code, Currency Name, Nb decimals
AED,UAE Dirham,2 AED,UAE Dirham,2
AFN,Afghanistan Afghani,2 AFN,Afghanistan Afghani,2
ALL,Albanian Lek,2 ALL,Albanian Lek,2

View File

@ -1,3 +1,5 @@
Date and number format
----------------------
For languages: For languages:
https://icu4c-demos.unicode.org/icu-bin/icudemos - Locale Explorer -> Error 404 https://icu4c-demos.unicode.org/icu-bin/icudemos - Locale Explorer -> Error 404

View File

@ -1,3 +1,6 @@
VAT Rates
---------
http://www.taxrates.cc/index.html http://www.taxrates.cc/index.html
https://en.wikipedia.org/wiki/List_of_countries_by_tax_rates https://en.wikipedia.org/wiki/List_of_countries_by_tax_rates

View File

@ -1,62 +1,93 @@
<VirtualHost *:80> <VirtualHost *:80>
#php_admin_value sendmail_path "/usr/sbin/sendmail -t -i" #php_admin_value sendmail_path "/usr/sbin/sendmail -t -i"
#php_admin_value mail.force_extra_parameters "-f postmaster@mydomain.com" #php_admin_value mail.force_extra_parameters "-f postmaster@mydomain.com"
php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f postmaster@mydomain.com" php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f postmaster@mydomain.com"
php_admin_value open_basedir /tmp/:/home/../htdocs php_admin_value open_basedir /tmp/:/home/.../htdocs:/home/.../dolibarr_documents:
ServerName myvirtualalias ServerName myvirtualalias
ServerAlias myvirtualalias ServerAlias myvirtualalias
UseCanonicalName On UseCanonicalName On
AddDefaultCharset UTF-8 KeepAlive On
KeepAliveTimeout 5
MaxKeepAliveRequests 20
DocumentRoot "/home/.../htdocs" AddDefaultCharset UTF-8
<Directory /home/.../htdocs/> DocumentRoot "/home/.../htdocs"
AllowOverride None
Options -Indexes -MultiViews +FollowSymLinks -ExecCGI
Require all granted
</Directory>
<Directory "/home/../htdocs/cache"> <Directory /home/.../htdocs/>
Deny from all AllowOverride None
RemoveHandler .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml Options -Indexes -MultiViews +FollowSymLinks -ExecCGI
AddType application/x-httpd-php-source .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml Require all granted
</Directory>
# To restrict access by a HTTP basic auth
#AuthType Basic
#AuthName "Authenticate to backoffice"
#AuthUserFile /etc/apache2/.htpasswd
#require valid-user
</Directory>
# Leaving /public and /api, /dav, .well_known but also wrappers for document and viewimage accessible to everyone
<Directory /home/admin/wwwroot/dolibarr/htdocs/public/>
AuthType None
Require all granted
Satisfy any
</Directory>
<Directory /home/admin/wwwroot/dolibarr/htdocs/api/>
AuthType None
Require all granted
Satisfy any
</Directory>
<Directory /home/admin/wwwroot/dolibarr/htdocs/dav/>
AuthType None
Require all granted
Satisfy any
</Directory>
<Directory /home/admin/wwwroot/dolibarr/htdocs/.well-known/>
AuthType None
Require all granted
Satisfy any
</Directory>
<Files ~ "(document\.php|viewimage\.php|\.js\.php|\.json\.php|\.js|\.css\.php|\.css|\.gif|\.png|\.svg|\.woff2|favicon\.ico)$">
AuthType None
Require all granted
Satisfy any
</Files>
ErrorLog /var/log/apache2/myvirtualalias_error_log ErrorLog /var/log/apache2/myvirtualalias_error_log
TransferLog /var/log/apache2/myvirtualalias_access_log TransferLog /var/log/apache2/myvirtualalias_access_log
# Compress returned resources of type php pages, text file export, css and javascript # Compress returned resources of type php pages, text file export, css and javascript
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/x-javascript AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/x-javascript
AddType text/javascript .jgz AddType text/javascript .jgz
AddEncoding gzip .jgz AddEncoding gzip .jgz
ExpiresActive On ExpiresActive On
ExpiresByType image/x-icon A2592000 ExpiresByType image/x-icon A2592000
ExpiresByType image/gif A2592000 ExpiresByType image/gif A2592000
ExpiresByType image/png A2592000 ExpiresByType image/png A2592000
ExpiresByType image/jpeg A2592000 ExpiresByType image/jpeg A2592000
ExpiresByType text/css A2592000 ExpiresByType text/css A2592000
ExpiresByType text/javascript A2592000 ExpiresByType text/javascript A2592000
ExpiresByType application/x-javascript A2592000 ExpiresByType application/x-javascript A2592000
ExpiresByType application/javascript A2592000 ExpiresByType application/javascript A2592000
SSLEngine On SSLEngine On
# A self-signed (snakeoil) certificate can be created by installing # A self-signed (snakeoil) certificate can be created by installing
# the ssl-cert package. See # the ssl-cert package. See
# /usr/share/doc/apache2.2-common/README.Debian.gz for more info. # /usr/share/doc/apache2.2-common/README.Debian.gz for more info.
# If both key and certificate are stored in the same file, only the # If both key and certificate are stored in the same file, only the
# SSLCertificateFile directive is needed. # SSLCertificateFile directive is needed.
SSLCertificateFile /etc/letsencrypt/live/www.mydomain.com/cert.pem SSLCertificateFile /etc/letsencrypt/live/www.mydomain.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.mydomain.com/privkey.pem SSLCertificateKeyFile /etc/letsencrypt/live/www.mydomain.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.mydomain.com/chain.pem SSLCertificateChainFile /etc/letsencrypt/live/www.mydomain.com/chain.pem
#RewriteEngine on #RewriteEngine on
#RewriteCond %{SERVER_PORT} ^80$ #RewriteCond %{SERVER_PORT} ^80$
#RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [L,R] #RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [L,R]
</VirtualHost> </VirtualHost>

View File

@ -17,14 +17,14 @@ fi
# To detec # To detec
if [ "x$1" = "xlist" ] if [ "x$1" = "xlist" ]
then then
find . \( -iname "functions" -o -iname "*.md" -o -iname "*.html" -o -iname "*.htm" -o -iname "*.php" -o -iname "*.sh" -o -iname "*.cml" -o -iname "*.css" -o -iname "*.js" -o -iname "*.lang" -o -iname "*.pl" -o -iname "*.sql" -o -iname "*.txt" -o -iname "*.xml" -o -iname "*.pml" \) -exec file "{}" + | grep -v 'documents\/website' | grep -v 'documents\/mdedias' | grep CRLF find . \( -iname "functions" -o -iname "*.md" -o -iname "*.html" -o -iname "*.htm" -o -iname "*.php" -o -iname "*.sh" -o -iname "*.cml" -o -iname "*.css" -o -iname "*.js" -o -iname "*.lang" -o -iname "*.pl" -o -iname "*.sql" -o -iname "*.txt" -o -iname "*.xml" -o -iname "*.pml" \) -exec file "{}" + | grep -v 'custom\/' | grep -v 'documents\/website' | grep -v 'documents\/medias' | grep -v 'documents\/sellyoursaas' | grep CRLF
# find . \( -iname "*.md" -o -iname "*.html" -o -iname "*.htm" -o -iname "*.php" -o -iname "*.sh" -o -iname "*.cml" -o -iname "*.css" -o -iname "*.js" -o -iname "*.lang" -o -iname "*.pl" -o -iname "*.sql" -o -iname "*.txt" -o -iname "*.xml" \) -exec file "{}" + | grep -v 'documents\/website' | grep -v 'documents\/mdedias' | grep -v 'htdocs\/includes' | grep CRLF # find . \( -iname "*.md" -o -iname "*.html" -o -iname "*.htm" -o -iname "*.php" -o -iname "*.sh" -o -iname "*.cml" -o -iname "*.css" -o -iname "*.js" -o -iname "*.lang" -o -iname "*.pl" -o -iname "*.sql" -o -iname "*.txt" -o -iname "*.xml" \) -exec file "{}" + | grep -v 'custom\/' | grep -v 'documents\/website' | grep -v 'documents\/medias' | grep -v 'documents\/sellyoursaas' | grep -v 'htdocs\/includes' | grep CRLF
fi fi
# To convert # To convert
if [ "x$1" = "xfix" ] if [ "x$1" = "xfix" ]
then then
for fic in `find . \( -iname "functions" -o -iname "*.md" -o -iname "*.html" -o -iname "*.htm" -o -iname "*.php" -o -iname "*.sh" -o -iname "*.cml" -o -iname "*.css" -o -iname "*.js" -o -iname "*.lang" -o -iname "*.pl" -o -iname "*.sql" -o -iname "*.txt" -o -iname "*.xml" -o -iname "*.pml" \) -exec file "{}" + | grep -v 'documents\/website' | grep -v 'documents\/mdedias' | grep CRLF | awk -F':' '{ print $1 }' ` for fic in `find . \( -iname "functions" -o -iname "*.md" -o -iname "*.html" -o -iname "*.htm" -o -iname "*.php" -o -iname "*.sh" -o -iname "*.cml" -o -iname "*.css" -o -iname "*.js" -o -iname "*.lang" -o -iname "*.pl" -o -iname "*.sql" -o -iname "*.txt" -o -iname "*.xml" -o -iname "*.pml" \) -exec file "{}" + | grep -v 'custom\/' | grep -v 'documents\/website' | grep -v 'documents\/medias' | grep -v 'documents\/sellyoursaas' | grep CRLF | awk -F':' '{ print $1 }' `
do do
echo "Fix file $fic" echo "Fix file $fic"
dos2unix "$fic" dos2unix "$fic"

View File

@ -14,7 +14,8 @@ max_output_size=0
usage() usage()
{ {
cat <<EO cat <<EO
Usage: $PROGNAME [options] Usage: $PROGNAME (list|fix) [options]
Example: optimize_images.sh (list|fix) -i dirtoscan
Script to optimize JPG and PNG images in a directory. Script to optimize JPG and PNG images in a directory.
@ -183,8 +184,8 @@ ARGS=$(getopt -s bash --options $SHORTOPTS --longoptions $LONGOPTS --name $PROGN
# Syntax # Syntax
if [ "x$1" != "xlist" -a "x$1" != "xfix" ] if [ "x$1" != "xlist" -a "x$1" != "xfix" ]
then then
echo "Usage: optimize_images.sh (list|fix) -i dirtoscan" usage
exit exit 0
fi fi
eval set -- "$ARGS" eval set -- "$ARGS"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 946 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
doc/images/dolibarr_logo.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 219 KiB

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 KiB

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -363,7 +363,7 @@ if ($resql) {
$newcardbutton .= dolGetButtonTitle($langs->trans("New"), $langs->trans("Addanaccount"), 'fa fa-plus-circle', './card.php?action=create'); $newcardbutton .= dolGetButtonTitle($langs->trans("New"), $langs->trans("Addanaccount"), 'fa fa-plus-circle', './card.php?action=create');
include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
print_barre_liste($langs->trans('ListAccounts'), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1); print_barre_liste($langs->trans('ListAccounts'), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'accounting_account', 0, $newcardbutton, '', $limit, 0, 0, 1);
// Box to select active chart of account // Box to select active chart of account
print $langs->trans("Selectchartofaccounts")." : "; print $langs->trans("Selectchartofaccounts")." : ";
@ -404,6 +404,11 @@ if ($resql) {
$moreforfilter = ''; $moreforfilter = '';
$accountstatic = new AccountingAccount($db);
$accountparent = new AccountingAccount($db);
$totalarray = array();
$totalarray['nbfield'] = 0;
print '<div class="div-table-responsive">'; print '<div class="div-table-responsive">';
print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n"; print '<table class="tagtable liste'.($moreforfilter ? " listwithfilterbefore" : "").'">'."\n";
@ -466,11 +471,6 @@ if ($resql) {
print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
print "</tr>\n"; print "</tr>\n";
$accountstatic = new AccountingAccount($db);
$accountparent = new AccountingAccount($db);
$totalarray = array();
$totalarray['nbfield'] = 0;
$i = 0; $i = 0;
while ($i < min($num, $limit)) { while ($i < min($num, $limit)) {
$obj = $db->fetch_object($resql); $obj = $db->fetch_object($resql);
@ -615,8 +615,13 @@ if ($resql) {
} }
if ($num == 0) { if ($num == 0) {
$totalarray['nbfield']++; $colspan = 1;
print '<tr><td colspan="'.$totalarray['nbfield'].'"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>'; foreach ($arrayfields as $key => $val) {
if (!empty($val['checked'])) {
$colspan++;
}
}
print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
} }
print "</table>"; print "</table>";

View File

@ -185,11 +185,6 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
$ok = 0; $ok = 0;
setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors'); setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors');
} }
/*if (!is_numeric($_POST['code'])) // disabled, code may not be in numeric base
{
$ok = 0;
$msg .= $langs->transnoentities('ErrorFieldFormat', $langs->transnoentities('Code')).'<br>';
}*/
} }
if (GETPOSTISSET("country") && (GETPOST("country") == '0') && ($id != 2)) { if (GETPOSTISSET("country") && (GETPOST("country") == '0') && ($id != 2)) {
$ok = 0; $ok = 0;
@ -228,17 +223,17 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
$i = 0; $i = 0;
foreach ($listfieldinsert as $f => $value) { foreach ($listfieldinsert as $f => $value) {
if ($value == 'price' || preg_match('/^amount/i', $value) || $value == 'taux') { if ($value == 'price' || preg_match('/^amount/i', $value) || $value == 'taux') {
$_POST[$listfieldvalue[$i]] = price2num($_POST[$listfieldvalue[$i]], 'MU'); $_POST[$listfieldvalue[$i]] = price2num(GETPOST($listfieldvalue[$i]), 'MU');
} elseif ($value == 'entity') { } elseif ($value == 'entity') {
$_POST[$listfieldvalue[$i]] = $conf->entity; $_POST[$listfieldvalue[$i]] = $conf->entity;
} }
if ($i) { if ($i) {
$sql .= ","; $sql .= ",";
} }
if ($_POST[$listfieldvalue[$i]] == '') { if (GETPOST($listfieldvalue[$i]) == '') {
$sql .= "null"; $sql .= "null";
} else { } else {
$sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'";
} }
$i++; $i++;
} }
@ -276,7 +271,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
$i = 0; $i = 0;
foreach ($listfieldmodify as $field) { foreach ($listfieldmodify as $field) {
if ($field == 'price' || preg_match('/^amount/i', $field) || $field == 'taux') { if ($field == 'price' || preg_match('/^amount/i', $field) || $field == 'taux') {
$_POST[$listfieldvalue[$i]] = price2num($_POST[$listfieldvalue[$i]], 'MU'); $_POST[$listfieldvalue[$i]] = price2num(GETPOST($listfieldvalue[$i]), 'MU');
} elseif ($field == 'entity') { } elseif ($field == 'entity') {
$_POST[$listfieldvalue[$i]] = $conf->entity; $_POST[$listfieldvalue[$i]] = $conf->entity;
} }
@ -284,10 +279,10 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
$sql .= ","; $sql .= ",";
} }
$sql .= $field."="; $sql .= $field."=";
if ($_POST[$listfieldvalue[$i]] == '') { if (GETPOST($listfieldvalue[$i]) == '') {
$sql .= "null"; $sql .= "null";
} else { } else {
$sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'";
} }
$i++; $i++;
} }

View File

@ -417,13 +417,13 @@ if ($action == 'create') {
print '<div class="tabsAction">'; print '<div class="tabsAction">';
if (!empty($user->rights->accounting->chartofaccount)) { if (!empty($user->rights->accounting->chartofaccount)) {
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=update&token='.newToken().'&id='.$id.'">'.$langs->trans('Modify').'</a>'; print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=update&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Modify').'</a>';
} else { } else {
print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans('Modify').'</a>'; print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans('Modify').'</a>';
} }
if (!empty($user->rights->accounting->chartofaccount)) { if (!empty($user->rights->accounting->chartofaccount)) {
print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$id.'">'.$langs->trans('Delete').'</a>'; print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Delete').'</a>';
} else { } else {
print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans('Delete').'</a>'; print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans('Delete').'</a>';
} }

View File

@ -148,10 +148,10 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
if ($value == 'formula' && !GETPOST('formula')) { if ($value == 'formula' && !GETPOST('formula')) {
continue; continue;
} }
if ($value == 'range_account' && empty($_POST['range_account'])) { if ($value == 'range_account' && !GETPOST('range_account')) {
continue; continue;
} }
if (($value == 'country' || $value == 'country_id') && (!empty($_POST['country_id']))) { if (($value == 'country' || $value == 'country_id') && GETPOST('country_id')) {
continue; continue;
} }
if (!GETPOSTISSET($value) || GETPOST($value) == '') { if (!GETPOSTISSET($value) || GETPOST($value) == '') {
@ -195,17 +195,6 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
setEventMessages($langs->transnoentities('ErrorFieldMustBeANumeric', $langs->transnoentities("Position")), null, 'errors'); setEventMessages($langs->transnoentities('ErrorFieldMustBeANumeric', $langs->transnoentities("Position")), null, 'errors');
} }
// Clean some parameters
if ($_POST["accountancy_code"] <= 0) {
$_POST["accountancy_code"] = ''; // If empty, we force to null
}
if ($_POST["accountancy_code_sell"] <= 0) {
$_POST["accountancy_code_sell"] = ''; // If empty, we force to null
}
if ($_POST["accountancy_code_buy"] <= 0) {
$_POST["accountancy_code_buy"] = ''; // If empty, we force to null
}
// Si verif ok et action add, on ajoute la ligne // Si verif ok et action add, on ajoute la ligne
if ($ok && GETPOST('actionadd', 'alpha')) { if ($ok && GETPOST('actionadd', 'alpha')) {
if ($tabrowid[$id]) { if ($tabrowid[$id]) {
@ -243,7 +232,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
if ($i) { if ($i) {
$sql .= ","; $sql .= ",";
} }
if ($_POST[$listfieldvalue[$i]] == '' && !$listfieldvalue[$i] == 'formula') { if (GETPOST($listfieldvalue[$i]) == '' && !$listfieldvalue[$i] == 'formula') {
$sql .= "null"; // For vat, we want/accept code = '' $sql .= "null"; // For vat, we want/accept code = ''
} else { } else {
$sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'";
@ -283,8 +272,8 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
} }
$i = 0; $i = 0;
foreach ($listfieldmodify as $field) { foreach ($listfieldmodify as $field) {
if ($field == 'fk_country' && $_POST['country'] > 0) { if ($field == 'fk_country' && GETPOST('country') > 0) {
$_POST[$listfieldvalue[$i]] = $_POST['country']; $_POST[$listfieldvalue[$i]] = GETPOST('country');
} elseif ($field == 'entity') { } elseif ($field == 'entity') {
$_POST[$listfieldvalue[$i]] = $conf->entity; $_POST[$listfieldvalue[$i]] = $conf->entity;
} }
@ -292,10 +281,10 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
$sql .= ","; $sql .= ",";
} }
$sql .= $field."="; $sql .= $field."=";
if ($_POST[$listfieldvalue[$i]] == '' && !$listfieldvalue[$i] == 'range_account') { if (GETPOST($listfieldvalue[$i]) == '' && !$listfieldvalue[$i] == 'range_account') {
$sql .= "null"; // For range_account, we want/accept code = '' $sql .= "null"; // For range_account, we want/accept code = ''
} else { } else {
$sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'";
} }
$i++; $i++;
} }

View File

@ -24,7 +24,7 @@
/** /**
* \file htdocs/accountancy/admin/export.php * \file htdocs/accountancy/admin/export.php
* \ingroup Accountancy (Double entries) * \ingroup Accountancy (Double entries)
* \brief Setup page to configure accounting expert module * \brief Setup page to configure accounting export module
*/ */
require '../../main.inc.php'; require '../../main.inc.php';
@ -142,7 +142,7 @@ $linkback = '';
print load_fiche_titre($langs->trans('ExportOptions'), $linkback, 'accountancy'); print load_fiche_titre($langs->trans('ExportOptions'), $linkback, 'accountancy');
print "\n".'<script type="text/javascript" language="javascript">'."\n"; print "\n".'<script type="text/javascript">'."\n";
print 'jQuery(document).ready(function () {'."\n"; print 'jQuery(document).ready(function () {'."\n";
print ' function initfields()'."\n"; print ' function initfields()'."\n";
print ' {'."\n"; print ' {'."\n";

View File

@ -58,8 +58,8 @@ $listoffset = GETPOST('listoffset', 'alpha');
$listlimit = GETPOST('listlimit', 'int') > 0 ?GETPOST('listlimit', 'int') : 1000; $listlimit = GETPOST('listlimit', 'int') > 0 ?GETPOST('listlimit', 'int') : 1000;
$active = 1; $active = 1;
$sortfield = GETPOST("sortfield", 'alpha'); $sortfield = GETPOST('sortfield', 'aZ09comma');
$sortorder = GETPOST("sortorder", 'alpha'); $sortorder = GETPOST('sortorder', 'aZ09comma');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { if (empty($page) || $page == -1) {
$page = 0; $page = 0;
@ -165,45 +165,19 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
// Check that all fields are filled // Check that all fields are filled
$ok = 1; $ok = 1;
foreach ($listfield as $f => $value) {
if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) {
$fieldnamekey = 'Label';
}
if ($fieldnamekey == 'code') {
$fieldnamekey = 'Code';
}
if ($fieldnamekey == 'nature') {
$fieldnamekey = 'NatureOfJournal';
}
}
// Other checks // Other checks
if (GETPOSTISSET("code")) { if (GETPOSTISSET("code")) {
if (GETPOST("code") == '0') { if (GETPOST("code") == '0') {
$ok = 0; $ok = 0;
setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors'); setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors');
} }
/*if (!is_numeric($_POST['code'])) // disabled, code may not be in numeric base
{
$ok = 0;
$msg .= $langs->transnoentities('ErrorFieldFormat', $langs->transnoentities('Code')).'<br>';
}*/
} }
if (!GETPOST('label', 'alpha')) { if (!GETPOST('label', 'alpha')) {
setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")), null, 'errors'); setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentitiesnoconv("Label")), null, 'errors');
$ok = 0; $ok = 0;
} }
// Clean some parameters
if ($_POST["accountancy_code"] <= 0) {
$_POST["accountancy_code"] = ''; // If empty, we force to null
}
if ($_POST["accountancy_code_sell"] <= 0) {
$_POST["accountancy_code_sell"] = ''; // If empty, we force to null
}
if ($_POST["accountancy_code_buy"] <= 0) {
$_POST["accountancy_code_buy"] = ''; // If empty, we force to null
}
// Si verif ok et action add, on ajoute la ligne // Si verif ok et action add, on ajoute la ligne
if ($ok && GETPOST('actionadd', 'alpha')) { if ($ok && GETPOST('actionadd', 'alpha')) {
if ($tabrowid[$id]) { if ($tabrowid[$id]) {
@ -235,16 +209,13 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
} }
$i = 0; $i = 0;
foreach ($listfieldinsert as $f => $value) { foreach ($listfieldinsert as $f => $value) {
if ($value == 'entity') {
$_POST[$listfieldvalue[$i]] = $conf->entity;
}
if ($i) { if ($i) {
$sql .= ","; $sql .= ",";
} }
if ($_POST[$listfieldvalue[$i]] == '') { if (GETPOST($listfieldvalue[$i]) == '') {
$sql .= "null"; // For vat, we want/accept code = '' $sql .= "null"; // For vat, we want/accept code = ''
} else { } else {
$sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'";
} }
$i++; $i++;
} }
@ -254,7 +225,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
$result = $db->query($sql); $result = $db->query($sql);
if ($result) { // Add is ok if ($result) { // Add is ok
setEventMessages($langs->transnoentities("RecordSaved"), null, 'mesgs'); 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 { } else {
if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors'); setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors');
@ -281,24 +252,15 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
} }
$i = 0; $i = 0;
foreach ($listfieldmodify as $field) { foreach ($listfieldmodify as $field) {
if ($field == 'price' || preg_match('/^amount/i', $field) || $field == 'taux') {
$_POST[$listfieldvalue[$i]] = price2num($_POST[$listfieldvalue[$i]], 'MU');
} elseif ($field == 'entity') {
$_POST[$listfieldvalue[$i]] = $conf->entity;
}
if ($i) { if ($i) {
$sql .= ","; $sql .= ",";
} }
$sql .= $field."="; $sql .= $field." = ";
if ($_POST[$listfieldvalue[$i]] == '' && !($listfieldvalue[$i] == 'code' && $id == 10)) { $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'";
$sql .= "null"; // For vat, we want/accept code = ''
} else {
$sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'";
}
$i++; $i++;
} }
$sql .= " WHERE ".$rowidcol." = ".((int) $rowid); $sql .= " WHERE ".$rowidcol." = ".((int) $rowid);
$sql .= " AND entity = ".$conf->entity; $sql .= " AND entity = ".((int) $conf->entity);
dol_syslog("actionmodify", LOG_DEBUG); dol_syslog("actionmodify", LOG_DEBUG);
//print $sql; //print $sql;
@ -323,7 +285,7 @@ if ($action == 'confirm_delete' && $confirm == 'yes') { // delete
} }
$sql = "DELETE from ".$tabname[$id]." WHERE ".$rowidcol." = ".((int) $rowid); $sql = "DELETE from ".$tabname[$id]." WHERE ".$rowidcol." = ".((int) $rowid);
$sql .= " AND entity = ".$conf->entity; $sql .= " AND entity = ".((int) $conf->entity);
dol_syslog("delete", LOG_DEBUG); dol_syslog("delete", LOG_DEBUG);
$result = $db->query($sql); $result = $db->query($sql);
@ -410,7 +372,7 @@ if ($action == 'delete') {
if ($id) { if ($id) {
// Complete requete recherche valeurs avec critere de tri // Complete requete recherche valeurs avec critere de tri
$sql = $tabsql[$id]; $sql = $tabsql[$id];
$sql .= " WHERE a.entity = ".$conf->entity; $sql .= " WHERE a.entity = ".((int) $conf->entity);
// If sort order is "country", we use country_code instead // If sort order is "country", we use country_code instead
if ($sortfield == 'country') { if ($sortfield == 'country') {
@ -510,7 +472,7 @@ if ($id) {
$num = $db->num_rows($resql); $num = $db->num_rows($resql);
$i = 0; $i = 0;
$param = '&id='.$id; $param = '&id='.((int) $id);
if ($search_country_id > 0) { if ($search_country_id > 0) {
$param .= '&search_country_id='.urlencode($search_country_id); $param .= '&search_country_id='.urlencode($search_country_id);
} }
@ -635,7 +597,7 @@ if ($id) {
$class = 'tddict'; $class = 'tddict';
// Show value for field // Show value for field
if ($showfield) { if ($showfield) {
print '<!-- '.$fieldlist[$field].' --><td class="'.$class.'">'.$valuetoshow.'</td>'; print '<!-- '.$fieldlist[$field].' --><td class="'.$class.'">'.dol_escape_htmltag($valuetoshow).'</td>';
} }
} }
} }

View File

@ -80,8 +80,8 @@ if (empty($accounting_product_mode)) {
} }
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION);
$sortfield = GETPOST("sortfield", 'alpha'); $sortfield = GETPOST('sortfield', 'aZ09comma');
$sortorder = GETPOST("sortorder", 'alpha'); $sortorder = GETPOST('sortorder', 'aZ09comma');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == -1) { if (empty($page) || $page == -1) {
$page = 0; $page = 0;
@ -753,7 +753,7 @@ if ($result) {
print '</table>'; print '</table>';
print '</div>'; print '</div>';
print '<script type="text/javascript" language="javascript"> print '<script type="text/javascript">
jQuery(document).ready(function() { jQuery(document).ready(function() {
function init_savebutton() function init_savebutton()
{ {

View File

@ -237,11 +237,11 @@ if ($action != 'export_csv') {
print '<input type="hidden" name="page" value="'.$page.'">'; print '<input type="hidden" name="page" value="'.$page.'">';
$parameters = array(); $parameters = array();
$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
if (empty($reshook)) { if (empty($reshook)) {
$button = '<input type="button" id="exportcsvbutton" name="exportcsvbutton" class="butAction" value="'.$langs->trans("Export").' ('.$conf->global->ACCOUNTING_EXPORT_FORMAT.')" />'; $button = '<input type="button" id="exportcsvbutton" name="exportcsvbutton" class="butAction" value="'.$langs->trans("Export").' ('.$conf->global->ACCOUNTING_EXPORT_FORMAT.')" />';
print '<script type="text/javascript" language="javascript"> print '<script type="text/javascript">
jQuery(document).ready(function() { jQuery(document).ready(function() {
jQuery("#exportcsvbutton").click(function() { jQuery("#exportcsvbutton").click(function() {
event.preventDefault(); event.preventDefault();
@ -417,7 +417,7 @@ if ($action != 'export_csv') {
// Show first line of a break // Show first line of a break
print '<tr class="trforbreak">'; print '<tr class="trforbreak">';
print '<td colspan="'.($colspan+1).'" style="font-weight:bold; border-bottom: 1pt solid black;">'.$line->numero_compte.($root_account_description ? ' - '.$root_account_description : '').'</td>'; print '<td colspan="'.($colspan+1).'" class="tdforbreak">'.$line->numero_compte.($root_account_description ? ' - '.$root_account_description : '').'</td>';
print '</tr>'; print '</tr>';
$displayed_account = $root_account_number; $displayed_account = $root_account_number;

View File

@ -38,6 +38,8 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
$langs->loadLangs(array("accountancy", "bills", "compta")); $langs->loadLangs(array("accountancy", "bills", "compta"));
$action = GETPOST('action', 'aZ09'); $action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
$id = GETPOST('id', 'int'); // id of record $id = GETPOST('id', 'int'); // id of record
@ -92,6 +94,11 @@ if (empty($user->rights->accounting->mouvements->lire)) {
* Actions * Actions
*/ */
if ($cancel) {
header("Location: ".DOL_URL_ROOT.'/accountancy/bookkeeping/list.php');
exit;
}
if ($action == "confirm_update") { if ($action == "confirm_update") {
$error = 0; $error = 0;
@ -618,9 +625,10 @@ if ($action == 'create') {
print '<input type="hidden" name="fk_docdet" value="'.$object->fk_docdet.'">'."\n"; print '<input type="hidden" name="fk_docdet" value="'.$object->fk_docdet.'">'."\n";
print '<input type="hidden" name="mode" value="'.$mode.'">'."\n"; print '<input type="hidden" name="mode" value="'.$mode.'">'."\n";
print '<table class="noborder centpercent">';
if (count($object->linesmvt) > 0) { if (count($object->linesmvt) > 0) {
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
$total_debit = 0; $total_debit = 0;
$total_credit = 0; $total_credit = 0;
@ -655,7 +663,7 @@ if ($action == 'create') {
// Also, it is not possible to use a value that is not in the list. // Also, it is not possible to use a value that is not in the list.
// Also, the label is not automatically filled when a value is selected. // Also, the label is not automatically filled when a value is selected.
if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) { if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) {
print $formaccounting->select_auxaccount((GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account), 'subledger_account', 1); print $formaccounting->select_auxaccount((GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account), 'subledger_account', 1, 'maxwidth250', '', 'subledger_label');
} else { } else {
print '<input type="text" class="maxwidth150" name="subledger_account" value="'.(GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account).'" placeholder="'.dol_escape_htmltag($langs->trans("SubledgerAccount")).'">'; print '<input type="text" class="maxwidth150" name="subledger_account" value="'.(GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account).'" placeholder="'.dol_escape_htmltag($langs->trans("SubledgerAccount")).'">';
} }
@ -670,8 +678,14 @@ if ($action == 'create') {
print '<input type="submit" class="button" name="update" value="'.$langs->trans("Update").'">'; print '<input type="submit" class="button" name="update" value="'.$langs->trans("Update").'">';
print '</td>'; print '</td>';
} else { } else {
$accountingaccount->fetch(null, $line->numero_compte, true); $resultfetch = $accountingaccount->fetch(null, $line->numero_compte, true);
print '<td>'.$accountingaccount->getNomUrl(0, 1, 1, '', 0).'</td>'; print '<td>';
if ($resultfetch > 0) {
print $accountingaccount->getNomUrl(0, 1, 1, '', 0);
} else {
print $line->numero_compte.' <span class="warning">('.$langs->trans("AccountRemovedFromCurrentChartOfAccount").')</span>';
}
print '</td>';
print '<td>'.length_accounta($line->subledger_account); print '<td>'.length_accounta($line->subledger_account);
if ($line->subledger_label) { if ($line->subledger_label) {
print ' - <span class="opacitymedium">'.$line->subledger_label.'</span>'; print ' - <span class="opacitymedium">'.$line->subledger_label.'</span>';
@ -681,11 +695,15 @@ if ($action == 'create') {
print '<td class="right nowraponall amount">'.price($line->debit).'</td>'; print '<td class="right nowraponall amount">'.price($line->debit).'</td>';
print '<td class="right nowraponall amount">'.price($line->credit).'</td>'; print '<td class="right nowraponall amount">'.price($line->credit).'</td>';
print '<td class="center">'; print '<td class="center nowraponall">';
if (empty($line->date_export) && empty($line->date_validation)) { if (empty($line->date_export) && empty($line->date_validation)) {
print '<a class="editfielda reposition" href="' . $_SERVER["PHP_SELF"] . '?action=update&id=' . $line->id . '&piece_num=' . urlencode($line->piece_num) . '&mode=' . urlencode($mode) . '&token=' . urlencode(newToken()) . '">'; print '<a class="editfielda reposition" href="' . $_SERVER["PHP_SELF"] . '?action=update&id=' . $line->id . '&piece_num=' . urlencode($line->piece_num) . '&mode=' . urlencode($mode) . '&token=' . urlencode(newToken()) . '">';
print img_edit('', 0, 'class="marginrightonly"'); print img_edit('', 0, 'class="marginrightonly"');
print '</a> &nbsp;'; print '</a> &nbsp;';
} else {
print '<a class="editfielda nohover cursornotallowed reposition disabled" href="#" title="'.dol_escape_htmltag($langs->trans("ForbiddenTransactionAlreadyExported")).'">';
print img_edit($langs->trans("ForbiddenTransactionAlreadyExported"), 0, 'class="marginrightonly"');
print '</a> &nbsp;';
} }
if (empty($line->date_validation)) { if (empty($line->date_validation)) {
@ -696,9 +714,13 @@ if ($action == 'create') {
print '<a href="' . $_SERVER["PHP_SELF"] . '?action=' . $actiontodelete . '&id=' . $line->id . '&piece_num=' . urlencode($line->piece_num) . '&mode=' . urlencode($mode) . '&token=' . urlencode(newToken()) . '">'; print '<a href="' . $_SERVER["PHP_SELF"] . '?action=' . $actiontodelete . '&id=' . $line->id . '&piece_num=' . urlencode($line->piece_num) . '&mode=' . urlencode($mode) . '&token=' . urlencode(newToken()) . '">';
print img_delete(); print img_delete();
print '</a>';
} else {
print '<a class="editfielda nohover cursornotallowed disabled" href="#" title="'.dol_escape_htmltag($langs->trans("ForbiddenTransactionAlreadyExported")).'">';
print img_delete($langs->trans("ForbiddenTransactionAlreadyValidated"));
print '</a>';
} }
print '</a>';
print '</td>'; print '</td>';
} }
print "</tr>\n"; print "</tr>\n";
@ -724,7 +746,7 @@ if ($action == 'create') {
// Also, it is not possible to use a value that is not in the list. // Also, it is not possible to use a value that is not in the list.
// Also, the label is not automatically filled when a value is selected. // Also, the label is not automatically filled when a value is selected.
if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) { if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) {
print $formaccounting->select_auxaccount('', 'subledger_account', 1); print $formaccounting->select_auxaccount('', 'subledger_account', 1, 'maxwidth250', '', 'subledger_label');
} else { } else {
print '<input type="text" class="maxwidth150" name="subledger_account" value="" placeholder="' . dol_escape_htmltag($langs->trans("SubledgerAccount")) . '">'; print '<input type="text" class="maxwidth150" name="subledger_account" value="" placeholder="' . dol_escape_htmltag($langs->trans("SubledgerAccount")) . '">';
} }
@ -733,12 +755,16 @@ if ($action == 'create') {
print '<td><input type="text" class="minwidth200" name="label_operation" value="' . $label_operation . '"/></td>'; print '<td><input type="text" class="minwidth200" name="label_operation" value="' . $label_operation . '"/></td>';
print '<td class="right"><input type="text" size="6" class="right" name="debit" value=""/></td>'; print '<td class="right"><input type="text" size="6" class="right" name="debit" value=""/></td>';
print '<td class="right"><input type="text" size="6" class="right" name="credit" value=""/></td>'; print '<td class="right"><input type="text" size="6" class="right" name="credit" value=""/></td>';
print '<td><input type="submit" class="button" name="save" value="' . $langs->trans("Add") . '"></td>'; print '<td>';
print '<input type="submit" class="button" name="save" value="' . $langs->trans("Add") . '">';
print '</td>';
print '</tr>'; print '</tr>';
} }
print '</table>';
} }
print '</table>';
print '</div>';
if ($mode == '_tmp' && $action == '') { if ($mode == '_tmp' && $action == '') {
print '<br>'; print '<br>';
print '<div class="center">'; print '<div class="center">';
@ -753,8 +779,9 @@ if ($action == 'create') {
print "</div>"; print "</div>";
} }
print '</form>';
} }
print '</form>';
} }
} else { } else {
print load_fiche_titre($langs->trans("NoRecords")); print load_fiche_titre($langs->trans("NoRecords"));

View File

@ -24,6 +24,7 @@
* \ingroup Accountancy (Double entries) * \ingroup Accountancy (Double entries)
* \brief List operation of book keeping * \brief List operation of book keeping
*/ */
require '../../main.inc.php'; require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancyexport.class.php'; 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.'/core/lib/accounting.lib.php';
@ -189,7 +190,7 @@ $arrayfields = array(
't.date_creation'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0), 't.date_creation'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0),
't.tms'=>array('label'=>$langs->trans("DateModification"), 'checked'=>0), 't.tms'=>array('label'=>$langs->trans("DateModification"), 'checked'=>0),
't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1), 't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1),
't.date_validated'=>array('label'=>$langs->trans("DateValidation"), 'checked'=>1), 't.date_validated'=>array('label'=>$langs->trans("DateValidationAndLock"), 'checked'=>1),
); );
if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) {
@ -333,10 +334,6 @@ if (empty($reshook)) {
$filter['t.numero_compte<='] = $search_accountancy_code_end; $filter['t.numero_compte<='] = $search_accountancy_code_end;
$param .= '&search_accountancy_code_end='.urlencode($search_accountancy_code_end); $param .= '&search_accountancy_code_end='.urlencode($search_accountancy_code_end);
} }
if (!empty($search_accountancy_aux_code)) {
$filter['t.subledger_account'] = $search_accountancy_aux_code;
$param .= '&search_accountancy_aux_code='.urlencode($search_accountancy_aux_code);
}
if (!empty($search_accountancy_aux_code_start)) { if (!empty($search_accountancy_aux_code_start)) {
$filter['t.subledger_account>='] = $search_accountancy_aux_code_start; $filter['t.subledger_account>='] = $search_accountancy_aux_code_start;
$param .= '&search_accountancy_aux_code_start='.urlencode($search_accountancy_aux_code_start); $param .= '&search_accountancy_aux_code_start='.urlencode($search_accountancy_aux_code_start);
@ -533,11 +530,11 @@ if (count($filter) > 0) {
$sqlwhere[] = $key."='".$db->idate($value)."'"; $sqlwhere[] = $key."='".$db->idate($value)."'";
} elseif ($key == 't.doc_date>=' || $key == 't.doc_date<=') { } elseif ($key == 't.doc_date>=' || $key == 't.doc_date<=') {
$sqlwhere[] = $key."'".$db->idate($value)."'"; $sqlwhere[] = $key."'".$db->idate($value)."'";
} elseif ($key == 't.numero_compte>=' || $key == 't.numero_compte<=') { } elseif ($key == 't.numero_compte>=' || $key == 't.numero_compte<=' || $key == 't.subledger_account>=' || $key == 't.subledger_account<=') {
$sqlwhere[] = $key."'".$db->escape($value)."'"; $sqlwhere[] = $key."'".$db->escape($value)."'";
} elseif ($key == 't.fk_doc' || $key == 't.fk_docdet' || $key == 't.piece_num') { } elseif ($key == 't.fk_doc' || $key == 't.fk_docdet' || $key == 't.piece_num') {
$sqlwhere[] = $key.'='.((int) $value); $sqlwhere[] = $key.'='.((int) $value);
} elseif ($key == 't.numero_compte') { } elseif ($key == 't.subledger_account' || $key == 't.numero_compte') {
$sqlwhere[] = $key." LIKE '".$db->escape($value)."%'"; $sqlwhere[] = $key." LIKE '".$db->escape($value)."%'";
} elseif ($key == 't.subledger_account') { } elseif ($key == 't.subledger_account') {
$sqlwhere[] = natural_search($key, $value, 0, 1); $sqlwhere[] = natural_search($key, $value, 0, 1);
@ -681,24 +678,35 @@ $formconfirm = '';
if ($action == 'export_file') { if ($action == 'export_file') {
$form_question = array(); $form_question = array();
// If 1 or not set, we check by default.
$checked = (!isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE));
$form_question['notifiedexportdate'] = array( $form_question['notifiedexportdate'] = array(
'name' => 'notifiedexportdate', 'name' => 'notifiedexportdate',
'type' => 'checkbox', 'type' => 'checkbox',
'label' => $langs->trans('NotifiedExportDate'), 'label' => $langs->trans('NotifiedExportDate'),
'value' => (!empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) ? 'false' : 'true'), 'value' => $checked,
); );
$form_question['separator'] = array('name'=>'separator', 'type'=>'separator');
// If 0 or not set, we NOT check by default.
$checked = (isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE));
$form_question['notifiedvalidationdate'] = array( $form_question['notifiedvalidationdate'] = array(
'name' => 'notifiedvalidationdate', 'name' => 'notifiedvalidationdate',
'type' => 'checkbox', 'type' => 'checkbox',
'label' => $langs->trans('NotifiedValidationDate'), 'label' => $langs->trans('NotifiedValidationDate'),
'value' => (!empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE) ? 'false' : 'true'), 'value' => $checked,
); );
$form_question['separator2'] = array('name'=>'separator2', 'type'=>'separator');
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', $langs->trans('ConfirmExportFile'), 'export_fileconfirm', $form_question, '', 1, 300, 600); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', $langs->trans('ConfirmExportFile'), 'export_fileconfirm', $form_question, '', 1, 300, 600);
} }
if ($action == 'delmouv') { if ($action == 'delmouv') {
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?mvt_num='.GETPOST('mvt_num').$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvtPartial'), 'delmouvconfirm', '', 0, 1); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?mvt_num='.urlencode(GETPOST('mvt_num')).$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvtPartial'), 'delmouvconfirm', '', 0, 1);
} }
if ($action == 'delbookkeepingyear') { if ($action == 'delbookkeepingyear') {
$form_question = array(); $form_question = array();
$delyear = GETPOST('delyear', 'int'); $delyear = GETPOST('delyear', 'int');
@ -719,6 +727,7 @@ if ($action == 'delbookkeepingyear') {
'type' => 'select', 'type' => 'select',
'label' => $langs->trans('DelMonth'), 'label' => $langs->trans('DelMonth'),
'values' => $month_array, 'values' => $month_array,
'morecss' => 'minwidth150',
'default' => '' 'default' => ''
); );
$form_question['delyear'] = array( $form_question['delyear'] = array(
@ -736,7 +745,7 @@ if ($action == 'delbookkeepingyear') {
'default' => $deljournal 'default' => $deljournal
); );
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'delbookkeepingyearconfirm', $form_question, '', 1, 300); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'delbookkeepingyearconfirm', $form_question, '', 1, 320);
} }
// Print form confirm // Print form confirm
@ -769,7 +778,7 @@ if (count($filter)) {
} }
$parameters = array(); $parameters = array();
$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
if (empty($reshook)) { if (empty($reshook)) {
// Button re-export // Button re-export
if (!empty($conf->global->ACCOUNTING_REEXPORT)) { if (!empty($conf->global->ACCOUNTING_REEXPORT)) {
@ -823,7 +832,7 @@ if (!empty($arrayfields['t.piece_num']['checked'])) {
// Code journal // Code journal
if (!empty($arrayfields['t.code_journal']['checked'])) { if (!empty($arrayfields['t.code_journal']['checked'])) {
print '<td class="liste_titre center">'; print '<td class="liste_titre center">';
print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1, 'maxwidth150'); print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1, 'small maxwidth150');
print '</td>'; print '</td>';
} }
// Date document // Date document
@ -845,10 +854,10 @@ if (!empty($arrayfields['t.doc_ref']['checked'])) {
if (!empty($arrayfields['t.numero_compte']['checked'])) { if (!empty($arrayfields['t.numero_compte']['checked'])) {
print '<td class="liste_titre">'; print '<td class="liste_titre">';
print '<div class="nowrap">'; print '<div class="nowrap">';
print $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth200', 'account'); print $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth150', 'account');
print '</div>'; print '</div>';
print '<div class="nowrap">'; print '<div class="nowrap">';
print $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth200', 'account'); print $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth150', 'account');
print '</div>'; print '</div>';
print '</td>'; print '</td>';
} }
@ -1125,24 +1134,25 @@ while ($i < min($num, $limit)) {
// Other type // Other type
} }
print '<td class="nowrap">'; $labeltoshow = '';
$labeltoshowalt = '';
print '<table class="nobordernopadding"><tr class="nocellnopadd">';
// Picto + Ref
print '<td class="nobordernopadding nowrap">';
if ($line->doc_type == 'customer_invoice' || $line->doc_type == 'supplier_invoice' || $line->doc_type == 'expense_report') { 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); $labeltoshow .= $objectstatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1);
print $documentlink; $labeltoshow .= $documentlink;
$labeltoshowalt .= $objectstatic->ref;
} elseif ($line->doc_type == 'bank') { } elseif ($line->doc_type == 'bank') {
print $objectstatic->getNomUrl(1); $labeltoshow .= $objectstatic->getNomUrl(1);
$labeltoshowalt .= $objectstatic->ref;
$bank_ref = strstr($line->doc_ref, '-'); $bank_ref = strstr($line->doc_ref, '-');
print " " . $bank_ref; $labeltoshow .= " " . $bank_ref;
$labeltoshowalt .= " " . $bank_ref;
} else { } else {
print $line->doc_ref; $labeltoshow .= $line->doc_ref;
$labeltoshowalt .= $line->doc_ref;
} }
print '</td></tr></table>';
print '<td class="nowraponall tdoverflowmax200" title="'.dol_escape_htmltag($labeltoshowalt).'">';
print $labeltoshow;
print "</td>\n"; print "</td>\n";
if (!$i) { if (!$i) {
$totalarray['nbfield']++; $totalarray['nbfield']++;
@ -1167,7 +1177,7 @@ while ($i < min($num, $limit)) {
// Label operation // Label operation
if (!empty($arrayfields['t.label_operation']['checked'])) { if (!empty($arrayfields['t.label_operation']['checked'])) {
print '<td>'.$line->label_operation.'</td>'; print '<td class="small tdoverflowmax200" title="'.dol_escape_htmltag($line->label_operation).'">'.dol_escape_htmltag($line->label_operation).'</td>';
if (!$i) { if (!$i) {
$totalarray['nbfield']++; $totalarray['nbfield']++;
} }
@ -1228,7 +1238,7 @@ while ($i < min($num, $limit)) {
// Exported operation date // Exported operation date
if (!empty($arrayfields['t.date_export']['checked'])) { if (!empty($arrayfields['t.date_export']['checked'])) {
print '<td class="center">'.dol_print_date($line->date_export, 'dayhour').'</td>'; print '<td class="center nowraponall">'.dol_print_date($line->date_export, 'dayhour').'</td>';
if (!$i) { if (!$i) {
$totalarray['nbfield']++; $totalarray['nbfield']++;
} }
@ -1236,7 +1246,7 @@ while ($i < min($num, $limit)) {
// Validated operation date // Validated operation date
if (!empty($arrayfields['t.date_validated']['checked'])) { if (!empty($arrayfields['t.date_validated']['checked'])) {
print '<td class="center">'.dol_print_date($line->date_validation, 'dayhour').'</td>'; print '<td class="center nowraponall">'.dol_print_date($line->date_validation, 'dayhour').'</td>';
if (!$i) { if (!$i) {
$totalarray['nbfield']++; $totalarray['nbfield']++;
} }

View File

@ -473,7 +473,7 @@ print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">'; print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
$parameters = array(); $parameters = array();
$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
if (empty($reshook)) { if (empty($reshook)) {
$newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param); $newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param);
$newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected'));
@ -711,8 +711,8 @@ while ($i < min($num, $limit)) {
} }
// Show the break account // Show the break account
print "<tr>"; print '<tr class="trforbreak">';
print '<td colspan="'.($totalarray['nbfield'] ? $totalarray['nbfield'] : 10).'" style="font-weight:bold; border-bottom: 1pt solid black;">'; print '<td colspan="'.($totalarray['nbfield'] ? $totalarray['nbfield'] : 10).'" class="tdforbreak">';
if ($line->numero_compte != "" && $line->numero_compte != '-1') { if ($line->numero_compte != "" && $line->numero_compte != '-1') {
print length_accountg($line->numero_compte).' : '.$object->get_compte_desc($line->numero_compte); print length_accountg($line->numero_compte).' : '.$object->get_compte_desc($line->numero_compte);
} else { } else {

View File

@ -473,7 +473,7 @@ print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">'; print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
$parameters = array(); $parameters = array();
$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
if (empty($reshook)) { if (empty($reshook)) {
$newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param); $newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param);
$newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly')); $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly'));
@ -713,8 +713,8 @@ while ($i < min($num, $limit)) {
} }
// Show the break account // Show the break account
print "<tr>"; print '<tr class="trforbreak">';
print '<td colspan="'.($totalarray['nbfield'] ? $totalarray['nbfield'] : 10).'" style="font-weight:bold; border-bottom: 1pt solid black;">'; print '<td colspan="'.($totalarray['nbfield'] ? $totalarray['nbfield'] : 10).'" class="tdforbreak">';
if ($line->subledger_account != "" && $line->subledger_account != '-1') { if ($line->subledger_account != "" && $line->subledger_account != '-1') {
print $line->subledger_label.' : '.length_accounta($line->subledger_account); print $line->subledger_label.' : '.length_accounta($line->subledger_account);
} else { } else {

View File

@ -1,325 +0,0 @@
<?php
/* Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2013 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013-2019 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2018-2020 Frédéric France <frederic.france@netlogic.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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 <https://www.gnu.org/licenses/>.
*
*/
/**
* \file htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php
* \ingroup accountancy
* \brief Tab to manage customer lettering
*/
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/lettering.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
// Load translation files required by the page
$langs->loadLangs(array("compta", "accountancy"));
$action = GETPOST('action', 'aZ09');
$massaction = GETPOST('massaction', 'alpha');
$show_files = GETPOST('show_files', 'int');
$confirm = GETPOST('confirm', 'alpha');
$toselect = GETPOST('toselect', 'array');
// $socid = GETPOST('socid', 'int') ?GETPOST('socid', 'int') : GETPOST('id', 'int');
// Security check
$socid = GETPOSTINT("socid");
// if ($user->socid) $socid=$user->socid;
$limit = GETPOSTISSET('limit') ? GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == - 1) {
$page = 0;
} // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
if ($sortorder == "") {
$sortorder = "ASC";
}
if ($sortfield == "") {
$sortfield = "bk.doc_date";
}
/*
$search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int'));
$search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
//$search_doc_type = GETPOST("search_doc_type", 'alpha');
$search_doc_ref = GETPOST("search_doc_ref", 'alpha');
*/
$lettering = GETPOST('lettering', 'alpha');
if (!empty($lettering)) {
$action = $lettering;
}
/*
if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers
{
$search_date_start = '';
$search_date_end = '';
//$search_doc_type = '';
$search_doc_ref = '';
}
*/
$lettering = new Lettering($db);
$object = new Societe($db);
$object->id = $socid;
$result = $object->fetch($socid);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
if (empty($conf->accounting->enabled)) {
accessforbidden();
}
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->mouvements->lire)) {
accessforbidden();
}
/*
* Action
*/
if ($action == 'lettering') {
$result = $lettering->updateLettering($toselect);
if ($result < 0) {
setEventMessages('', $lettering->errors, 'errors');
$error++;
}
}
/*
if ($action == 'autolettrage') {
$result = $lettering->letteringThirdparty($socid);
if ($result < 0) {
setEventMessages('', $lettering->errors, 'errors');
$error++;
}
}
*/
/*
* View
*/
$form = new Form($db);
$formaccounting = new FormAccounting($db);
$title = $object->name." - ".$langs->trans('TabLetteringCustomer');
$help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas|DE:Modul_Geschäftspartner';
llxHeader('', $title, $help_url);
$head = societe_prepare_head($object);
dol_htmloutput_mesg(is_numeric($error) ? '' : $error, $errors, 'error');
print dol_get_fiche_head($head, 'lettering_customer', $langs->trans("ThirdParty"), 0, 'company');
$linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom', '', '', 0, '', '', 'arearefnobottom');
print dol_get_fiche_end();
$sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, ";
$sql .= " bk.subledger_account, bk.numero_compte , bk.label_compte, bk.debit, ";
$sql .= " bk.credit, bk.montant, bk.sens, bk.code_journal, bk.piece_num, bk.lettering_code";
$sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as bk";
$sql .= " WHERE (bk.subledger_account = '".$db->escape($object->code_compta)."' AND bk.numero_compte = '".$db->escape($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER)."' )";
/*
if (dol_strlen($search_date_start) || dol_strlen($search_date_end)) {
$sql .= " AND ( bk.doc_date BETWEEN '" . $db->idate($search_date_start) . "' AND '" . $db->idate($search_date_end) . "' )";
}
*/
$sql .= ' AND bk.entity IN ('.getEntity('accountingbookkeeping').')';
$sql .= $db->order($sortfield, $sortorder);
$debit = 0;
$credit = 0;
$solde = 0;
// Count total nb of records and calc total sum
$nbtotalofrecords = '';
$resql = $db->query($sql);
if (!$resql) {
dol_print_error($db);
exit();
}
$nbtotalofrecords = $db->num_rows($resql);
while ($obj = $db->fetch_object($resql)) {
$debit += $obj->debit;
$credit += $obj->credit;
$solde += ($obj->credit - $obj->debit);
}
$sql .= $db->plimit($limit + 1, $offset);
dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_customer.php", LOG_DEBUG);
$resql = $db->query($sql);
if (!$resql) {
dol_print_error($db);
exit();
}
$param = '';
$param .= "&socid=".urlencode($socid);
$num = $db->num_rows($resql);
dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_customer.php", LOG_DEBUG);
if ($resql) {
$i = 0;
$param = "&socid=".$socid;
print '<form name="add" action="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="socid" value="'.$object->id.'">';
$letteringbutton = '<a class="divButAction"><span class="valignmiddle"><input class="butAction" type="submit" value="lettering" name="lettering" id="lettering"></span></a>';
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, $letteringbutton, '', $limit);
print '<div class="div-table-responsive-no-min">';
print '<table class="liste centpercent">'."\n";
/*
print '<tr class="liste_titre">';
//print '<td><input type="text" name="search_doc_type" value="' . $search_doc_type . '"></td>';
// Date
print '<td class="liste_titre center">';
print '<div class="nowrap">';
print $langs->trans('From') . ' ';
print $form->selectDate($search_date_start, 'date_creation_start', 0, 0, 1);
print '</div>';
print '<div class="nowrap">';
print $langs->trans('to') . ' ';
print $form->selectDate($search_date_end, 'date_creation_end', 0, 0, 1);
print '</div>';
print '</td>';
// Piece
print '<td><input type="text" name="search_doc_ref" value="' . $search_doc_ref . '"></td>';
print '<td colspan="6">&nbsp;</td>';
print '<td class="right">';
$searchpicto = $form->showFilterButtons();
print $searchpicto;
print '</td>';
print '</tr>';
*/
print '<tr class="liste_titre">';
//print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder, 'center ');
print_liste_field_titre("Piece", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder, 'center ');
print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder, 'center ');
print_liste_field_titre("", "", "", '', '', "", $sortfield, $sortorder, 'maxwidthsearch center ');
print "</tr>\n";
$solde = 0;
$tmp = '';
while ($obj = $db->fetch_object($resql)) {
if ($tmp != $obj->lettering_code || empty($tmp)) {
$tmp = $obj->lettering_code;
}
/*if ($tmp != $obj->lettering_code || empty($obj->lettering_code))*/ $solde += ($obj->credit - $obj->debit);
print '<tr class="oddeven">';
//print '<td>' . $obj->doc_type . '</td>' . "\n";
print '<td class="center">'.dol_print_date($db->jdate($obj->doc_date), 'day').'</td>';
print '<td>'.$obj->doc_ref.'</td>';
print '<td>'.$obj->label_compte.'</td>';
print '<td class="nowrap right">'.price($obj->debit).'</td>';
print '<td class="nowrap right">'.price($obj->credit).'</td>';
print '<td class="nowrap right">'.price(round($solde, 2)).'</td>';
// Journal
$accountingjournal = new AccountingJournal($db);
$result = $accountingjournal->fetch('', $obj->code_journal);
$journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $obj->code_journal);
print '<td class="center">'.$journaltoshow.'</td>';
if (empty($obj->lettering_code) && empty($obj->date_validated)) {
print '<td class="nowrap center"><input type="checkbox" class="flat checkforselect" name="toselect[]" id="toselect[]" value="'.$obj->rowid.'" /></td>';
print '<td><a href="'.DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?piece_num='.$obj->piece_num.'">';
print img_edit();
print '</a></td>'."\n";
} else {
print '<td class="center">'.$obj->lettering_code.'</td>';
print '<td></td>';
}
print "</tr>\n";
}
print '<tr class="oddeven">';
print '<td class="right" colspan="3">'.$langs->trans("Total").':</td>'."\n";
print '<td class="right nowraponall amount"><strong>'.price($debit).'</strong></td>';
print '<td class="right nowraponall amount"><strong>'.price($credit).'</strong></td>';
print '<td colspan="4"></td>';
print "</tr>\n";
print '<tr class="oddeven">';
print '<td class="right" colspan="3">'.$langs->trans("Balancing").':</td>'."\n";
print '<td colspan="2">&nbsp;</td>';
print '<td class="right nowraponall amount"><strong>'.price($credit - $debit).'</strong></td>';
print '<td colspan="6"></td>';
print "</tr>\n";
print "</table>";
print '<div class="tabsAction tabsActionNoBottom">'."\n";
print $letteringbutton;
print '</div>';
print "</form>";
$db->free($resql);
} else {
dol_print_error($db);
}
// End of page
llxFooter();
$db->close();

View File

@ -1,322 +0,0 @@
<?php
/* Copyright (C) 2004-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2005 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2013 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013-2019 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2018-2020 Frédéric France <frederic.france@netlogic.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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 <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php
* \ingroup Accountancy (Double entries)
* \brief Tab to setup lettering
*/
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/lettering.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
// Load translation files required by the page
$langs->loadLangs(array("compta", "accountancy"));
$action = GETPOST('action', 'aZ09');
$massaction = GETPOST('massaction', 'alpha');
$show_files = GETPOST('show_files', 'int');
$confirm = GETPOST('confirm', 'alpha');
$toselect = GETPOST('toselect', 'array');
// $socid = GETPOST('socid', 'int') ? ((int) GETPOST('socid', 'int')) : ((int) GETPOST('id', 'int'));
// Security check
$socid = GETPOSTINT("socid");
// if ($user->socid) $socid=$user->socid;
$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST("sortfield", 'alpha');
$sortorder = GETPOST("sortorder", 'alpha');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page == - 1) {
$page = 0;
} // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
if ($sortorder == "") {
$sortorder = "ASC";
}
if ($sortfield == "") {
$sortfield = "bk.doc_date";
}
/*
$search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int'));
$search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
//$search_doc_type = GETPOST("search_doc_type",'alpha');
$search_doc_ref = GETPOST("search_doc_ref",'alpha');
*/
$lettering = GETPOST('lettering', 'alpha');
if (!empty($lettering)) {
$action = $lettering;
}
/*
if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers
{
$search_date_start = '';
$search_date_end = '';
//$search_doc_type='';
$search_doc_ref='';
}
*/
$lettering = new Lettering($db);
$object = new Societe($db);
$object->id = $socid;
$result = $object->fetch($socid);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
if (empty($conf->accounting->enabled)) {
accessforbidden();
}
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->mouvements->lire)) {
accessforbidden();
}
/*
* Action
*/
if ($action == 'lettering') {
$result = $lettering->updateLettering($toselect);
if ($result < 0) {
setEventMessages('', $lettering->errors, 'errors');
$error++;
}
}
/*
if ($action == 'autolettrage') {
$result = $lettering->letteringThirdparty($socid);
if ($result < 0) {
setEventMessages('', $lettering->errors, 'errors');
$error++;
}
}
*/
/*
* View
*/
$form = new Form($db);
$formaccounting = new FormAccounting($db);
$title = $object->name." - ".$langs->trans('TabLetteringSupplier');
$help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas|DE:Modul_Geschäftspartner';
llxHeader('', $title, $help_url);
$head = societe_prepare_head($object);
dol_htmloutput_mesg(is_numeric($error) ? '' : $error, $errors, 'error');
print dol_get_fiche_head($head, 'lettering_supplier', $langs->trans("ThirdParty"), 0, 'company');
$linkback = '<a href="'.DOL_URL_ROOT.'/societe/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom', '', '', 0, '', '', 'arearefnobottom');
print dol_get_fiche_end();
$sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, ";
$sql .= " bk.subledger_account, bk.numero_compte , bk.label_compte, bk.debit, ";
$sql .= " bk.credit, bk.montant, bk.sens, bk.code_journal, bk.piece_num, bk.lettering_code, bk.date_validated ";
$sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as bk";
$sql .= " WHERE (bk.subledger_account = '".$db->escape($object->code_compta_fournisseur)."' AND bk.numero_compte = '".$db->escape($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER)."' )";
if (dol_strlen($search_date_start) || dol_strlen($search_date_end)) {
$sql .= " AND (bk.doc_date BETWEEN '".$db->idate($search_date_start)."' AND '".$db->idate($search_date_end)."' )";
}
$sql .= ' AND bk.entity IN ('.getEntity('accountingbookkeeping').')';
$sql .= $db->order($sortfield, $sortorder);
$debit = 0;
$credit = 0;
$solde = 0;
// Count total nb of records and calc total sum
$nbtotalofrecords = '';
$resql = $db->query($sql);
if (!$resql) {
dol_print_error($db);
exit;
}
$nbtotalofrecords = $db->num_rows($resql);
while ($obj = $db->fetch_object($resql)) {
$debit += $obj->debit;
$credit += $obj->credit;
$solde += ($obj->credit - $obj->debit);
}
$sql .= $db->plimit($limit + 1, $offset);
dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_supplier.php", LOG_DEBUG);
$resql = $db->query($sql);
if (!$resql) {
dol_print_error($db);
exit;
}
$param = '';
$param .= "&socid=".urlencode($socid);
$num = $db->num_rows($resql);
dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_supplier.php", LOG_DEBUG);
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
$i = 0;
$param = "&socid=".$socid;
print '<form name="add" action="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="socid" value="'.$object->id.'">';
$letteringbutton = '<a class="divButAction"><span class="valignmiddle"><input class="butAction" type="submit" value="lettering" name="lettering" id="lettering"></span></a>';
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, $letteringbutton, '', $limit);
print '<div class="div-table-responsive-no-min">';
print '<table class="liste centpercent">'."\n";
/*
print '<tr class="liste_titre">';
//print '<td><input type="text" name="search_doc_type" value="' . $search_doc_type . '"></td>';
// Date
print '<td class="liste_titre center">';
print '<div class="nowrap">';
print $langs->trans('From') . ' ';
print $form->selectDate($search_date_start, 'date_creation_start', 0, 0, 1);
print '</div>';
print '<div class="nowrap">';
print $langs->trans('to') . ' ';
print $form->selectDate($search_date_end, 'date_creation_end', 0, 0, 1);
print '</div>';
print '</td>';
// Piece
print '<td><input type="text" name="search_doc_ref" value="' . $search_doc_ref . '"></td>';
print '<td colspan="6">&nbsp;</td>';
print '<td class="right">';
$searchpicto = $form->showFilterButtons();
print $searchpicto;
print '</td>';
print '</tr>';
*/
print '<tr class="liste_titre">';
//print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder, 'center ');
print_liste_field_titre("Piece", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder);
print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder, 'center ');
print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder, 'center ');
print_liste_field_titre("", "", "", '', '', "", $sortfield, $sortorder, 'maxwidthsearch center ');
print "</tr>\n";
$solde = 0;
$tmp = '';
while ($obj = $db->fetch_object($resql)) {
if ($tmp != $obj->lettering_code || empty($tmp)) {
$tmp = $obj->lettering_code;
}
/*if ($tmp != $obj->lettering_code || empty($obj->lettering_code))*/ $solde += ($obj->credit - $obj->debit);
print '<tr class="oddeven">';
//print '<td>' . $obj->doc_type . '</td>' . "\n";
print '<td class="center">'.dol_print_date($db->jdate($obj->doc_date), 'day').'</td>';
print '<td>'.$obj->doc_ref.'</td>';
print '<td>'.$obj->label_compte.'</td>';
print '<td class="nowrap right">'.price($obj->debit).'</td>';
print '<td class="nowrap right">'.price($obj->credit).'</td>';
print '<td class="nowrap right">'.price(round($solde, 2)).'</td>';
// Journal
$accountingjournal = new AccountingJournal($db);
$result = $accountingjournal->fetch('', $obj->code_journal);
$journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $obj->code_journal);
print '<td class="center">'.$journaltoshow.'</td>';
if (empty($obj->lettering_code) && empty($obj->date_validated)) {
print '<td class="nowrap center"><input type="checkbox" class="flat checkforselect" name="toselect[]" id="toselect[]" value="'.$obj->rowid.'" /></td>';
print '<td><a href="'.DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?piece_num='.$obj->piece_num.'">';
print img_edit();
print '</a></td>'."\n";
} else {
print '<td class="center">'.$obj->lettering_code.'</td>';
print '<td></td>';
}
print "</tr>\n";
}
print '<tr class="oddeven">';
print '<td class="right" colspan="3">'.$langs->trans("Total").':</td>'."\n";
print '<td class="right nowraponall amount"><strong>'.price($debit).'</strong></td>';
print '<td class="right nowraponall amount"><strong>'.price($credit).'</strong></td>';
print '<td colspan="6"></td>';
print "</tr>\n";
print '<tr class="oddeven">';
print '<td class="right" colspan="3">'.$langs->trans("Balancing").':</td>'."\n";
print '<td colspan="2">&nbsp;</td>';
print '<td class="right nowraponall amount"><strong>'.price($credit - $debit).'</strong></td>';
print '<td colspan="4"></td>';
print "</tr>\n";
print "</table>";
print '<div class="tabsAction tabsActionNoBottom">'."\n";
print $letteringbutton;
print '</div>';
print "</form>";
$db->free($resql);
} else {
dol_print_error($db);
}
// End of page
llxFooter();
$db->close();

View File

@ -64,6 +64,10 @@ class AccountancyExport
public static $EXPORT_TYPE_FEC = 1000; public static $EXPORT_TYPE_FEC = 1000;
public static $EXPORT_TYPE_FEC2 = 1010; public static $EXPORT_TYPE_FEC2 = 1010;
/**
* @var DoliDB Database handler
*/
public $db;
/** /**
* @var string[] Error codes (or messages) * @var string[] Error codes (or messages)
@ -915,7 +919,7 @@ class AccountancyExport
print "Montantdevise".$separator; print "Montantdevise".$separator;
print "Idevise".$separator; print "Idevise".$separator;
print "DateLimitReglmt".$separator; print "DateLimitReglmt".$separator;
print "NumFacture".$separator; print "NumFacture";
print $end_line; print $end_line;
foreach ($objectLines as $line) { foreach ($objectLines as $line) {
@ -997,13 +1001,13 @@ class AccountancyExport
print $line->multicurrency_amount . $separator; print $line->multicurrency_amount . $separator;
// FEC:Idevise // FEC:Idevise
print $line->multicurrency_code.$separator; print $line->multicurrency_code . $separator;
// FEC_suppl:DateLimitReglmt // FEC_suppl:DateLimitReglmt
print $date_limit_payment; print $date_limit_payment . $separator;
// FEC_suppl:NumFacture // FEC_suppl:NumFacture
print dol_trunc(self::toAnsi($refInvoice), 17, 'right', 'UTF-8', 1) . $separator; print dol_trunc(self::toAnsi($refInvoice), 17, 'right', 'UTF-8', 1);
print $end_line; print $end_line;
} }
@ -1042,7 +1046,7 @@ class AccountancyExport
print "Montantdevise".$separator; print "Montantdevise".$separator;
print "Idevise".$separator; print "Idevise".$separator;
print "DateLimitReglmt".$separator; print "DateLimitReglmt".$separator;
print "NumFacture".$separator; print "NumFacture";
print $end_line; print $end_line;
foreach ($objectLines as $line) { foreach ($objectLines as $line) {
@ -1127,10 +1131,10 @@ class AccountancyExport
print $line->multicurrency_code . $separator; print $line->multicurrency_code . $separator;
// FEC_suppl:DateLimitReglmt // FEC_suppl:DateLimitReglmt
print $date_limit_payment; print $date_limit_payment . $separator;
// FEC_suppl:NumFacture // FEC_suppl:NumFacture
print dol_trunc(self::toAnsi($refInvoice), 17, 'right', 'UTF-8', 1) . $separator; print dol_trunc(self::toAnsi($refInvoice), 17, 'right', 'UTF-8', 1);
print $end_line; print $end_line;

View File

@ -29,7 +29,7 @@
/** /**
* \file htdocs/accountancy/class/accountancyimport.class.php * \file htdocs/accountancy/class/accountancyimport.class.php
* \ingroup Accountancy (Double entries) * \ingroup Accountancy (Double entries)
* \brief Class accountancy import * \brief Class with methods for accountancy import
*/ */
@ -39,63 +39,104 @@
*/ */
class AccountancyImport class AccountancyImport
{ {
/**
* @var DoliDB Database handler
*/
public $db;
/**
* Constructor
*
* @param DoliDb $db Database handler
*/
public function __construct(DoliDB $db)
{
$this->db = $db;
}
/**
* Clean amount
*
* @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]...
* @param array $listfields Fields list to add
* @param int $record_key Record key
* @return mixed Value
*/
public function cleanAmount(&$arrayrecord, $listfields, $record_key)
{
$value_trim = trim($arrayrecord[$record_key]['val']);
return floatval($value_trim);
}
/**
* Clean value with trim
*
* @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]...
* @param array $listfields Fields list to add
* @param int $record_key Record key
* @return mixed Value
*/
public function cleanValue(&$arrayrecord, $listfields, $record_key)
{
return trim($arrayrecord[$record_key]['val']);
}
/** /**
* Compute amount * Compute amount
* *
* @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... * @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]...
* @param string $fieldname Field name with alias
* @param array $listfields Fields list to add * @param array $listfields Fields list to add
* @param array $listvalues Values list to add * @param int $record_key Record key
* @return int <0 if KO, >0 if OK * @return mixed Value
*/ */
public function computeAmount(&$arrayrecord, $fieldname, &$listfields, &$listvalues) public function computeAmount(&$arrayrecord, $listfields, $record_key)
{ {
$fieldArr = explode('.', $fieldname); // get fields indexes
if (count($fieldArr) > 0) { $field_index_list = array_flip($listfields);
$fieldname = $fieldArr[1]; if (isset($field_index_list['debit']) && isset($field_index_list['credit'])) {
$debit_index = $field_index_list['debit'];
$credit_index = $field_index_list['credit'];
$debit = floatval($arrayrecord[$debit_index]['val']);
$credit = floatval($arrayrecord[$credit_index]['val']);
if (!empty($debit)) {
$amount = $debit;
} else {
$amount = $credit;
}
return "'" . $this->db->escape(abs($amount)) . "'";
} }
$debit = trim($arrayrecord[11]['val']); return "''";
$credit = trim($arrayrecord[12]['val']);
if (!empty($debit)) {
$amount = $debit;
} else {
$amount = $credit;
}
$listfields[] = $fieldname;
$listvalues[] = "'" . abs($amount) . "'";
return 1;
} }
/** /**
* Compute sens * Compute direction
* *
* @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... * @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]...
* @param string $fieldname Field name with alias
* @param array $listfields Fields list to add * @param array $listfields Fields list to add
* @param array $listvalues Values list to add * @param int $record_key Record key
* @return int <0 if KO, >0 if OK * @return mixed Value
*/ */
public function computeDirection(&$arrayrecord, $fieldname, &$listfields, &$listvalues) public function computeDirection(&$arrayrecord, $listfields, $record_key)
{ {
$fieldArr = explode('.', $fieldname); $field_index_list = array_flip($listfields);
if (count($fieldArr) > 0) { if (isset($field_index_list['debit'])) {
$fieldname = $fieldArr[1]; $debit_index = $field_index_list['debit'];
$debit = floatval($arrayrecord[$debit_index]['val']);
if (!empty($debit)) {
$sens = 'D';
} else {
$sens = 'C';
}
return "'" . $this->db->escape($sens) . "'";
} }
$debit = trim($arrayrecord[11]['val']); return "''";
if (!empty($debit)) {
$sens = 'D';
} else {
$sens = 'C';
}
$listfields[] = $fieldname;
$listvalues[] = "'" . $sens . "'";
return 1;
} }
} }

View File

@ -29,6 +29,7 @@
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
/** /**
* Class to manage accounting accounts * Class to manage accounting accounts
*/ */
@ -108,6 +109,11 @@ class AccountingAccount extends CommonObject
*/ */
public $account_category; public $account_category;
/**
* @var int Label category account
*/
public $account_category_label;
/** /**
* @var int Status * @var int Status
*/ */
@ -148,6 +154,11 @@ class AccountingAccount extends CommonObject
*/ */
private $accountingaccount_codetotid_cache = array(); private $accountingaccount_codetotid_cache = array();
const STATUS_ENABLED = 1;
const STATUS_DISABLED = 0;
/** /**
* Constructor * Constructor
* *
@ -158,7 +169,7 @@ class AccountingAccount extends CommonObject
global $conf; global $conf;
$this->db = $db; $this->db = $db;
$this->next_prev_filter = "fk_pcg_version IN (SELECT pcg_version FROM ".MAIN_DB_PREFIX."accounting_system WHERE rowid=".((int) $conf->global->CHARTOFACCOUNTS).")"; // Used to add a filter in Form::showrefnav method $this->next_prev_filter = "fk_pcg_version IN (SELECT pcg_version FROM ".MAIN_DB_PREFIX."accounting_system WHERE rowid = ".((int) $conf->global->CHARTOFACCOUNTS).")"; // Used to add a filter in Form::showrefnav method
} }
/** /**
@ -166,7 +177,7 @@ class AccountingAccount extends CommonObject
* *
* @param int $rowid Id * @param int $rowid Id
* @param string $account_number Account number * @param string $account_number Account number
* @param int|boolean $limittocurrentchart 1 or true=Load record only if it is into current active char of account * @param int|boolean $limittocurrentchart 1 or true=Load record only if it is into current active chart of account
* @param string $limittoachartaccount 'ABC'=Load record only if it is into chart account with code 'ABC' (better and faster than previous parameter if you have chart of account code). * @param string $limittoachartaccount 'ABC'=Load record only if it is into chart account with code 'ABC' (better and faster than previous parameter if you have chart of account code).
* @return int <0 if KO, 0 if not found, Id of record if OK and found * @return int <0 if KO, 0 if not found, Id of record if OK and found
*/ */
@ -187,13 +198,14 @@ class AccountingAccount extends CommonObject
$sql .= " AND a.entity = ".$conf->entity; $sql .= " AND a.entity = ".$conf->entity;
} }
if (!empty($limittocurrentchart)) { if (!empty($limittocurrentchart)) {
$sql .= ' AND a.fk_pcg_version IN (SELECT pcg_version FROM '.MAIN_DB_PREFIX.'accounting_system WHERE rowid='.$this->db->escape($conf->global->CHARTOFACCOUNTS).')'; $sql .= ' AND a.fk_pcg_version IN (SELECT pcg_version FROM '.MAIN_DB_PREFIX.'accounting_system WHERE rowid = '.((int) $conf->global->CHARTOFACCOUNTS).')';
} }
if (!empty($limittoachartaccount)) { if (!empty($limittoachartaccount)) {
$sql .= " AND a.fk_pcg_version = '".$this->db->escape($limittoachartaccount)."'"; $sql .= " AND a.fk_pcg_version = '".$this->db->escape($limittoachartaccount)."'";
} }
dol_syslog(get_class($this)."::fetch", LOG_DEBUG); dol_syslog(get_class($this)."::fetch rowid=".$rowid." account_number=".$account_number, LOG_DEBUG);
$result = $this->db->query($sql); $result = $this->db->query($sql);
if ($result) { if ($result) {
$obj = $this->db->fetch_object($result); $obj = $this->db->fetch_object($result);
@ -464,7 +476,7 @@ class AccountingAccount extends CommonObject
*/ */
public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1, $withcompletelabel = 0, $option = '') public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1, $withcompletelabel = 0, $option = '')
{ {
global $langs, $conf; global $langs, $conf, $hookmanager;
require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
if (!empty($conf->dol_no_mouse_hover)) { if (!empty($conf->dol_no_mouse_hover)) {
@ -495,7 +507,7 @@ class AccountingAccount extends CommonObject
$url .= '&save_lastsearch_values=1'; $url .= '&save_lastsearch_values=1';
} }
$picto = 'billr'; $picto = 'accounting_account';
$label = ''; $label = '';
if (empty($this->labelshort) || $withcompletelabel == 1) { if (empty($this->labelshort) || $withcompletelabel == 1) {
@ -549,13 +561,22 @@ class AccountingAccount extends CommonObject
if ($withpicto != 2) { if ($withpicto != 2) {
$result .= $linkstart . $label_link . $linkend; $result .= $linkstart . $label_link . $linkend;
} }
global $action;
$hookmanager->initHooks(array($this->element . 'dao'));
$parameters = array('id'=>$this->id, 'getnomurl' => &$result);
$reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook > 0) {
$result = $hookmanager->resPrint;
} else {
$result .= $hookmanager->resPrint;
}
return $result; return $result;
} }
/** /**
* Information on record * Information on record
* *
* @param int $id of record * @param int $id ID of record
* @return void * @return void
*/ */
public function info($id) public function info($id)
@ -685,49 +706,22 @@ class AccountingAccount extends CommonObject
public function LibStatut($status, $mode = 0) public function LibStatut($status, $mode = 0)
{ {
// phpcs:enable // phpcs:enable
global $langs; if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
$langs->loadLangs(array("users")); global $langs;
$langs->load("users");
if ($mode == 0) { $this->labelStatus[self::STATUS_ENABLED] = $langs->transnoentitiesnoconv('Enabled');
if ($status == 1) { $this->labelStatus[self::STATUS_DISABLED] = $langs->transnoentitiesnoconv('Disabled');
return $langs->trans('Enabled'); $this->labelStatusShort[self::STATUS_ENABLED] = $langs->transnoentitiesnoconv('Enabled');
} elseif ($status == 0) { $this->labelStatusShort[self::STATUS_DISABLED] = $langs->transnoentitiesnoconv('Disabled');
return $langs->trans('Disabled');
}
} elseif ($mode == 1) {
if ($status == 1) {
return $langs->trans('Enabled');
} elseif ($status == 0) {
return $langs->trans('Disabled');
}
} elseif ($mode == 2) {
if ($status == 1) {
return img_picto($langs->trans('Enabled'), 'statut4') . ' ' . $langs->trans('Enabled');
} elseif ($status == 0) {
return img_picto($langs->trans('Disabled'), 'statut5') . ' ' . $langs->trans('Disabled');
}
} elseif ($mode == 3) {
if ($status == 1) {
return img_picto($langs->trans('Enabled'), 'statut4');
} elseif ($status == 0) {
return img_picto($langs->trans('Disabled'), 'statut5');
}
} elseif ($mode == 4) {
if ($status == 1) {
return img_picto($langs->trans('Enabled'), 'statut4') . ' ' . $langs->trans('Enabled');
} elseif ($status == 0) {
return img_picto($langs->trans('Disabled'), 'statut5') . ' ' . $langs->trans('Disabled');
}
} elseif ($mode == 5) {
if ($status == 1) {
return $langs->trans('Enabled') . ' ' . img_picto($langs->trans('Enabled'), 'statut4');
} elseif ($status == 0) {
return $langs->trans('Disabled') . ' ' . img_picto($langs->trans('Disabled'), 'statut5');
}
} }
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps $statusType = 'status4';
if ($status == self::STATUS_DISABLED) {
$statusType = 'status5';
}
return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
}
/** /**
* Return Suggest accounting accounts to bind * Return Suggest accounting accounts to bind
@ -866,8 +860,8 @@ class AccountingAccount extends CommonObject
// Level 3 (define $code_t): Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) // Level 3 (define $code_t): Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding)
if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) {
if (!empty($buyer->code_compta)) { if (!empty($buyer->code_compta_product)) {
$code_t = $buyer->code_compta; $code_t = $buyer->code_compta_product;
$suggestedid = $accountingAccount['thirdparty']; $suggestedid = $accountingAccount['thirdparty'];
$suggestedaccountingaccountfor = 'thridparty'; $suggestedaccountingaccountfor = 'thridparty';
} }

View File

@ -1,5 +1,5 @@
<?php <?php
/* Copyright (C) 2017 Alexandre Spangaro <aspangaro@open-dsi.fr> /* Copyright (C) 2017-2022 OpenDSI <support@open-dsi.fr>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -81,6 +81,24 @@ class AccountingJournal extends CommonObject
*/ */
public $lines; public $lines;
/**
* @var array Accounting account cached
*/
static public $accounting_account_cached = array();
/**
* @var array Nature mapping
*/
static public $nature_maps = array(
1 => 'variousoperations',
2 => 'sells',
3 => 'purchases',
4 => 'bank',
5 => 'expensereports',
8 => 'inventories',
9 => 'hasnew',
);
/** /**
* Constructor * Constructor
* *
@ -221,7 +239,7 @@ class AccountingJournal extends CommonObject
*/ */
public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0) public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0)
{ {
global $langs, $conf, $user; global $langs, $conf, $user, $hookmanager;
if (!empty($conf->dol_no_mouse_hover)) { if (!empty($conf->dol_no_mouse_hover)) {
$notooltip = 1; // Force disable tooltips $notooltip = 1; // Force disable tooltips
@ -276,6 +294,15 @@ class AccountingJournal extends CommonObject
} }
$result .= $linkend; $result .= $linkend;
global $action;
$hookmanager->initHooks(array('accountingjournaldao'));
$parameters = array('id'=>$this->id, 'getnomurl' => &$result);
$reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook > 0) {
$result = $hookmanager->resPrint;
} else {
$result .= $hookmanager->resPrint;
}
return $result; return $result;
} }
@ -336,4 +363,680 @@ class AccountingJournal extends CommonObject
} }
} }
} }
/**
* Get journal data
*
* @param User $user User who get infos
* @param string $type Type data returned ('view', 'bookkeeping', 'csv')
* @param int $date_start Filter 'start date'
* @param int $date_end Filter 'end date'
* @param string $in_bookkeeping Filter 'in bookkeeping' ('already', 'notyet')
* @return array|int <0 if KO, >0 if OK
*/
public function getData(User $user, $type = 'view', $date_start = null, $date_end = null, $in_bookkeeping = 'notyet')
{
global $hookmanager;
// Clean parameters
if (empty($type)) $type = 'view';
if (empty($in_bookkeeping)) $in_bookkeeping = 'notyet';
// Hook
if (!is_object($hookmanager)) {
include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
$hookmanager = new HookManager($this->db);
}
$data = array();
$hookmanager->initHooks(array('accountingjournaldao'));
$parameters = array('data' => &$data, 'user' => $user, 'type' => $type, 'date_start' => $date_start, 'date_end' => $date_end, 'in_bookkeeping' => $in_bookkeeping);
$reshook = $hookmanager->executeHooks('getData', $parameters, $this); // Note that $action and $object may have been
if ($reshook < 0) {
$this->error = $hookmanager->error;
$this->errors = $hookmanager->errors;
return -1;
} elseif (empty($reshook)) {
switch ($this->nature) {
case 1: // Various Journal
$data = $this->getAssetData($user, $type, $date_start, $date_end, $in_bookkeeping);
break;
// case 2: // Sells Journal
// case 3: // Purchases Journal
// case 4: // Bank Journal
// case 5: // Expense reports Journal
// case 8: // Inventory Journal
// case 9: // hasnew Journal
}
}
return $data;
}
/**
* Get asset data for various journal
*
* @param User $user User who get infos
* @param string $type Type data returned ('view', 'bookkeeping', 'csv')
* @param int $date_start Filter 'start date'
* @param int $date_end Filter 'end date'
* @param string $in_bookkeeping Filter 'in bookkeeping' ('already', 'notyet')
* @return array|int <0 if KO, >0 if OK
*/
public function getAssetData(User $user, $type = 'view', $date_start = null, $date_end = null, $in_bookkeeping = 'notyet')
{
global $conf, $langs;
if (empty($conf->asset->enabled)) {
return array();
}
require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php';
require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php';
require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php';
$langs->loadLangs(array("assets"));
// Clean parameters
if (empty($type)) $type = 'view';
if (empty($in_bookkeeping)) $in_bookkeeping = 'notyet';
$sql = "";
if ($in_bookkeeping == 'already' || $in_bookkeeping == 'notyet') {
$sql .= "WITH in_accounting_bookkeeping(fk_docdet) AS (";
$sql .= " SELECT DISTINCT fk_docdet";
$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping";
$sql .= " WHERE doc_type = 'asset'";
$sql .= ")";
}
$sql .= "SELECT ad.fk_asset AS rowid, a.ref AS asset_ref, a.label AS asset_label, a.acquisition_value_ht AS asset_acquisition_value_ht";
$sql .= ", a.disposal_date AS asset_disposal_date, a.disposal_amount_ht AS asset_disposal_amount_ht, a.disposal_subject_to_vat AS asset_disposal_subject_to_vat";
$sql .= ", ad.rowid AS depreciation_id, ad.depreciation_mode, ad.ref AS depreciation_ref, ad.depreciation_date, ad.depreciation_ht, ad.accountancy_code_debit, ad.accountancy_code_credit";
$sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation as ad";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "asset as a ON a.rowid = ad.fk_asset";
if ($in_bookkeeping == 'already' || $in_bookkeeping == 'notyet') {
$sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid";
}
$sql .= " WHERE a.entity IN (" . getEntity('asset', 0) . ')'; // We don't share object for accountancy, we use source object sharing
$sql .= " AND ad.ref != ''"; // not reversal lines
if ($date_start && $date_end) {
$sql .= " AND ad.depreciation_date >= '" . $this->db->idate($date_start) . "' AND ad.depreciation_date <= '" . $this->db->idate($date_end) . "'";
}
// Define begin binding date
if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) {
$sql .= " AND ad.depreciation_date >= '" . $this->db->idate($conf->global->ACCOUNTING_DATE_START_BINDING) . "'";
}
// Already in bookkeeping or not
if ($in_bookkeeping == 'already' || $in_bookkeeping == 'notyet') {
$sql .= " AND iab.fk_docdet IS" . ($in_bookkeeping == 'already' ? " NOT" : "") . " NULL";
}
$sql .= " ORDER BY ad.depreciation_date";
dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$this->errors[] = $this->db->lasterror();
return -1;
}
$pre_data = array(
'elements' => array(),
);
while ($obj = $this->db->fetch_object($resql)) {
if (!isset($pre_data['elements'][$obj->rowid])) {
$pre_data['elements'][$obj->rowid] = array(
'ref' => $obj->asset_ref,
'label' => $obj->asset_label,
'acquisition_value_ht' => $obj->asset_acquisition_value_ht,
'depreciation' => array(),
);
// Disposal infos
if (isset($obj->asset_disposal_date)) {
$pre_data['elements'][$obj->rowid]['disposal'] = array(
'date' => $this->db->jdate($obj->asset_disposal_date),
'amount' => $obj->asset_disposal_amount_ht,
'subject_to_vat' => !empty($obj->asset_disposal_subject_to_vat),
);
}
}
$compta_debit = empty($obj->accountancy_code_debit) ? 'NotDefined' : $obj->accountancy_code_debit;
$compta_credit = empty($obj->accountancy_code_credit) ? 'NotDefined' : $obj->accountancy_code_credit;
$pre_data['elements'][$obj->rowid]['depreciation'][$obj->depreciation_id] = array(
'date' => $this->db->jdate($obj->depreciation_date),
'ref' => $obj->depreciation_ref,
'lines' => array(
$compta_debit => -$obj->depreciation_ht,
$compta_credit => $obj->depreciation_ht,
),
);
}
$disposal_ref = $langs->transnoentitiesnoconv('AssetDisposal');
$journal = $this->code;
$journal_label = $this->label;
$journal_label_formatted = $langs->transnoentities($journal_label);
$now = dol_now();
$element_static = new Asset($this->db);
$journal_data = array();
foreach ($pre_data['elements'] as $pre_data_id => $pre_data_info) {
$element_static->id = $pre_data_id;
$element_static->ref = (string) $pre_data_info["ref"];
$element_static->label = (string) $pre_data_info["label"];
$element_static->acquisition_value_ht = $pre_data_info["acquisition_value_ht"];
$element_link = $element_static->getNomUrl(1, 'with_label');
$element_name_formatted_0 = dol_trunc($element_static->label, 16);
$element_name_formatted_1 = utf8_decode(dol_trunc($element_static->label, 32));
$element_name_formatted_2 = utf8_decode(dol_trunc($element_static->label, 16));
$label_operation = $element_static->getNomUrl(0, 'label', 16);
$element = array(
'ref' => dol_trunc($element_static->ref, 16, 'right', 'UTF-8', 1),
'error' => $pre_data_info['error'],
'blocks' => array(),
);
// Depreciation lines
//--------------------
foreach ($pre_data_info['depreciation'] as $depreciation_id => $line) {
$depreciation_ref = $line["ref"];
$depreciation_date = $line["date"];
$depreciation_date_formatted = dol_print_date($depreciation_date, 'day');
// lines
$blocks = array();
foreach ($line['lines'] as $account => $mt) {
$account_infos = $this->getAccountingAccountInfos($account);
if ($type == 'view') {
$account_to_show = length_accounta($account);
if (($account_to_show == "") || $account_to_show == 'NotDefined') {
$account_to_show = '<span class="error">' . $langs->trans("AssetInAccountNotDefined") . '</span>';
}
$blocks[] = array(
'date' => $depreciation_date_formatted,
'piece' => $element_link,
'account_accounting' => $account_to_show,
'subledger_account' => '',
'label_operation' => $label_operation . ' - ' . $depreciation_ref,
'debit' => $mt < 0 ? price(-$mt) : '',
'credit' => $mt >= 0 ? price($mt) : '',
);
} elseif ($type == 'bookkeeping') {
if ($account_infos['found']) {
$blocks[] = array(
'doc_date' => $depreciation_date,
'date_lim_reglement' => '',
'doc_ref' => $element_static->ref,
'date_creation' => $now,
'doc_type' => 'asset',
'fk_doc' => $element_static->id,
'fk_docdet' => $depreciation_id, // Useless, can be several lines that are source of this record to add
'thirdparty_code' => '',
'subledger_account' => '',
'subledger_label' => '',
'numero_compte' => $account,
'label_compte' => $account_infos['label'],
'label_operation' => $element_name_formatted_0 . ' - ' . $depreciation_ref,
'montant' => $mt,
'sens' => $mt < 0 ? 'D' : 'C',
'debit' => $mt < 0 ? -$mt : 0,
'credit' => $mt >= 0 ? $mt : 0,
'code_journal' => $journal,
'journal_label' => $journal_label_formatted,
'piece_num' => '',
'import_key' => '',
'fk_user_author' => $user->id,
'entity' => $conf->entity,
);
}
} else { // $type == 'csv'
$blocks[] = array(
$depreciation_date, // Date
$element_static->ref, // Piece
$account_infos['code_formatted_1'], // AccountAccounting
$element_name_formatted_0 . ' - ' . $depreciation_ref, // LabelOperation
$mt < 0 ? price(-$mt) : '', // Debit
$mt >= 0 ? price($mt) : '', // Credit
);
}
}
$element['blocks'][] = $blocks;
}
// Disposal line
//--------------------
if (!empty($pre_data_info['disposal'])) {
$disposal_date = $pre_data_info['disposal']['date'];
if ((!($date_start && $date_end) || ($date_start <= $disposal_date && $disposal_date <= $date_end)) &&
(empty($conf->global->ACCOUNTING_DATE_START_BINDING) || $conf->global->ACCOUNTING_DATE_START_BINDING <= $disposal_date)
) {
$disposal_amount = $pre_data_info['disposal']['amount'];
$disposal_subject_to_vat = $pre_data_info['disposal']['subject_to_vat'];
$disposal_date_formatted = dol_print_date($disposal_date, 'day');
$disposal_vat = $conf->global->ASSET_DISPOSAL_VAT > 0 ? $conf->global->ASSET_DISPOSAL_VAT : 20;
// Get accountancy codes
//---------------------------
require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php';
$accountancy_codes = new AssetAccountancyCodes($this->db);
$result = $accountancy_codes->fetchAccountancyCodes($element_static->id);
if ($result < 0) {
$element['error'] = $accountancy_codes->errorsToString();
} else {
// Get last depreciation cumulative amount
$element_static->fetchDepreciationLines();
foreach ($element_static->depreciation_lines as $mode_key => $depreciation_lines) {
$accountancy_codes_list = $accountancy_codes->accountancy_codes[$mode_key];
if (!isset($accountancy_codes_list['value_asset_sold'])) {
continue;
}
$accountancy_code_value_asset_sold = empty($accountancy_codes_list['value_asset_sold']) ? 'NotDefined' : $accountancy_codes_list['value_asset_sold'];
$accountancy_code_depreciation_asset = empty($accountancy_codes_list['depreciation_asset']) ? 'NotDefined' : $accountancy_codes_list['depreciation_asset'];
$accountancy_code_asset = empty($accountancy_codes_list['asset']) ? 'NotDefined' : $accountancy_codes_list['asset'];
$accountancy_code_receivable_on_assignment = empty($accountancy_codes_list['receivable_on_assignment']) ? 'NotDefined' : $accountancy_codes_list['receivable_on_assignment'];
$accountancy_code_vat_collected = empty($accountancy_codes_list['vat_collected']) ? 'NotDefined' : $accountancy_codes_list['vat_collected'];
$accountancy_code_proceeds_from_sales = empty($accountancy_codes_list['proceeds_from_sales']) ? 'NotDefined' : $accountancy_codes_list['proceeds_from_sales'];
$last_cumulative_amount_ht = 0;
$depreciated_ids = array_keys($pre_data_info['depreciation']);
foreach ($depreciation_lines as $line) {
$last_cumulative_amount_ht = $line['cumulative_depreciation_ht'];
if (!in_array($line['id'], $depreciated_ids) && empty($line['bookkeeping']) && !empty($line['ref'])) {
break;
}
}
$lines = array();
$lines[0][$accountancy_code_value_asset_sold] = -($element_static->acquisition_value_ht - $last_cumulative_amount_ht);
$lines[0][$accountancy_code_depreciation_asset] = -$last_cumulative_amount_ht;
$lines[0][$accountancy_code_asset] = $element_static->acquisition_value_ht;
$disposal_amount_vat = $disposal_subject_to_vat ? (double) price2num($disposal_amount * $disposal_vat / 100, 'MT') : 0;
$lines[1][$accountancy_code_receivable_on_assignment] = -($disposal_amount + $disposal_amount_vat);
if ($disposal_subject_to_vat) $lines[1][$accountancy_code_vat_collected] = $disposal_amount_vat;
$lines[1][$accountancy_code_proceeds_from_sales] = $disposal_amount;
foreach ($lines as $lines_block) {
$blocks = array();
foreach ($lines_block as $account => $mt) {
$account_infos = $this->getAccountingAccountInfos($account);
if ($type == 'view') {
$account_to_show = length_accounta($account);
if (($account_to_show == "") || $account_to_show == 'NotDefined') {
$account_to_show = '<span class="error">' . $langs->trans("AssetInAccountNotDefined") . '</span>';
}
$blocks[] = array(
'date' => $disposal_date_formatted,
'piece' => $element_link,
'account_accounting' => $account_to_show,
'subledger_account' => '',
'label_operation' => $label_operation . ' - ' . $disposal_ref,
'debit' => $mt < 0 ? price(-$mt) : '',
'credit' => $mt >= 0 ? price($mt) : '',
);
} elseif ($type == 'bookkeeping') {
if ($account_infos['found']) {
$blocks[] = array(
'doc_date' => $disposal_date,
'date_lim_reglement' => '',
'doc_ref' => $element_static->ref,
'date_creation' => $now,
'doc_type' => 'asset',
'fk_doc' => $element_static->id,
'fk_docdet' => 0, // Useless, can be several lines that are source of this record to add
'thirdparty_code' => '',
'subledger_account' => '',
'subledger_label' => '',
'numero_compte' => $account,
'label_compte' => $account_infos['label'],
'label_operation' => $element_name_formatted_0 . ' - ' . $disposal_ref,
'montant' => $mt,
'sens' => $mt < 0 ? 'D' : 'C',
'debit' => $mt < 0 ? -$mt : 0,
'credit' => $mt >= 0 ? $mt : 0,
'code_journal' => $journal,
'journal_label' => $journal_label_formatted,
'piece_num' => '',
'import_key' => '',
'fk_user_author' => $user->id,
'entity' => $conf->entity,
);
}
} else { // $type == 'csv'
$blocks[] = array(
$disposal_date, // Date
$element_static->ref, // Piece
$account_infos['code_formatted_1'], // AccountAccounting
$element_name_formatted_0 . ' - ' . $disposal_ref, // LabelOperation
$mt < 0 ? price(-$mt) : '', // Debit
$mt >= 0 ? price($mt) : '', // Credit
);
}
}
$element['blocks'][] = $blocks;
}
}
}
}
}
$journal_data[$pre_data_id] = $element;
}
unset($pre_data);
return $journal_data;
}
/**
* Write bookkeeping
*
* @param User $user User who write in the bookkeeping
* @param array $journal_data Journal data to write in the bookkeeping
* $journal_data = array(
* id_element => array(
* 'ref' => 'ref',
* 'error' => '',
* 'blocks' => array(
* pos_block => array(
* num_line => array(
* 'doc_date' => '',
* 'date_lim_reglement' => '',
* 'doc_ref' => '',
* 'date_creation' => '',
* 'doc_type' => '',
* 'fk_doc' => '',
* 'fk_docdet' => '',
* 'thirdparty_code' => '',
* 'subledger_account' => '',
* 'subledger_label' => '',
* 'numero_compte' => '',
* 'label_compte' => '',
* 'label_operation' => '',
* 'montant' => '',
* 'sens' => '',
* 'debit' => '',
* 'credit' => '',
* 'code_journal' => '',
* 'journal_label' => '',
* 'piece_num' => '',
* 'import_key' => '',
* 'fk_user_author' => '',
* 'entity' => '',
* ),
* ),
* ),
* ),
* );
* @param int $max_nb_errors Nb error authorized before stop the process
* @return int <0 if KO, >0 if OK
*/
public function writeIntoBookkeeping(User $user, &$journal_data = array(), $max_nb_errors = 10)
{
global $conf, $langs, $hookmanager;
require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php';
// Hook
if (!is_object($hookmanager)) {
include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
$hookmanager = new HookManager($this->db);
}
$error = 0;
$hookmanager->initHooks(array('accountingjournaldao'));
$parameters = array('journal_data' => &$journal_data);
$reshook = $hookmanager->executeHooks('writeBookkeeping', $parameters, $this); // Note that $action and $object may have been
if ($reshook < 0) {
$this->error = $hookmanager->error;
$this->errors = $hookmanager->errors;
return -1;
} elseif (empty($reshook)) {
// Clean parameters
$journal_data = is_array($journal_data) ? $journal_data : array();
foreach ($journal_data as $element_id => $element) {
$error_for_line = 0;
$total_credit = 0;
$total_debit = 0;
$this->db->begin();
if ($element['error'] == 'somelinesarenotbound') {
$error++;
$error_for_line++;
$this->errors[] = $langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $element['ref']);
}
if (!$error_for_line) {
foreach ($element['blocks'] as $lines) {
foreach ($lines as $line) {
$bookkeeping = new BookKeeping($this->db);
$bookkeeping->doc_date = $line['doc_date'];
$bookkeeping->date_lim_reglement = $line['date_lim_reglement'];
$bookkeeping->doc_ref = $line['doc_ref'];
$bookkeeping->date_creation = $line['date_creation']; // not used
$bookkeeping->doc_type = $line['doc_type'];
$bookkeeping->fk_doc = $line['fk_doc'];
$bookkeeping->fk_docdet = $line['fk_docdet'];
$bookkeeping->thirdparty_code = $line['thirdparty_code'];
$bookkeeping->subledger_account = $line['subledger_account'];
$bookkeeping->subledger_label = $line['subledger_label'];
$bookkeeping->numero_compte = $line['numero_compte'];
$bookkeeping->label_compte = $line['label_compte'];
$bookkeeping->label_operation = $line['label_operation'];
$bookkeeping->montant = $line['montant'];
$bookkeeping->sens = $line['sens'];
$bookkeeping->debit = $line['debit'];
$bookkeeping->credit = $line['credit'];
$bookkeeping->code_journal = $line['code_journal'];
$bookkeeping->journal_label = $line['journal_label'];
$bookkeeping->piece_num = $line['piece_num'];
$bookkeeping->import_key = $line['import_key'];
$bookkeeping->fk_user_author = $user->id;
$bookkeeping->entity = $conf->entity;
$total_debit += $bookkeeping->debit;
$total_credit += $bookkeeping->credit;
$result = $bookkeeping->create($user);
if ($result < 0) {
if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
$error++;
$error_for_line++;
$journal_data[$element_id]['error'] = 'alreadyjournalized';
} else {
$error++;
$error_for_line++;
$journal_data[$element_id]['error'] = 'other';
$this->errors[] = $bookkeeping->errorsToString();
}
}
//
// if (!$error_for_line && !empty($conf->asset->enabled) && $this->nature == 1 && $bookkeeping->fk_doc > 0) {
// // Set last cumulative depreciation
// require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php';
// $asset = new Asset($this->db);
// $result = $asset->setLastCumulativeDepreciation($bookkeeping->fk_doc);
// if ($result < 0) {
// $error++;
// $error_for_line++;
// $journal_data[$element_id]['error'] = 'other';
// $this->errors[] = $asset->errorsToString();
// }
// }
}
if ($error_for_line) {
break;
}
}
}
// Protection against a bug on lines before
if (!$error_for_line && (price2num($total_debit, 'MT') != price2num($total_credit, 'MT'))) {
$error++;
$error_for_line++;
$journal_data[$element_id]['error'] = 'amountsnotbalanced';
$this->errors[] = 'Try to insert a non balanced transaction in book for ' . $element['blocks'] . '. Canceled. Surely a bug.';
}
if (!$error_for_line) {
$this->db->commit();
} else {
$this->db->rollback();
if ($error >= $max_nb_errors) {
$this->errors[] = $langs->trans("ErrorTooManyErrorsProcessStopped");
break; // Break in the foreach
}
}
}
}
return $error ? -$error : 1;
}
/**
* Export journal CSV
* ISO and not UTF8 !
*
* @param array $journal_data Journal data to write in the bookkeeping
* $journal_data = array(
* id_element => array(
* 'continue' => false,
* 'blocks' => array(
* pos_block => array(
* num_line => array(
* data to write in the CSV line
* ),
* ),
* ),
* ),
* );
* @param int $search_date_end Search date end
* @param string $sep CSV separator
* @return int|string <0 if KO, >0 if OK
*/
public function exportCsv(&$journal_data = array(), $search_date_end = 0, $sep = '')
{
global $conf, $langs, $hookmanager;
if (empty($sep)) $sep = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV;
$out = '';
// Hook
if (!is_object($hookmanager)) {
include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
$hookmanager = new HookManager($this->db);
}
$hookmanager->initHooks(array('accountingjournaldao'));
$parameters = array('journal_data' => &$journal_data, 'search_date_end' => &$search_date_end, 'sep' => &$sep, 'out' => &$out);
$reshook = $hookmanager->executeHooks('exportCsv', $parameters, $this); // Note that $action and $object may have been
if ($reshook < 0) {
$this->error = $hookmanager->error;
$this->errors = $hookmanager->errors;
return -1;
} elseif (empty($reshook)) {
// Clean parameters
$journal_data = is_array($journal_data) ? $journal_data : array();
// CSV header line
$header = array();
if ($this->nature == 4) {
$header = array(
$langs->transnoentitiesnoconv("BankId"),
$langs->transnoentitiesnoconv("Date"),
$langs->transnoentitiesnoconv("PaymentMode"),
$langs->transnoentitiesnoconv("AccountAccounting"),
$langs->transnoentitiesnoconv("LedgerAccount"),
$langs->transnoentitiesnoconv("SubledgerAccount"),
$langs->transnoentitiesnoconv("Label"),
$langs->transnoentitiesnoconv("Debit"),
$langs->transnoentitiesnoconv("Credit"),
$langs->transnoentitiesnoconv("Journal"),
$langs->transnoentitiesnoconv("Note"),
);
} elseif ($this->nature == 5) {
$header = array(
$langs->transnoentitiesnoconv("Date"),
$langs->transnoentitiesnoconv("Piece"),
$langs->transnoentitiesnoconv("AccountAccounting"),
$langs->transnoentitiesnoconv("LabelOperation"),
$langs->transnoentitiesnoconv("Debit"),
$langs->transnoentitiesnoconv("Credit"),
);
} elseif ($this->nature == 1) {
$header = array(
$langs->transnoentitiesnoconv("Date"),
$langs->transnoentitiesnoconv("Piece"),
$langs->transnoentitiesnoconv("AccountAccounting"),
$langs->transnoentitiesnoconv("LabelOperation"),
$langs->transnoentitiesnoconv("Debit"),
$langs->transnoentitiesnoconv("Credit"),
);
}
if (!empty($header)) $out .= '"' . implode('"' . $sep . '"', $header) . '"' . "\n";
foreach ($journal_data as $element_id => $element) {
foreach ($element['blocks'] as $lines) {
foreach ($lines as $line) {
$out .= '"' . implode('"' . $sep . '"', $line) . '"' . "\n";
}
}
}
}
return $out;
}
/**
* Get accounting account infos
*
* @param string $account Accounting account number
* @return array Accounting account infos
*/
public function getAccountingAccountInfos($account)
{
if (!isset(self::$accounting_account_cached[$account])) {
require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php';
$accountingaccount = new AccountingAccount($this->db);
$result = $accountingaccount->fetch(null, $account, true);
if ($result > 0) {
self::$accounting_account_cached[$account] = array(
'found' => true,
'label' => $accountingaccount->label,
'code_formatted_1' => length_accounta(html_entity_decode($account)),
'label_formatted_1' => utf8_decode(dol_trunc($accountingaccount->label, 32)),
'label_formatted_2' => dol_trunc($accountingaccount->label, 32),
);
} else {
self::$accounting_account_cached[$account] = array(
'found' => false,
'label' => '',
'code_formatted_1' => length_accounta(html_entity_decode($account)),
'label_formatted_1' => '',
'label_formatted_2' => '',
);
}
}
return self::$accounting_account_cached[$account];
}
} }

View File

@ -331,7 +331,7 @@ class BookKeeping extends CommonObject
if (empty($this->piece_num)) { if (empty($this->piece_num)) {
$sqlnum = "SELECT MAX(piece_num)+1 as maxpiecenum"; $sqlnum = "SELECT MAX(piece_num)+1 as maxpiecenum";
$sqlnum .= " FROM ".MAIN_DB_PREFIX.$this->table_element; $sqlnum .= " FROM ".MAIN_DB_PREFIX.$this->table_element;
$sqlnum .= " WHERE entity = ".$conf->entity; // Do not use getEntity for accounting features $sqlnum .= " WHERE entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features
$resqlnum = $this->db->query($sqlnum); $resqlnum = $this->db->query($sqlnum);
if ($resqlnum) { if ($resqlnum) {
@ -460,7 +460,7 @@ class BookKeeping extends CommonObject
{ {
global $db, $conf, $langs; global $db, $conf, $langs;
global $dolibarr_main_authentication, $dolibarr_main_demo; global $dolibarr_main_authentication, $dolibarr_main_demo;
global $menumanager; global $menumanager, $hookmanager;
if (!empty($conf->dol_no_mouse_hover)) { if (!empty($conf->dol_no_mouse_hover)) {
$notooltip = 1; // Force disable tooltips $notooltip = 1; // Force disable tooltips
@ -512,6 +512,15 @@ class BookKeeping extends CommonObject
$result .= $linkend; $result .= $linkend;
//if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : '');
global $action;
$hookmanager->initHooks(array($this->element . 'dao'));
$parameters = array('id'=>$this->id, 'getnomurl' => &$result);
$reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook > 0) {
$result = $hookmanager->resPrint;
} else {
$result .= $hookmanager->resPrint;
}
return $result; return $result;
} }
@ -736,7 +745,7 @@ class BookKeeping extends CommonObject
$sql .= " t.date_validated as date_validation"; $sql .= " t.date_validated as date_validation";
$sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.$mode.' as t'; $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.$mode.' as t';
$sql .= ' WHERE 1 = 1'; $sql .= ' WHERE 1 = 1';
$sql .= " AND entity IN (".getEntity('accountancy').")"; $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features
if (null !== $ref) { if (null !== $ref) {
$sql .= " AND t.ref = '".$this->db->escape($ref)."'"; $sql .= " AND t.ref = '".$this->db->escape($ref)."'";
} else { } else {
@ -881,7 +890,7 @@ class BookKeeping extends CommonObject
} }
$sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t';
$sql .= ' WHERE 1 = 1'; $sql .= ' WHERE 1 = 1';
$sql .= " AND entity IN (".getEntity('accountancy').")"; $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features
if (count($sqlwhere) > 0) { if (count($sqlwhere) > 0) {
$sql .= " AND ".implode(" ".$filtermode." ", $sqlwhere); $sql .= " AND ".implode(" ".$filtermode." ", $sqlwhere);
} }
@ -1013,7 +1022,7 @@ class BookKeeping extends CommonObject
} elseif ($key == 't.numero_compte>=' || $key == 't.numero_compte<=' || $key == 't.subledger_account>=' || $key == 't.subledger_account<=') { } elseif ($key == 't.numero_compte>=' || $key == 't.numero_compte<=' || $key == 't.subledger_account>=' || $key == 't.subledger_account<=') {
$sqlwhere[] = $key.'\''.$this->db->escape($value).'\''; $sqlwhere[] = $key.'\''.$this->db->escape($value).'\'';
} elseif ($key == 't.fk_doc' || $key == 't.fk_docdet' || $key == 't.piece_num') { } elseif ($key == 't.fk_doc' || $key == 't.fk_docdet' || $key == 't.piece_num') {
$sqlwhere[] = $key.'='.$value; $sqlwhere[] = $key.'='.((int) $value);
} elseif ($key == 't.subledger_account' || $key == 't.numero_compte') { } elseif ($key == 't.subledger_account' || $key == 't.numero_compte') {
$sqlwhere[] = $key.' LIKE \''.$this->db->escape($value).'%\''; $sqlwhere[] = $key.' LIKE \''.$this->db->escape($value).'%\'';
} elseif ($key == 't.date_creation>=' || $key == 't.date_creation<=') { } elseif ($key == 't.date_creation>=' || $key == 't.date_creation<=') {
@ -1037,7 +1046,7 @@ class BookKeeping extends CommonObject
} }
} }
} }
$sql .= ' WHERE t.entity IN ('.getEntity('accountancy').')'; $sql .= ' WHERE t.entity = ' . ((int) $conf->entity); // Do not use getEntity for accounting features
if ($showAlreadyExportMovements == 0) { if ($showAlreadyExportMovements == 0) {
$sql .= " AND t.date_export IS NULL"; $sql .= " AND t.date_export IS NULL";
} }
@ -1157,7 +1166,7 @@ class BookKeeping extends CommonObject
} }
} }
} }
$sql .= ' WHERE entity IN ('.getEntity('accountancy').')'; $sql .= ' WHERE entity = ' . ((int) $conf->entity); // Do not use getEntity for accounting features
if (count($sqlwhere) > 0) { if (count($sqlwhere) > 0) {
$sql .= " AND ".implode(" ".$filtermode." ", $sqlwhere); $sql .= " AND ".implode(" ".$filtermode." ", $sqlwhere);
} }
@ -1455,7 +1464,7 @@ class BookKeeping extends CommonObject
*/ */
public function deleteByYearAndJournal($delyear = 0, $journal = '', $mode = '', $delmonth = 0) public function deleteByYearAndJournal($delyear = 0, $journal = '', $mode = '', $delmonth = 0)
{ {
global $langs; global $conf, $langs;
if (empty($delyear) && empty($journal)) { if (empty($delyear) && empty($journal)) {
$this->error = 'ErrorOneFieldRequired'; $this->error = 'ErrorOneFieldRequired';
@ -1476,7 +1485,7 @@ class BookKeeping extends CommonObject
if (!empty($journal)) { if (!empty($journal)) {
$sql .= " AND code_journal = '".$this->db->escape($journal)."'"; $sql .= " AND code_journal = '".$this->db->escape($journal)."'";
} }
$sql .= " AND entity IN (".getEntity('accountancy').")"; $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features
// Exclusion of validated entries at the time of deletion // Exclusion of validated entries at the time of deletion
$sql .= " AND date_validated IS NULL"; $sql .= " AND date_validated IS NULL";
@ -1515,7 +1524,7 @@ class BookKeeping extends CommonObject
$sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element;
$sql .= " WHERE piece_num = ".(int) $piecenum; $sql .= " WHERE piece_num = ".(int) $piecenum;
$sql .= " AND date_validated IS NULL"; // For security, exclusion of validated entries at the time of deletion $sql .= " AND date_validated IS NULL"; // For security, exclusion of validated entries at the time of deletion
$sql .= " AND entity IN (".getEntity('accountancy').")"; $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
@ -1637,7 +1646,7 @@ class BookKeeping extends CommonObject
} }
$sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element.$mode; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element.$mode;
$sql .= " WHERE piece_num = ".((int) $piecenum); $sql .= " WHERE piece_num = ".((int) $piecenum);
$sql .= " AND entity IN (".getEntity('accountancy').")"; $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features
dol_syslog(__METHOD__, LOG_DEBUG); dol_syslog(__METHOD__, LOG_DEBUG);
$result = $this->db->query($sql); $result = $this->db->query($sql);
@ -1675,9 +1684,10 @@ class BookKeeping extends CommonObject
global $conf; global $conf;
$sql = "SELECT MAX(piece_num)+1 as max FROM ".MAIN_DB_PREFIX.$this->table_element.$mode; $sql = "SELECT MAX(piece_num)+1 as max FROM ".MAIN_DB_PREFIX.$this->table_element.$mode;
$sql .= " WHERE entity IN (".getEntity('accountancy').")"; $sql .= " WHERE entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features
dol_syslog(get_class($this)."::getNextNumMvt", LOG_DEBUG);
dol_syslog(get_class($this)."getNextNumMvt", LOG_DEBUG);
$result = $this->db->query($sql); $result = $this->db->query($sql);
if ($result) { if ($result) {
@ -1718,7 +1728,7 @@ class BookKeeping extends CommonObject
} }
$sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element.$mode; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element.$mode;
$sql .= " WHERE piece_num = ".((int) $piecenum); $sql .= " WHERE piece_num = ".((int) $piecenum);
$sql .= " AND entity IN (".getEntity('accountancy').")"; $sql .= " AND entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features
dol_syslog(__METHOD__, LOG_DEBUG); dol_syslog(__METHOD__, LOG_DEBUG);
$result = $this->db->query($sql); $result = $this->db->query($sql);
@ -1781,7 +1791,7 @@ class BookKeeping extends CommonObject
$sql .= " montant as amount, sens, fk_user_author, import_key, code_journal, piece_num,"; $sql .= " montant as amount, sens, fk_user_author, import_key, code_journal, piece_num,";
$sql .= " date_validated as date_validation"; $sql .= " date_validated as date_validation";
$sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element;
$sql .= " WHERE entity IN (".getEntity('accountancy').")"; $sql .= " WHERE entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features
dol_syslog(get_class($this)."::export_bookkeeping", LOG_DEBUG); dol_syslog(get_class($this)."::export_bookkeeping", LOG_DEBUG);
@ -1837,6 +1847,8 @@ class BookKeeping extends CommonObject
*/ */
public function transformTransaction($direction = 0, $piece_num = '') public function transformTransaction($direction = 0, $piece_num = '')
{ {
global $conf;
$error = 0; $error = 0;
$this->db->begin(); $this->db->begin();
@ -1856,14 +1868,14 @@ class BookKeeping extends CommonObject
$sql .= ' doc_ref, fk_doc, fk_docdet, entity, thirdparty_code, subledger_account, subledger_label,'; $sql .= ' doc_ref, fk_doc, fk_docdet, entity, thirdparty_code, subledger_account, subledger_label,';
$sql .= ' numero_compte, label_compte, label_operation, debit, credit,'; $sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
$sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, '.((int) $next_piecenum).", '".$this->db->idate($now)."'"; $sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, '.((int) $next_piecenum).", '".$this->db->idate($now)."'";
$sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num); $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if (!$resql) { if (!$resql) {
$error++; $error++;
$this->errors[] = 'Error '.$this->db->lasterror(); $this->errors[] = 'Error '.$this->db->lasterror();
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
} }
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num); $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if (!$resql) { if (!$resql) {
$error++; $error++;
@ -1871,7 +1883,7 @@ class BookKeeping extends CommonObject
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
} }
} elseif ($direction == 1) { } elseif ($direction == 1) {
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num); $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if (!$resql) { if (!$resql) {
$error++; $error++;
@ -1886,14 +1898,14 @@ class BookKeeping extends CommonObject
$sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,'; $sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,';
$sql .= ' numero_compte, label_compte, label_operation, debit, credit,'; $sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
$sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num'; $sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num';
$sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE piece_num = '.((int) $piece_num); $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if (!$resql) { if (!$resql) {
$error++; $error++;
$this->errors[] = 'Error '.$this->db->lasterror(); $this->errors[] = 'Error '.$this->db->lasterror();
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
} }
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num); $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if (!$resql) { if (!$resql) {
$error++; $error++;
@ -1948,7 +1960,7 @@ class BookKeeping extends CommonObject
$sql .= " AND aa.active = 1"; $sql .= " AND aa.active = 1";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
$sql .= " AND asy.rowid = ".((int) $pcgver); $sql .= " AND asy.rowid = ".((int) $pcgver);
$sql .= " AND ab.entity IN (".getEntity('accountancy').")"; $sql .= " AND ab.entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features
$sql .= " ORDER BY account_number ASC"; $sql .= " ORDER BY account_number ASC";
dol_syslog(get_class($this)."::select_account", LOG_DEBUG); dol_syslog(get_class($this)."::select_account", LOG_DEBUG);
@ -2012,7 +2024,7 @@ class BookKeeping extends CommonObject
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as parent ON aa.account_parent = parent.rowid AND parent.active = 1"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as parent ON aa.account_parent = parent.rowid AND parent.active = 1";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as root ON parent.account_parent = root.rowid AND root.active = 1"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as root ON parent.account_parent = root.rowid AND root.active = 1";
$sql .= " WHERE aa.account_number = '".$this->db->escape($account)."'"; $sql .= " WHERE aa.account_number = '".$this->db->escape($account)."'";
$sql .= " AND aa.entity IN (".getEntity('accountancy').")"; $sql .= " AND aa.entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features
dol_syslog(get_class($this)."::select_account", LOG_DEBUG); dol_syslog(get_class($this)."::select_account", LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
@ -2052,7 +2064,7 @@ class BookKeeping extends CommonObject
$sql .= " AND asy.rowid = ".((int) $pcgver); $sql .= " AND asy.rowid = ".((int) $pcgver);
$sql .= " AND aa.active = 1"; $sql .= " AND aa.active = 1";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_accounting_category as cat ON aa.fk_accounting_category = cat.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_accounting_category as cat ON aa.fk_accounting_category = cat.rowid";
$sql .= " WHERE aa.entity IN (".getEntity('accountancy').")"; $sql .= " WHERE aa.entity = " . ((int) $conf->entity); // Do not use getEntity for accounting features
dol_syslog(get_class($this)."::select_account", LOG_DEBUG); dol_syslog(get_class($this)."::select_account", LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
@ -2114,15 +2126,26 @@ class BookKeepingLine
public $montant; public $montant;
/** /**
* @var float Amount * @var float Amount
*/ */
public $amount; public $amount;
/**
* @var float Multicurrency amount
*/
public $multicurrency_amount;
/**
* @var float Multicurrency code
*/
public $multicurrency_code;
/** /**
* @var string Sens * @var string Sens
*/ */
public $sens; public $sens;
public $lettering_code; public $lettering_code;
public $date_lettering;
/** /**
* @var int ID * @var int ID
@ -2153,4 +2176,9 @@ class BookKeepingLine
* @var integer|string $date_validation; * @var integer|string $date_validation;
*/ */
public $date_validation; public $date_validation;
/**
* @var integer|string $date_lim_reglement;
*/
public $date_lim_reglement;
} }

View File

@ -13,7 +13,6 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/ */
/** /**
@ -31,7 +30,8 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
// Load translation files required by the page // Load translation files required by the page
$langs->loadLangs(array("compta", "bills", "other", "accountancy")); $langs->loadLangs(array("compta", "bills", "other", "accountancy"));
$socid = GETPOST('socid', 'int'); $validatemonth = GETPOST('validatemonth', 'int');
$validateyear = GETPOST('validateyear', 'int');
$action = GETPOST('action', 'aZ09'); $action = GETPOST('action', 'aZ09');
@ -68,52 +68,47 @@ if (empty($user->rights->accounting->fiscalyear->write)) {
} }
/* /*
* Actions * Actions
*/ */
$now = dol_now();
if ($action == 'validate_movements_confirm' && !empty($user->rights->accounting->fiscalyear->write)) { if ($action == 'validate_movements_confirm' && !empty($user->rights->accounting->fiscalyear->write)) {
$result = $object->fetchAll(); $date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int'));
$date_end = dol_mktime(23, 59, 59, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
if ($result < 0) { $error = 0;
setEventMessages($object->error, $object->errors, 'errors');
} else {
// Specify as export : update field date_validated on selected month/year
$error = 0;
$db->begin();
$date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); $db->begin();
$date_end = dol_mktime(23, 59, 59, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
if (is_array($object->lines)) { // Specify as export : update field date_validated on selected month/year
foreach ($object->lines as $movement) { $sql = " UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping";
$now = dol_now(); $sql .= " SET date_validated = '".$db->idate($now)."'";
$sql .= " WHERE entity = " . ((int) $conf->entity);
$sql .= " AND doc_date >= '" . $db->idate($date_start) . "'";
$sql .= " AND doc_date <= '" . $db->idate($date_end) . "'";
$sql .= " AND date_validated IS NULL";
$sql = " UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping"; dol_syslog("/accountancy/closure/index.php action=validate_movement_confirm -> Set movements as validated", LOG_DEBUG);
$sql .= " SET date_validated = '".$db->idate($now)."'"; $result = $db->query($sql);
$sql .= " WHERE rowid = ".((int) $movement->id); if (!$result) {
$sql .= " AND doc_date >= '" . $db->idate($date_start) . "'"; $error++;
$sql .= " AND doc_date <= '" . $db->idate($date_end) . "'"; }
dol_syslog("/accountancy/closure/index.php :: Function validate_movement_confirm Specify movements as validated", LOG_DEBUG); if (!$error) {
$result = $db->query($sql); $db->commit();
if (!$result) {
$error++; setEventMessages($langs->trans("AllMovementsWereRecordedAsValidated"), null, 'mesgs');
break;
}
}
}
if (!$error) {
$db->commit();
setEventMessages($langs->trans("AllMovementsWereRecordedAsValidated"), null, 'mesgs');
} else {
$error++;
$db->rollback();
setEventMessages($langs->trans("NotAllMovementsCouldBeRecordedAsValidated"), null, 'errors');
}
header("Location: ".$_SERVER['PHP_SELF']."?year=".$year_start); header("Location: ".$_SERVER['PHP_SELF']."?year=".$year_start);
exit; exit;
} else {
$db->rollback();
setEventMessages($langs->trans("NotAllMovementsCouldBeRecordedAsValidated"), null, 'errors');
$action = '';
} }
} }

View File

@ -93,7 +93,7 @@ if (empty($user->rights->accounting->mouvements->lire)) {
*/ */
if (($action == 'clean' || $action == 'validatehistory') && $user->rights->accounting->bind->write) { if (($action == 'clean' || $action == 'validatehistory') && $user->rights->accounting->bind->write) {
// Clean database // Clean database by removing binding done on non existing or no more existing accounts
$db->begin(); $db->begin();
$sql1 = "UPDATE ".MAIN_DB_PREFIX."facturedet as fd"; $sql1 = "UPDATE ".MAIN_DB_PREFIX."facturedet as fd";
$sql1 .= " SET fk_code_ventilation = 0"; $sql1 .= " SET fk_code_ventilation = 0";
@ -119,6 +119,9 @@ if (($action == 'clean' || $action == 'validatehistory') && $user->rights->accou
if ($action == 'validatehistory') { if ($action == 'validatehistory') {
$error = 0; $error = 0;
$nbbinddone = 0;
$notpossible = 0;
$db->begin(); $db->begin();
// Now make the binding. Bind automatically only for product with a dedicated account that exists into chart of account, others need a manual bind // Now make the binding. Bind automatically only for product with a dedicated account that exists into chart of account, others need a manual bind
@ -150,18 +153,17 @@ if ($action == 'validatehistory') {
$sql .= " co.code as country_code, co.label as country_label,"; $sql .= " co.code as country_code, co.label as country_label,";
$sql .= " s.tva_intra,"; $sql .= " s.tva_intra,";
if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) {
$sql .= " spe.accountancy_code_sell as company_code_sell"; $sql .= " spe.accountancy_code_sell as company_code_sell"; // accounting code for product but stored on thirdparty
} else { } else {
$sql .= " s.accountancy_code_sell as company_code_sell"; $sql .= " s.accountancy_code_sell as company_code_sell"; // accounting code for product but stored on thirdparty
} }
$sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql .= " FROM ".MAIN_DB_PREFIX."facture as f";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc";
if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) {
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity); $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity);
} }
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON co.rowid = s.fk_pays "; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON co.rowid = s.fk_pays ";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."facturedet as l ON f.rowid = l.fk_facture"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."facturedet as l ON f.rowid = l.fk_facture"; // the main table
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = l.fk_product"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = l.fk_product";
if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) { if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_perentity as ppe ON ppe.fk_product = p.rowid AND ppe.entity = " . ((int) $conf->entity); $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_perentity as ppe ON ppe.fk_product = p.rowid AND ppe.entity = " . ((int) $conf->entity);
@ -172,8 +174,7 @@ if ($action == 'validatehistory') {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa2 ON " . $alias_product_perentity . ".accountancy_code_sell_intra = aa2.account_number AND aa2.active = 1 AND aa2.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa2.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa2 ON " . $alias_product_perentity . ".accountancy_code_sell_intra = aa2.account_number AND aa2.active = 1 AND aa2.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa2.entity = ".$conf->entity;
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa3 ON " . $alias_product_perentity . ".accountancy_code_sell_export = aa3.account_number AND aa3.active = 1 AND aa3.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa3.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa3 ON " . $alias_product_perentity . ".accountancy_code_sell_export = aa3.account_number AND aa3.active = 1 AND aa3.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa3.entity = ".$conf->entity;
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON " . $alias_societe_perentity . ".accountancy_code_sell = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON " . $alias_societe_perentity . ".accountancy_code_sell = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity;
$sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0 AND l.product_type <= 2 AND f.entity = ".((int) $conf->entity);
$sql .= " AND l.product_type <= 2";
if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) { if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) {
$sql .= " AND f.datef >= '".$db->idate($conf->global->ACCOUNTING_DATE_START_BINDING)."'"; $sql .= " AND f.datef >= '".$db->idate($conf->global->ACCOUNTING_DATE_START_BINDING)."'";
} }
@ -214,7 +215,7 @@ if ($action == 'validatehistory') {
$thirdpartystatic->email = $objp->email; $thirdpartystatic->email = $objp->email;
$thirdpartystatic->country_code = $objp->country_code; $thirdpartystatic->country_code = $objp->country_code;
$thirdpartystatic->tva_intra = $objp->tva_intra; $thirdpartystatic->tva_intra = $objp->tva_intra;
$thirdpartystatic->code_compta = $objp->company_code_sell; $thirdpartystatic->code_compta_product = $objp->company_code_sell; // The accounting account for product stored on thirdparty object (for level3 suggestion)
$product_static->ref = $objp->product_ref; $product_static->ref = $objp->product_ref;
$product_static->id = $objp->product_id; $product_static->id = $objp->product_id;
@ -254,7 +255,7 @@ if ($action == 'validatehistory') {
$suggestedid = 0; $suggestedid = 0;
$return=$accountingAccount->getAccountingCodeToBind($thirdpartystatic, $mysoc, $product_static, $facture_static, $facture_static_det, $accountingAccountArray, 'customer'); $return=$accountingAccount->getAccountingCodeToBind($thirdpartystatic, $mysoc, $product_static, $facture_static, $facture_static_det, $accountingAccountArray, 'customer');
if (!is_array($return) && $return<0) { if (!is_array($return) && $return < 0) {
setEventMessage($accountingAccount->error, 'errors'); setEventMessage($accountingAccount->error, 'errors');
} else { } else {
$suggestedid = $return['suggestedid']; $suggestedid = $return['suggestedid'];
@ -277,18 +278,25 @@ if ($action == 'validatehistory') {
$error++; $error++;
setEventMessages($db->lasterror(), null, 'errors'); setEventMessages($db->lasterror(), null, 'errors');
break; break;
} else {
$nbbinddone++;
} }
} else {
$notpossible++;
} }
$i++; $i++;
} }
if ($num_lines > 10000) {
$notpossible += ($num_lines - 10000);
}
} }
if ($error) { if ($error) {
$db->rollback(); $db->rollback();
} else { } else {
$db->commit(); $db->commit();
setEventMessages($langs->trans('AutomaticBindingDone'), null, 'mesgs'); setEventMessages($langs->trans('AutomaticBindingDone', $nbbinddone, $notpossible), null, 'mesgs');
} }
} }
@ -492,6 +500,7 @@ if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
} }
$sql .= " AND aa.account_number IS NOT NULL"; $sql .= " AND aa.account_number IS NOT NULL";
$sql .= " GROUP BY fd.fk_code_ventilation,aa.account_number,aa.label"; $sql .= " GROUP BY fd.fk_code_ventilation,aa.account_number,aa.label";
$sql .= ' ORDER BY aa.account_number';
dol_syslog('htdocs/accountancy/customer/index.php'); dol_syslog('htdocs/accountancy/customer/index.php');
$resql = $db->query($sql); $resql = $db->query($sql);
@ -624,16 +633,22 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) { // This part of code looks strange
print '<td width="60" class="right">'.$langs->trans('MonthShort'.str_pad($j, 2, '0', STR_PAD_LEFT)).'</td>'; print '<td width="60" class="right">'.$langs->trans('MonthShort'.str_pad($j, 2, '0', STR_PAD_LEFT)).'</td>';
} }
print '<td width="60" class="right"><b>'.$langs->trans("Total").'</b></td></tr>'; print '<td width="60" class="right"><b>'.$langs->trans("Total").'</b></td></tr>';
$sql = "SELECT '".$db->escape($langs->trans("Vide"))."' AS marge,"; $sql = "SELECT '".$db->escape($langs->trans("Vide"))."' AS marge,";
for ($i = 1; $i <= 12; $i++) { for ($i = 1; $i <= 12; $i++) {
$j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) - 1; $j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) - 1;
if ($j > 12) { if ($j > 12) {
$j -= 12; $j -= 12;
} }
$sql .= " SUM(".$db->ifsql("MONTH(f.datef)=".$j, "(fd.total_ht-(fd.qty * fd.buy_price_ht))", "0").") AS month".str_pad($j, 2, "0", STR_PAD_LEFT).","; $sql .= " SUM(".$db->ifsql("MONTH(f.datef)=".$j,
" (".$db->ifsql("fd.total_ht < 0",
" (-1 * (abs(fd.total_ht) - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100))))",
" (fd.total_ht - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100)))").")",
0).") AS month".str_pad($j, 2, '0', STR_PAD_LEFT).",";
} }
$sql .= " SUM((fd.total_ht-(fd.qty * fd.buy_price_ht))) as total"; $sql .= " SUM(".$db->ifsql("fd.total_ht < 0",
" (-1 * (abs(fd.total_ht) - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100))))",
" (fd.total_ht - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100)))").") as total";
$sql .= " FROM ".MAIN_DB_PREFIX."facturedet as fd"; $sql .= " FROM ".MAIN_DB_PREFIX."facturedet as fd";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.rowid = fd.fk_facture"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.rowid = fd.fk_facture";
$sql .= " WHERE f.datef >= '".$db->idate($search_date_start)."'"; $sql .= " WHERE f.datef >= '".$db->idate($search_date_start)."'";
@ -650,7 +665,6 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) { // This part of code looks strange
} else { } else {
$sql .= " AND f.type IN (".Facture::TYPE_STANDARD.", ".Facture::TYPE_REPLACEMENT.", ".Facture::TYPE_CREDIT_NOTE.", ".Facture::TYPE_DEPOSIT.", ".Facture::TYPE_SITUATION.")"; $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.", ".Facture::TYPE_REPLACEMENT.", ".Facture::TYPE_CREDIT_NOTE.", ".Facture::TYPE_DEPOSIT.", ".Facture::TYPE_SITUATION.")";
} }
dol_syslog('htdocs/accountancy/customer/index.php'); dol_syslog('htdocs/accountancy/customer/index.php');
$resql = $db->query($sql); $resql = $db->query($sql);
if ($resql) { if ($resql) {

View File

@ -68,7 +68,7 @@ $search_tvaintra = GETPOST('search_tvaintra', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION);
$sortfield = GETPOST('sortfield', 'aZ09comma'); $sortfield = GETPOST('sortfield', 'aZ09comma');
$sortorder = GETPOST('sortorder', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); $page = GETPOSTISSET('pageplusonPour le détail de la facture ref…e') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page < 0) { if (empty($page) || $page < 0) {
$page = 0; $page = 0;
} }
@ -137,9 +137,9 @@ if (is_array($changeaccount) && count($changeaccount) > 0 && $user->rights->acco
if (!$error) { if (!$error) {
$db->begin(); $db->begin();
$sql1 = "UPDATE ".MAIN_DB_PREFIX."facturedet as l"; $sql1 = "UPDATE ".MAIN_DB_PREFIX."facturedet";
$sql1 .= " SET l.fk_code_ventilation=".(GETPOST('account_parent', 'int') > 0 ? GETPOST('account_parent', 'int') : '0'); $sql1 .= " SET fk_code_ventilation=".(GETPOST('account_parent', 'int') > 0 ? GETPOST('account_parent', 'int') : '0');
$sql1 .= ' WHERE l.rowid IN ('.$db->sanitize(implode(',', $changeaccount)).')'; $sql1 .= ' WHERE rowid IN ('.$db->sanitize(implode(',', $changeaccount)).')';
dol_syslog('accountancy/customer/lines.php::changeaccount sql= '.$sql1); dol_syslog('accountancy/customer/lines.php::changeaccount sql= '.$sql1);
$resql1 = $db->query($sql1); $resql1 = $db->query($sql1);
@ -496,8 +496,8 @@ if ($result) {
} }
print '</td>'; print '</td>';
print '<td class="tdoverflowonsmartphone">'; print '<td class="tdoverflowonsmartphone small">';
$text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description)); $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description, 1));
$trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION;
print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description); print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description);
print '</td>'; print '</td>';
@ -516,7 +516,7 @@ if ($result) {
} }
print '</td>'; print '</td>';
print '<td>'.$objp->tva_intra.'</td>'; print '<td class="tdoverflowmax80" title="'.dol_escape_htmltag($objp->tva_intra).'">'.dol_escape_htmltag($objp->tva_intra).'</td>';
print '<td>'; print '<td>';
print $accountingaccountstatic->getNomUrl(0, 1, 1, '', 1); print $accountingaccountstatic->getNomUrl(0, 1, 1, '', 1);

View File

@ -539,13 +539,14 @@ if ($result) {
$thirdpartystatic->client = $objp->client; $thirdpartystatic->client = $objp->client;
$thirdpartystatic->fournisseur = $objp->fournisseur; $thirdpartystatic->fournisseur = $objp->fournisseur;
$thirdpartystatic->code_client = $objp->code_client; $thirdpartystatic->code_client = $objp->code_client;
$thirdpartystatic->code_compta = $objp->code_compta_client; // For backward compatibility
$thirdpartystatic->code_compta_client = $objp->code_compta_client; $thirdpartystatic->code_compta_client = $objp->code_compta_client;
$thirdpartystatic->code_fournisseur = $objp->code_fournisseur; $thirdpartystatic->code_fournisseur = $objp->code_fournisseur;
$thirdpartystatic->code_compta_fournisseur = $objp->code_compta_fournisseur; $thirdpartystatic->code_compta_fournisseur = $objp->code_compta_fournisseur;
$thirdpartystatic->email = $objp->email; $thirdpartystatic->email = $objp->email;
$thirdpartystatic->country_code = $objp->country_code; $thirdpartystatic->country_code = $objp->country_code;
$thirdpartystatic->tva_intra = $objp->tva_intra; $thirdpartystatic->tva_intra = $objp->tva_intra;
$thirdpartystatic->code_compta_company = $objp->company_code_sell; $thirdpartystatic->code_compta_product = $objp->company_code_sell; // The accounting account for product stored on thirdparty object (for level3 suggestion)
$product_static->ref = $objp->product_ref; $product_static->ref = $objp->product_ref;
$product_static->id = $objp->product_id; $product_static->id = $objp->product_id;
@ -630,13 +631,13 @@ if ($result) {
print $product_static->getNomUrl(1); print $product_static->getNomUrl(1);
} }
if ($product_static->label) { if ($product_static->label) {
print '<br><span class="opacitymedium small">'.$product_static->label.'</span>'; print '<br><span class="opacitymedium small">'.dol_escape_htmltag($product_static->label).'</span>';
} }
print '</td>'; print '</td>';
// Description // Description
print '<td class="tdoverflowonsmartphone small">'; print '<td class="tdoverflowonsmartphone small">';
$text = dolGetFirstLineOfText(dol_string_nohtmltag($facture_static_det->desc)); $text = dolGetFirstLineOfText(dol_string_nohtmltag($facture_static_det->desc, 1));
$trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION;
print $form->textwithtooltip(dol_trunc($text, $trunclength), $facture_static_det->desc); print $form->textwithtooltip(dol_trunc($text, $trunclength), $facture_static_det->desc);
print '</td>'; print '</td>';
@ -664,7 +665,7 @@ if ($result) {
print '</td>'; print '</td>';
// VAT Num // VAT Num
print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($objp->tva_intra).'">'.dol_escape_htmltag($objp->tva_intra).'</td>'; print '<td class="tdoverflowmax80" title="'.dol_escape_htmltag($objp->tva_intra).'">'.dol_escape_htmltag($objp->tva_intra).'</td>';
// Found accounts // Found accounts
print '<td class="small">'; print '<td class="small">';
@ -738,7 +739,7 @@ if ($db->type == 'mysqli') {
} }
// Add code to auto check the box when we select an account // Add code to auto check the box when we select an account
print '<script type="text/javascript" language="javascript"> print '<script type="text/javascript">
jQuery(document).ready(function() { jQuery(document).ready(function() {
jQuery(".codeventil").change(function() { jQuery(".codeventil").change(function() {
var s=$(this).attr("id").replace("codeventil", "") var s=$(this).attr("id").replace("codeventil", "")

View File

@ -99,40 +99,69 @@ if (($action == 'clean' || $action == 'validatehistory') && $user->rights->accou
if ($action == 'validatehistory') { if ($action == 'validatehistory') {
$error = 0; $error = 0;
$nbbinddone = 0;
$notpossible = 0;
$db->begin(); $db->begin();
// Now make the binding // Now make the binding
if ($db->type == 'pgsql') { $sql1 = "SELECT erd.rowid, accnt.rowid as suggestedid";
$sql1 = "UPDATE ".MAIN_DB_PREFIX."expensereport_det"; $sql1 .= " FROM ".MAIN_DB_PREFIX."expensereport_det as erd";
$sql1 .= " SET fk_code_ventilation = accnt.rowid"; $sql1 .= " LEFT JOIN ".MAIN_DB_PREFIX."c_type_fees as t ON erd.fk_c_type_fees = t.id";
$sql1 .= " FROM ".MAIN_DB_PREFIX."c_type_fees as t, ".MAIN_DB_PREFIX."accounting_account as accnt , ".MAIN_DB_PREFIX."accounting_system as syst"; $sql1 .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as accnt ON t.accountancy_code = accnt.account_number AND accnt.active = 1 AND accnt.entity =".((int) $conf->entity);
$sql1 .= " WHERE ".MAIN_DB_PREFIX."expensereport_det.fk_c_type_fees = t.id AND accnt.fk_pcg_version = syst.pcg_version AND syst.rowid = ".((int) $conf->global->CHARTOFACCOUNTS).' AND accnt.entity = '.((int) $conf->entity); $sql1 .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_system as syst ON accnt.fk_pcg_version = syst.pcg_version AND syst.rowid = ".((int) $conf->global->CHARTOFACCOUNTS).' AND syst.active = 1,';
$sql1 .= " AND accnt.active = 1 AND t.accountancy_code = accnt.account_number"; $sql1 .= " ".MAIN_DB_PREFIX."expensereport as er";
$sql1 .= " AND ".MAIN_DB_PREFIX."expensereport_det.fk_code_ventilation = 0"; $sql1 .= " WHERE erd.fk_expensereport = er.rowid AND er.entity = ".((int) $conf->entity);
if ($validatemonth && $validateyear) { $sql1 .= " AND er.fk_statut IN (".ExpenseReport::STATUS_APPROVED.", ".ExpenseReport::STATUS_CLOSED.") AND erd.fk_code_ventilation <= 0";
$sql1 .= dolSqlDateFilter('date', 0, $validatemonth, $validateyear); if ($validatemonth && $validateyear) {
} $sql1 .= dolSqlDateFilter('erd.date', 0, $validatemonth, $validateyear);
} else {
$sql1 = "UPDATE ".MAIN_DB_PREFIX."expensereport_det as erd, ".MAIN_DB_PREFIX."c_type_fees as t, ".MAIN_DB_PREFIX."accounting_account as accnt , ".MAIN_DB_PREFIX."accounting_system as syst";
$sql1 .= " SET erd.fk_code_ventilation = accnt.rowid";
$sql1 .= " WHERE erd.fk_c_type_fees = t.id AND accnt.fk_pcg_version = syst.pcg_version AND syst.rowid = ".((int) $conf->global->CHARTOFACCOUNTS).' AND accnt.entity = '.((int) $conf->entity);
$sql1 .= " AND accnt.active = 1 AND t.accountancy_code=accnt.account_number";
$sql1 .= " AND erd.fk_code_ventilation = 0";
if ($validatemonth && $validateyear) {
$sql1 .= dolSqlDateFilter('erd.date', 0, $validatemonth, $validateyear);
}
} }
dol_syslog('htdocs/accountancy/expensereport/index.php'); dol_syslog('htdocs/accountancy/expensereport/index.php');
$resql1 = $db->query($sql1); $result = $db->query($sql1);
if (!$resql1) { if (!$result) {
$error++; $error++;
$db->rollback();
setEventMessages($db->lasterror(), null, 'errors'); setEventMessages($db->lasterror(), null, 'errors');
} else {
$num_lines = $db->num_rows($result);
$i = 0;
while ($i < min($num_lines, 10000)) { // No more than 10000 at once
$objp = $db->fetch_object($result);
$lineid = $objp->rowid;
$suggestedid = $objp->suggestedid;
if ($suggestedid > 0) {
$sqlupdate = "UPDATE ".MAIN_DB_PREFIX."expensereport_det";
$sqlupdate .= " SET fk_code_ventilation = ".((int) $suggestedid);
$sqlupdate .= " WHERE fk_code_ventilation <= 0 AND rowid = ".((int) $lineid);
$resqlupdate = $db->query($sqlupdate);
if (!$resqlupdate) {
$error++;
setEventMessages($db->lasterror(), null, 'errors');
break;
} else {
$nbbinddone++;
}
} else {
$notpossible++;
}
$i++;
}
if ($num_lines > 10000) {
$notpossible += ($num_lines - 10000);
}
}
if ($error) {
$db->rollback();
} else { } else {
$db->commit(); $db->commit();
setEventMessages($langs->trans('AutomaticBindingDone'), null, 'mesgs'); setEventMessages($langs->trans('AutomaticBindingDone', $nbbinddone, $notpossible), null, 'mesgs');
} }
} }
@ -155,7 +184,7 @@ print '</span><br>';
$y = $year_current; $y = $year_current;
$buttonbind = '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=validatehistory&token='.newToken().'">'.$langs->trans("ValidateHistory").'</a>'; $buttonbind = '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=validatehistory&token='.newToken().'&year='.$year_current.'">'.$langs->trans("ValidateHistory").'</a>';
print_barre_liste(img_picto('', 'unlink', 'class="paddingright fa-color-unset"').$langs->trans("OverviewOfAmountOfLinesNotBound"), '', '', '', '', '', '', -1, '', '', 0, $buttonbind, '', 0, 1, 1); print_barre_liste(img_picto('', 'unlink', 'class="paddingright fa-color-unset"').$langs->trans("OverviewOfAmountOfLinesNotBound"), '', '', '', '', '', '', -1, '', '', 0, $buttonbind, '', 0, 1, 1);
@ -170,7 +199,25 @@ for ($i = 1; $i <= 12; $i++) {
if ($j > 12) { if ($j > 12) {
$j -= 12; $j -= 12;
} }
print '<td width="60" class="right">'.$langs->trans('MonthShort'.str_pad($j, 2, '0', STR_PAD_LEFT)).'</td>'; $cursormonth = $j;
if ($cursormonth > 12) {
$cursormonth -= 12;
}
$cursoryear = ($cursormonth < ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1)) ? $y + 1 : $y;
$tmp = dol_getdate(dol_get_last_day($cursoryear, $cursormonth, 'gmt'), false, 'gmt');
print '<td width="60" class="right">';
if (!empty($tmp['mday'])) {
$param = 'search_date_startday=1&search_date_startmonth='.$cursormonth.'&search_date_startyear='.$cursoryear;
$param .= '&search_date_endday='.$tmp['mday'].'&search_date_endmonth='.$tmp['mon'].'&search_date_endyear='.$tmp['year'];
$param .= '&search_month='.$tmp['mon'].'&search_year='.$tmp['year'];
print '<a href="'.DOL_URL_ROOT.'/accountancy/expensereport/list.php?'.$param.'">';
}
print $langs->trans('MonthShort'.str_pad($j, 2, '0', STR_PAD_LEFT));
if (!empty($tmp['mday'])) {
print '</a>';
}
print '</td>';
} }
print '<td width="60" class="right"><b>'.$langs->trans("Total").'</b></td></tr>'; print '<td width="60" class="right"><b>'.$langs->trans("Total").'</b></td></tr>';
@ -197,6 +244,7 @@ $sql .= " AND er.fk_statut IN (".ExpenseReport::STATUS_APPROVED.", ".ExpenseRepo
$sql .= " AND er.entity IN (".getEntity('expensereport', 0).")"; // We don't share object for accountancy $sql .= " AND er.entity IN (".getEntity('expensereport', 0).")"; // We don't share object for accountancy
$sql .= " AND aa.account_number IS NULL"; $sql .= " AND aa.account_number IS NULL";
$sql .= " GROUP BY erd.fk_code_ventilation,aa.account_number,aa.label"; $sql .= " GROUP BY erd.fk_code_ventilation,aa.account_number,aa.label";
$sql .= ' ORDER BY aa.account_number';
dol_syslog('/accountancy/expensereport/index.php:: sql='.$sql); dol_syslog('/accountancy/expensereport/index.php:: sql='.$sql);
$resql = $db->query($sql); $resql = $db->query($sql);

View File

@ -1,6 +1,6 @@
<?php <?php
/* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com> /* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2017 Alexandre Spangaro <aspangaro@open-dsi.fr> * Copyright (C) 2013-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2014-2015 Ari Elbaz (elarifr) <github@accedinfo.com> * Copyright (C) 2014-2015 Ari Elbaz (elarifr) <github@accedinfo.com>
* Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro> * Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
@ -26,8 +26,8 @@
*/ */
require '../../main.inc.php'; require '../../main.inc.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/class/html.formaccounting.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
@ -49,9 +49,14 @@ $search_desc = GETPOST('search_desc', 'alpha');
$search_amount = GETPOST('search_amount', 'alpha'); $search_amount = GETPOST('search_amount', 'alpha');
$search_account = GETPOST('search_account', 'alpha'); $search_account = GETPOST('search_account', 'alpha');
$search_vat = GETPOST('search_vat', 'alpha'); $search_vat = GETPOST('search_vat', 'alpha');
$search_day = GETPOST("search_day", "int"); $search_date_startday = GETPOST('search_date_startday', 'int');
$search_month = GETPOST("search_month", "int"); $search_date_startmonth = GETPOST('search_date_startmonth', 'int');
$search_year = GETPOST("search_year", "int"); $search_date_startyear = GETPOST('search_date_startyear', 'int');
$search_date_endday = GETPOST('search_date_endday', 'int');
$search_date_endmonth = GETPOST('search_date_endmonth', 'int');
$search_date_endyear = GETPOST('search_date_endyear', 'int');
$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); // Use tzserver
$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear);
// Load variable for pagination // Load variable for pagination
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION);
@ -61,9 +66,9 @@ $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("pa
if (empty($page) || $page < 0) { if (empty($page) || $page < 0) {
$page = 0; $page = 0;
} }
$offset = $limit * $page;
$pageprev = $page - 1; $pageprev = $page - 1;
$pagenext = $page + 1; $pagenext = $page + 1;
$offset = $limit * $page;
if (!$sortfield) { if (!$sortfield) {
$sortfield = "erd.date, erd.rowid"; $sortfield = "erd.date, erd.rowid";
} }
@ -101,9 +106,14 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
$search_amount = ''; $search_amount = '';
$search_account = ''; $search_account = '';
$search_vat = ''; $search_vat = '';
$search_day = ''; $search_date_startday = '';
$search_month = ''; $search_date_startmonth = '';
$search_year = ''; $search_date_startyear = '';
$search_date_endday = '';
$search_date_endmonth = '';
$search_date_endyear = '';
$search_date_start = '';
$search_date_end = '';
} }
if (is_array($changeaccount) && count($changeaccount) > 0 && $user->rights->accounting->bind->write) { if (is_array($changeaccount) && count($changeaccount) > 0 && $user->rights->accounting->bind->write) {
@ -204,7 +214,12 @@ if (strlen(trim($search_account))) {
if (strlen(trim($search_vat))) { if (strlen(trim($search_vat))) {
$sql .= natural_search("erd.tva_tx", price2num($search_vat), 1); $sql .= natural_search("erd.tva_tx", price2num($search_vat), 1);
} }
$sql .= dolSqlDateFilter('erd.date', $search_day, $search_month, $search_year); if ($search_date_start) {
$sql .= " AND erd.date >= '".$db->idate($search_date_start)."'";
}
if ($search_date_end) {
$sql .= " AND erd.date <= '".$db->idate($search_date_end)."'";
}
$sql .= " AND er.entity IN (".getEntity('expensereport', 0).")"; // We don't share object for accountancy $sql .= " AND er.entity IN (".getEntity('expensereport', 0).")"; // We don't share object for accountancy
$sql .= $db->order($sortfield, $sortorder); $sql .= $db->order($sortfield, $sortorder);
@ -222,9 +237,8 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
$sql .= $db->plimit($limit + 1, $offset); $sql .= $db->plimit($limit + 1, $offset);
dol_syslog('accountancy/expensereport/lines.php::list'); dol_syslog("accountancy/expensereport/lines.php", LOG_DEBUG);
$result = $db->query($sql); $result = $db->query($sql);
if ($result) { if ($result) {
$num_lines = $db->num_rows($result); $num_lines = $db->num_rows($result);
$i = 0; $i = 0;
@ -254,14 +268,23 @@ if ($result) {
if ($search_vat) { if ($search_vat) {
$param .= "&search_vat=".urlencode($search_vat); $param .= "&search_vat=".urlencode($search_vat);
} }
if ($search_day) { if ($search_date_startday) {
$param .= '&search_day='.urlencode($search_day); $param .= '&search_date_startday='.urlencode($search_date_startday);
} }
if ($search_month) { if ($search_date_startmonth) {
$param .= '&search_month='.urlencode($search_month); $param .= '&search_date_startmonth='.urlencode($search_date_startmonth);
} }
if ($search_year) { if ($search_date_startyear) {
$param .= '&search_year='.urlencode($search_year); $param .= '&search_date_startyear='.urlencode($search_date_startyear);
}
if ($search_date_endday) {
$param .= '&search_date_endday='.urlencode($search_date_endday);
}
if ($search_date_endmonth) {
$param .= '&search_date_endmonth='.urlencode($search_date_endmonth);
}
if ($search_date_endyear) {
$param .= '&search_date_endyear='.urlencode($search_date_endyear);
} }
print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">'."\n"; print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">'."\n";
@ -276,12 +299,11 @@ if ($result) {
print '<input type="hidden" name="page" value="'.$page.'">'; print '<input type="hidden" name="page" value="'.$page.'">';
print_barre_liste($langs->trans("ExpenseReportLinesDone"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit); print_barre_liste($langs->trans("ExpenseReportLinesDone"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
print '<span class="opacitymedium">'.$langs->trans("DescVentilDoneExpenseReport").'</span><br>'; print '<span class="opacitymedium">'.$langs->trans("DescVentilDoneExpenseReport").'</span><br>';
print '<br><div class="inline-block divButAction">'.$langs->trans("ChangeAccount").'<br>'; print '<br><div class="inline-block divButAction paddingbottom">'.$langs->trans("ChangeAccount").' ';
print $formaccounting->select_account($account_parent, 'account_parent', 2, array(), 0, 0, 'maxwidth300 maxwidthonsmartphone valignmiddle'); print $formaccounting->select_account($account_parent, 'account_parent', 2, array(), 0, 0, 'maxwidth300 maxwidthonsmartphone valignmiddle');
print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("ChangeBinding").'" /></div>'; print '<input type="submit" class="button small valignmiddle" value="'.$langs->trans("ChangeBinding").'"/></div>';
$moreforfilter = ''; $moreforfilter = '';
@ -296,11 +318,12 @@ if ($result) {
print '<td class="liste_titre"></td>'; print '<td class="liste_titre"></td>';
} }
print '<td class="liste_titre center">'; print '<td class="liste_titre center">';
if (!empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) { print '<div class="nowrap">';
print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_day" value="'.$search_day.'">'; print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
} print '</div>';
print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_month" value="'.$search_month.'">'; print '<div class="nowrap">';
$formother->select_year($search_year, 'search_year', 1, 20, 5); print $form->selectDate($search_date_end ? $search_date_end : -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
print '</div>';
print '</td>'; print '</td>';
print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="'.dol_escape_htmltag($search_label).'"></td>'; print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="'.dol_escape_htmltag($search_label).'"></td>';
print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_desc" value="'.dol_escape_htmltag($search_desc).'"></td>'; print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_desc" value="'.dol_escape_htmltag($search_desc).'"></td>';
@ -382,7 +405,7 @@ if ($result) {
// Fees description -- Can be null // Fees description -- Can be null
print '<td>'; print '<td>';
$text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->comments)); $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->comments, 1));
$trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION;
print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->comments); print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->comments);
print '</td>'; print '</td>';

View File

@ -1,6 +1,6 @@
<?php <?php
/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com> /* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2017 Alexandre Spangaro <aspangaro@open-dsi.fr> * Copyright (C) 2013-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2014-2015 Ari Elbaz (elarifr) <github@accedinfo.com> * Copyright (C) 2014-2015 Ari Elbaz (elarifr) <github@accedinfo.com>
* Copyright (C) 2013-2014 Florian Henry <florian.henry@open-concept.pro> * Copyright (C) 2013-2014 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>s * Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>s
@ -30,9 +30,9 @@ require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
// Load translation files required by the page // Load translation files required by the page
@ -59,9 +59,14 @@ $search_desc = GETPOST('search_desc', 'alpha');
$search_amount = GETPOST('search_amount', 'alpha'); $search_amount = GETPOST('search_amount', 'alpha');
$search_account = GETPOST('search_account', 'alpha'); $search_account = GETPOST('search_account', 'alpha');
$search_vat = GETPOST('search_vat', 'alpha'); $search_vat = GETPOST('search_vat', 'alpha');
$search_day = GETPOST("search_day", "int"); $search_date_startday = GETPOST('search_date_startday', 'int');
$search_month = GETPOST("search_month", "int"); $search_date_startmonth = GETPOST('search_date_startmonth', 'int');
$search_year = GETPOST("search_year", "int"); $search_date_startyear = GETPOST('search_date_startyear', 'int');
$search_date_endday = GETPOST('search_date_endday', 'int');
$search_date_endmonth = GETPOST('search_date_endmonth', 'int');
$search_date_endyear = GETPOST('search_date_endyear', 'int');
$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); // Use tzserver
$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear);
// Load variable for pagination // Load variable for pagination
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION);
@ -83,6 +88,9 @@ if (!$sortorder) {
} }
} }
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('accountancyexpensereportlist'));
$formaccounting = new FormAccounting($db); $formaccounting = new FormAccounting($db);
$accounting = new AccountingAccount($db); $accounting = new AccountingAccount($db);
@ -101,7 +109,7 @@ if (empty($user->rights->accounting->mouvements->lire)) {
/* /*
* Action * Actions
*/ */
if (GETPOST('cancel', 'alpha')) { if (GETPOST('cancel', 'alpha')) {
@ -111,30 +119,47 @@ if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massa
$massaction = ''; $massaction = '';
} }
// Purge search criteria $parameters = array();
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All test are required to be compatible with all browsers $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
$search_login = ''; if ($reshook < 0) {
$search_expensereport = ''; setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
$search_label = ''; }
$search_desc = '';
$search_amount = ''; if (empty($reshook)) {
$search_account = ''; // Purge search criteria
$search_vat = ''; if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All test are required to be compatible with all browsers
$search_day = ''; $search_login = '';
$search_month = ''; $search_expensereport = '';
$search_year = ''; $search_label = '';
$search_desc = '';
$search_amount = '';
$search_account = '';
$search_vat = '';
$search_date_startday = '';
$search_date_startmonth = '';
$search_date_startyear = '';
$search_date_endday = '';
$search_date_endmonth = '';
$search_date_endyear = '';
$search_date_start = '';
$search_date_end = '';
$search_country = '';
$search_tvaintra = '';
}
// Mass actions
$objectclass = 'ExpenseReport';
$objectlabel = 'ExpenseReport';
$permissiontoread = $user->rights->expensereport->read;
$permissiontodelete = $user->rights->expensereport->delete;
$uploaddir = $conf->expensereport->dir_output;
include DOL_DOCUMENT_ROOT . '/core/actions_massactions.inc.php';
} }
// Mass actions
$objectclass = 'ExpenseReport';
$objectlabel = 'ExpenseReport';
$permissiontoread = $user->rights->expensereport->read;
$permissiontodelete = $user->rights->expensereport->delete;
$uploaddir = $conf->expensereport->dir_output;
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
if ($massaction == 'ventil' && $user->rights->accounting->bind->write) { if ($massaction == 'ventil' && $user->rights->accounting->bind->write) {
$msg = ''; $msg = '';
//print '<div><span style="color:red">' . $langs->trans("Processing") . '...</span></div>'; //print '<div><span style="color:red">' . $langs->trans("Processing") . '...</span></div>';
if (!empty($mesCasesCochees)) { if (!empty($mesCasesCochees)) {
$msg = '<div>'.$langs->trans("SelectedLines").': '.count($mesCasesCochees).'</div>'; $msg = '<div>'.$langs->trans("SelectedLines").': '.count($mesCasesCochees).'</div>';
@ -159,7 +184,7 @@ if ($massaction == 'ventil' && $user->rights->accounting->bind->write) {
$accountventilated = new AccountingAccount($db); $accountventilated = new AccountingAccount($db);
$accountventilated->fetch($monCompte, '', 1); $accountventilated->fetch($monCompte, '', 1);
dol_syslog('accountancy/expensereport/list.php', LOG_DEBUG); dol_syslog('accountancy/expensereport/list.php:: sql='.$sql, LOG_DEBUG);
if ($db->query($sql)) { if ($db->query($sql)) {
$msg .= '<div><span style="color:green">'.$langs->trans("LineOfExpenseReport").' '.$monId.' - '.$langs->trans("VentilatedinAccount").' : '.length_accountg($accountventilated->account_number).'</span></div>'; $msg .= '<div><span style="color:green">'.$langs->trans("LineOfExpenseReport").' '.$monId.' - '.$langs->trans("VentilatedinAccount").' : '.length_accountg($accountventilated->account_number).'</span></div>';
$ok++; $ok++;
@ -201,6 +226,9 @@ $sql .= " erd.rowid, erd.fk_c_type_fees, erd.comments, erd.total_ht as price, er
$sql .= " f.id as type_fees_id, f.code as type_fees_code, f.label as type_fees_label, f.accountancy_code as code_buy,"; $sql .= " f.id as type_fees_id, f.code as type_fees_code, f.label as type_fees_label, f.accountancy_code as code_buy,";
$sql .= " u.rowid as userid, u.login, u.lastname, u.firstname, u.email, u.gender, u.employee, u.photo, u.statut,"; $sql .= " u.rowid as userid, u.login, u.lastname, u.firstname, u.email, u.gender, u.employee, u.photo, u.statut,";
$sql .= " aa.rowid as aarowid"; $sql .= " aa.rowid as aarowid";
$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."expensereport as er"; $sql .= " FROM ".MAIN_DB_PREFIX."expensereport as er";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."expensereport_det as erd ON er.rowid = erd.fk_expensereport"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."expensereport_det as erd ON er.rowid = erd.fk_expensereport";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_type_fees as f ON f.id = erd.fk_c_type_fees"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_type_fees as f ON f.id = erd.fk_c_type_fees";
@ -233,9 +261,19 @@ if (strlen(trim($search_account))) {
if (strlen(trim($search_vat))) { if (strlen(trim($search_vat))) {
$sql .= natural_search("erd.tva_tx", $search_vat, 1); $sql .= natural_search("erd.tva_tx", $search_vat, 1);
} }
$sql .= dolSqlDateFilter('erd.date', $search_day, $search_month, $search_year); if ($search_date_start) {
$sql .= " AND erd.date >= '".$db->idate($search_date_start)."'";
}
if ($search_date_end) {
$sql .= " AND erd.date <= '".$db->idate($search_date_end)."'";
}
$sql .= " AND er.entity IN (".getEntity('expensereport', 0).")"; // We don't share object for accountancy $sql .= " AND er.entity IN (".getEntity('expensereport', 0).")"; // We don't share object for accountancy
// Add where from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
$sql .= $hookmanager->resPrint;
$sql .= $db->order($sortfield, $sortorder); $sql .= $db->order($sortfield, $sortorder);
// Count total nb of records // Count total nb of records
@ -251,7 +289,13 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
$sql .= $db->plimit($limit + 1, $offset); $sql .= $db->plimit($limit + 1, $offset);
dol_syslog('accountancy/expensereport/list.php'); dol_syslog("accountancy/expensereport/list.php", LOG_DEBUG);
// MAX_JOIN_SIZE can be very low (ex: 300000) on some limited configurations (ex: https://www.online.net/fr/hosting/online-perso)
// This big SELECT command may exceed the MAX_JOIN_SIZE limit => Therefore we use SQL_BIG_SELECTS=1 to disable the MAX_JOIN_SIZE security
if ($db->type == 'mysqli') {
$db->query("SET SQL_BIG_SELECTS=1");
}
$result = $db->query($sql); $result = $db->query($sql);
if ($result) { if ($result) {
$num_lines = $db->num_rows($result); $num_lines = $db->num_rows($result);
@ -272,14 +316,23 @@ if ($result) {
if ($search_lineid) { if ($search_lineid) {
$param .= '&search_lineid='.urlencode($search_lineid); $param .= '&search_lineid='.urlencode($search_lineid);
} }
if ($search_day) { if ($search_date_startday) {
$param .= '&search_day='.urlencode($search_day); $param .= '&search_date_startday='.urlencode($search_date_startday);
} }
if ($search_month) { if ($search_date_startmonth) {
$param .= '&search_month='.urlencode($search_month); $param .= '&search_date_startmonth='.urlencode($search_date_startmonth);
} }
if ($search_year) { if ($search_date_startyear) {
$param .= '&search_year='.urlencode($search_year); $param .= '&search_date_startyear='.urlencode($search_date_startyear);
}
if ($search_date_endday) {
$param .= '&search_date_endday='.urlencode($search_date_endday);
}
if ($search_date_endmonth) {
$param .= '&search_date_endmonth='.urlencode($search_date_endmonth);
}
if ($search_date_endyear) {
$param .= '&search_date_endyear='.urlencode($search_date_endyear);
} }
if ($search_expensereport) { if ($search_expensereport) {
$param .= '&search_expensereport='.urlencode($search_expensereport); $param .= '&search_expensereport='.urlencode($search_expensereport);
@ -302,7 +355,6 @@ if ($result) {
); );
$massactionbutton = $form->selectMassAction('ventil', $arrayofmassactions, 1); $massactionbutton = $form->selectMassAction('ventil', $arrayofmassactions, 1);
print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">'."\n"; print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">'."\n";
print '<input type="hidden" name="action" value="ventil">'; print '<input type="hidden" name="action" value="ventil">';
if ($optioncss != '') { if ($optioncss != '') {
@ -335,20 +387,21 @@ if ($result) {
if (!empty($conf->global->ACCOUNTANCY_USE_EXPENSE_REPORT_VALIDATION_DATE)) { if (!empty($conf->global->ACCOUNTANCY_USE_EXPENSE_REPORT_VALIDATION_DATE)) {
print '<td class="liste_titre"></td>'; print '<td class="liste_titre"></td>';
} }
print '<td class="liste_titre center nowraponall minwidth100imp">'; print '<td class="liste_titre center">';
if (!empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) { print '<div class="nowrap">';
print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_day" value="'.$search_day.'">'; print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
} print '</div>';
print '<input class="flat valignmiddle maxwidth25" type="text" maxlength="2" name="search_month" value="'.$search_month.'">'; print '<div class="nowrap">';
$formother->select_year($search_year, 'search_year', 1, 20, 5); print $form->selectDate($search_date_end ? $search_date_end : -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to'));
print '</div>';
print '</td>'; print '</td>';
print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="'.dol_escape_htmltag($search_label).'"></td>'; print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="'.dol_escape_htmltag($search_label).'"></td>';
print '<td class="liste_titre"><input type="text" class="flat maxwidthonsmartphone" name="search_desc" value="'.dol_escape_htmltag($search_desc).'"></td>'; print '<td class="liste_titre"><input type="text" class="flat maxwidthonsmartphone" name="search_desc" value="'.dol_escape_htmltag($search_desc).'"></td>';
print '<td class="liste_titre right"><input type="text" class="right flat maxwidth50" name="search_amount" value="'.dol_escape_htmltag($search_amount).'"></td>'; print '<td class="liste_titre right"><input type="text" class="flat maxwidth50 right" name="search_amount" value="'.dol_escape_htmltag($search_amount).'"></td>';
print '<td class="liste_titre right"><input type="text" class="right flat maxwidth50" name="search_vat" placeholder="%" size="1" value="'.dol_escape_htmltag($search_vat).'"></td>'; print '<td class="liste_titre right"><input type="text" class="flat maxwidth50 right" name="search_vat" placeholder="%" size="1" value="'.dol_escape_htmltag($search_vat).'"></td>';
print '<td class="liste_titre"></td>'; print '<td class="liste_titre"></td>';
print '<td class="liste_titre"></td>'; print '<td class="liste_titre"></td>';
print '<td class="center" class="liste_titre">'; print '<td class="center liste_titre">';
$searchpicto = $form->showFilterButtons(); $searchpicto = $form->showFilterButtons();
print $searchpicto; print $searchpicto;
print '</td>'; print '</td>';
@ -428,7 +481,7 @@ if ($result) {
// Fees description -- Can be null // Fees description -- Can be null
print '<td>'; print '<td>';
$text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->comments)); $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->comments, 1));
$trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION;
print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->comments); print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->comments);
print '</td>'; print '</td>';
@ -468,9 +521,12 @@ if ($result) {
} else { } else {
print $db->error(); 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 // Add code to auto check the box when we select an account
print '<script type="text/javascript" language="javascript"> print '<script type="text/javascript">
jQuery(document).ready(function() { jQuery(document).ready(function() {
jQuery(".codeventil").change(function() { jQuery(".codeventil").change(function() {
var s=$(this).attr("id").replace("codeventil", "") var s=$(this).attr("id").replace("codeventil", "")

View File

@ -100,7 +100,7 @@ if (!empty($conf->global->INVOICE_USE_SITUATION) && $conf->global->INVOICE_USE_S
$showtutorial .= ' '.$langs->trans("ShowTutorial"); $showtutorial .= ' '.$langs->trans("ShowTutorial");
$showtutorial .= '</a></div>'; $showtutorial .= '</a></div>';
$showtutorial .= '<script type="text/javascript" language="javascript"> $showtutorial .= '<script type="text/javascript">
jQuery(document).ready(function() { jQuery(document).ready(function() {
jQuery("#show_hide").click(function () { jQuery("#show_hide").click(function () {
jQuery( "#idfaq" ).toggle({ jQuery( "#idfaq" ).toggle({
@ -117,77 +117,79 @@ if (!empty($conf->global->INVOICE_USE_SITUATION) && $conf->global->INVOICE_USE_S
print '<div class="'.($helpisexpanded ? '' : 'hideobject').'" id="idfaq">'; // hideobject is to start hidden print '<div class="'.($helpisexpanded ? '' : 'hideobject').'" id="idfaq">'; // hideobject is to start hidden
print "<br>\n"; print "<br>\n";
print '<span class="opacitymedium">'.$langs->trans("AccountancyAreaDescIntro")."</span><br>\n"; print '<span class="opacitymedium">'.$langs->trans("AccountancyAreaDescIntro")."</span><br>\n";
print "<br>\n"; print "<br>\n"; if (!empty($user->rights->accounting->chartofaccount)) {
print "<br>\n"; print "<br>\n";
print load_fiche_titre('<span class="fa fa-calendar-check-o"></span> '.$langs->trans("AccountancyAreaDescActionOnce"), '', '')."\n"; print load_fiche_titre('<span class="fa fa-calendar-check-o"></span> '.$langs->trans("AccountancyAreaDescActionOnce"), '', '')."\n";
print '<hr>'; print '<hr>';
print "<br>\n"; print "<br>\n";
// STEPS // STEPS
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescJournalSetup", $step, '{s}');
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/accountancy/admin/journals_list.php?id=35"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("AccountingJournals").'</strong></a>', $s);
print $s;
print "<br>\n";
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChartModel", $step, '{s}');
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/accountancy/admin/accountmodel.php"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Pcg_version").'</strong></a>', $s);
print $s;
print "<br>\n";
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChart", $step, '{s}');
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/accountancy/admin/account.php"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Chartofaccounts").'</strong></a>', $s);
print $s;
print "<br>\n";
print "<br>\n";
print $langs->trans("AccountancyAreaDescActionOnceBis");
print "<br>\n";
print "<br>\n";
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescDefault", $step, '{s}');
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/accountancy/admin/defaultaccounts.php"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong></a>', $s);
print $s;
print "<br>\n";
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBank", $step, '{s}')."\n";
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/compta/bank/list.php"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuBankAccounts").'</strong></a>', $s);
print $s;
print "<br>\n";
$step++;
$textlink = '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=10&from=accountancy"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuVatAccounts").'</strong></a>';
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescVat", $step, '{s}');
$s = str_replace('{s}', $textlink, $s);
print $s;
print "<br>\n";
if (!empty($conf->tax->enabled)) {
$textlink = '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=7&from=accountancy"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuTaxAccounts").'</strong></a>';
$step++; $step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescContrib", $step, '{s}'); $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescJournalSetup", $step, '{s}');
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/accountancy/admin/journals_list.php?id=35"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("AccountingJournals").'</strong></a>', $s);
print $s;
print "<br>\n";
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChartModel", $step, '{s}');
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/accountancy/admin/accountmodel.php"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Pcg_version").'</strong></a>', $s);
print $s;
print "<br>\n";
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescChart", $step, '{s}');
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/accountancy/admin/account.php"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Chartofaccounts").'</strong></a>', $s);
print $s;
print "<br>\n";
print "<br>\n";
print $langs->trans("AccountancyAreaDescActionOnceBis");
print "<br>\n";
print "<br>\n";
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescDefault", $step, '{s}');
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/accountancy/admin/defaultaccounts.php"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong></a>', $s);
print $s;
print "<br>\n";
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBank", $step, '{s}')."\n";
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/compta/bank/list.php"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuBankAccounts").'</strong></a>', $s);
print $s;
print "<br>\n";
$step++;
$textlink = '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=10&from=accountancy"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuVatAccounts").'</strong></a>';
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescVat", $step, '{s}');
$s = str_replace('{s}', $textlink, $s); $s = str_replace('{s}', $textlink, $s);
print $s; print $s;
print "<br>\n"; print "<br>\n";
}
if (!empty($conf->expensereport->enabled)) { // TODO Move this in the default account page because this is only one accounting account per purpose, not several. if (!empty($conf->tax->enabled)) {
$textlink = '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=7&from=accountancy"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuTaxAccounts").'</strong></a>';
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescContrib", $step, '{s}');
$s = str_replace('{s}', $textlink, $s);
print $s;
print "<br>\n";
}
if (!empty($conf->expensereport->enabled)) { // TODO Move this in the default account page because this is only one accounting account per purpose, not several.
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescExpenseReport", $step, '{s}');
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=17&from=accountancy"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuExpenseReportAccounts").'</strong></a>', $s);
print $s;
print "<br>\n";
}
$step++; $step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescExpenseReport", $step, '{s}'); $s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescProd", $step, '{s}');
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=17&from=accountancy"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuExpenseReportAccounts").'</strong></a>', $s); $s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/accountancy/admin/productaccount.php"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("ProductsBinding").'</strong></a>', $s);
print $s; print $s;
print "<br>\n"; print "<br>\n";
print '<br>';
} }
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescProd", $step, '{s}');
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/accountancy/admin/productaccount.php"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("ProductsBinding").'</strong></a>', $s);
print $s;
print "<br>\n";
print '<br>';
// Step A - E // Step A - E
print "<br>\n"; print "<br>\n";

View File

@ -117,7 +117,7 @@ if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))
$date_end = dol_get_last_day($pastmonthyear, $pastmonth, false); $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
} }
$sql = "SELECT b.rowid, b.dateo as do, b.datev as dv, b.amount, b.label, b.rappro, b.num_releve, b.num_chq, b.fk_type, b.fk_account,"; $sql = "SELECT b.rowid, b.dateo as do, b.datev as dv, b.amount, b.amount_main_currency, b.label, b.rappro, b.num_releve, b.num_chq, b.fk_type, b.fk_account,";
$sql .= " ba.courant, ba.ref as baref, ba.account_number, ba.fk_accountancy_journal,"; $sql .= " ba.courant, ba.ref as baref, ba.account_number, ba.fk_accountancy_journal,";
$sql .= " soc.rowid as socid, soc.nom as name, soc.email as email, bu1.type as typeop_company,"; $sql .= " soc.rowid as socid, soc.nom as name, soc.email as email, bu1.type as typeop_company,";
if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) {
@ -142,7 +142,7 @@ if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) {
} }
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on bu2.url_id=u.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on bu2.url_id=u.rowid";
$sql .= " WHERE ba.fk_accountancy_journal=".((int) $id_journal); $sql .= " WHERE ba.fk_accountancy_journal=".((int) $id_journal);
$sql .= ' AND b.amount != 0 AND ba.entity IN ('.getEntity('bank_account', 0).')'; // We don't share object for accountancy $sql .= ' AND b.amount <> 0 AND ba.entity IN ('.getEntity('bank_account', 0).')'; // We don't share object for accountancy
if ($date_start && $date_end) { if ($date_start && $date_end) {
$sql .= " AND b.dateo >= '".$db->idate($date_start)."' AND b.dateo <= '".$db->idate($date_end)."'"; $sql .= " AND b.dateo >= '".$db->idate($date_start)."' AND b.dateo <= '".$db->idate($date_end)."'";
} }
@ -282,6 +282,7 @@ if ($result) {
$tabpay[$obj->rowid]["fk_bank"] = $obj->rowid; $tabpay[$obj->rowid]["fk_bank"] = $obj->rowid;
$tabpay[$obj->rowid]["bank_account_ref"] = $obj->baref; $tabpay[$obj->rowid]["bank_account_ref"] = $obj->baref;
$tabpay[$obj->rowid]["fk_bank_account"] = $obj->fk_account; $tabpay[$obj->rowid]["fk_bank_account"] = $obj->fk_account;
$reg = array();
if (preg_match('/^\((.*)\)$/i', $obj->label, $reg)) { if (preg_match('/^\((.*)\)$/i', $obj->label, $reg)) {
$tabpay[$obj->rowid]["lib"] = $langs->trans($reg[1]); $tabpay[$obj->rowid]["lib"] = $langs->trans($reg[1]);
} else { } else {
@ -296,6 +297,12 @@ if ($result) {
$tabtype[$obj->rowid] = 'unknown'; $tabtype[$obj->rowid] = 'unknown';
$tabmoreinfo[$obj->rowid] = array(); $tabmoreinfo[$obj->rowid] = array();
$amounttouse = $obj->amount;
if (!empty($obj->amount_main_currency)) {
// If $obj->amount_main_currency is set, it means that $obj->amount is not in same currency, we must use $obj->amount_main_currency
$amounttouse = $obj->amount_main_currency;
}
// get_url may return -1 which is not traversable // get_url may return -1 which is not traversable
if (is_array($links) && count($links) > 0) { if (is_array($links) && count($links) > 0) {
// Now loop on each link of record in bank (code similar to bankentries_list.php) // Now loop on each link of record in bank (code similar to bankentries_list.php)
@ -334,7 +341,7 @@ if ($result) {
$societestatic->email = $tabcompany[$obj->rowid]['email']; $societestatic->email = $tabcompany[$obj->rowid]['email'];
$tabpay[$obj->rowid]["soclib"] = $societestatic->getNomUrl(1, '', 30); $tabpay[$obj->rowid]["soclib"] = $societestatic->getNomUrl(1, '', 30);
if ($compta_soc) { if ($compta_soc) {
$tabtp[$obj->rowid][$compta_soc] += $obj->amount; $tabtp[$obj->rowid][$compta_soc] += $amounttouse;
} }
} elseif ($links[$key]['type'] == 'user') { } elseif ($links[$key]['type'] == 'user') {
$userstatic->id = $links[$key]['url_id']; $userstatic->id = $links[$key]['url_id'];
@ -350,7 +357,7 @@ if ($result) {
$tabpay[$obj->rowid]["soclib"] = '???'; // Should not happen, but happens with old data when id of user was not saved on expense report payment. $tabpay[$obj->rowid]["soclib"] = '???'; // Should not happen, but happens with old data when id of user was not saved on expense report payment.
} }
if ($compta_user) { if ($compta_user) {
$tabtp[$obj->rowid][$compta_user] += $obj->amount; $tabtp[$obj->rowid][$compta_user] += $amounttouse;
} }
} elseif ($links[$key]['type'] == 'sc') { } elseif ($links[$key]['type'] == 'sc') {
$chargestatic->id = $links[$key]['url_id']; $chargestatic->id = $links[$key]['url_id'];
@ -383,7 +390,7 @@ if ($result) {
$resultmid = $db->query($sqlmid); $resultmid = $db->query($sqlmid);
if ($resultmid) { if ($resultmid) {
$objmid = $db->fetch_object($resultmid); $objmid = $db->fetch_object($resultmid);
$tabtp[$obj->rowid][$objmid->accountancy_code] += $obj->amount; $tabtp[$obj->rowid][$objmid->accountancy_code] += $amounttouse;
} }
} elseif ($links[$key]['type'] == 'payment_donation') { } elseif ($links[$key]['type'] == 'payment_donation') {
$paymentdonstatic->id = $links[$key]['url_id']; $paymentdonstatic->id = $links[$key]['url_id'];
@ -391,7 +398,7 @@ if ($result) {
$paymentdonstatic->fk_donation = $links[$key]['url_id']; $paymentdonstatic->fk_donation = $links[$key]['url_id'];
$tabpay[$obj->rowid]["lib"] .= ' '.$paymentdonstatic->getNomUrl(2); $tabpay[$obj->rowid]["lib"] .= ' '.$paymentdonstatic->getNomUrl(2);
$tabpay[$obj->rowid]["paymentdonationid"] = $paymentdonstatic->id; $tabpay[$obj->rowid]["paymentdonationid"] = $paymentdonstatic->id;
$tabtp[$obj->rowid][$account_pay_donation] += $obj->amount; $tabtp[$obj->rowid][$account_pay_donation] += $amounttouse;
} elseif ($links[$key]['type'] == 'member') { } elseif ($links[$key]['type'] == 'member') {
$paymentsubscriptionstatic->id = $links[$key]['url_id']; $paymentsubscriptionstatic->id = $links[$key]['url_id'];
$paymentsubscriptionstatic->ref = $links[$key]['url_id']; $paymentsubscriptionstatic->ref = $links[$key]['url_id'];
@ -399,14 +406,14 @@ if ($result) {
$tabpay[$obj->rowid]["lib"] .= ' '.$paymentsubscriptionstatic->getNomUrl(2); $tabpay[$obj->rowid]["lib"] .= ' '.$paymentsubscriptionstatic->getNomUrl(2);
$tabpay[$obj->rowid]["paymentsubscriptionid"] = $paymentsubscriptionstatic->id; $tabpay[$obj->rowid]["paymentsubscriptionid"] = $paymentsubscriptionstatic->id;
$paymentsubscriptionstatic->fetch($paymentsubscriptionstatic->id); $paymentsubscriptionstatic->fetch($paymentsubscriptionstatic->id);
$tabtp[$obj->rowid][$account_pay_subscription] += $obj->amount; $tabtp[$obj->rowid][$account_pay_subscription] += $amounttouse;
} elseif ($links[$key]['type'] == 'payment_vat') { // Payment VAT } elseif ($links[$key]['type'] == 'payment_vat') { // Payment VAT
$paymentvatstatic->id = $links[$key]['url_id']; $paymentvatstatic->id = $links[$key]['url_id'];
$paymentvatstatic->ref = $links[$key]['url_id']; $paymentvatstatic->ref = $links[$key]['url_id'];
$paymentvatstatic->label = $links[$key]['label']; $paymentvatstatic->label = $links[$key]['label'];
$tabpay[$obj->rowid]["lib"] .= ' '.$paymentvatstatic->getNomUrl(2); $tabpay[$obj->rowid]["lib"] .= ' '.$paymentvatstatic->getNomUrl(2);
$tabpay[$obj->rowid]["paymentvatid"] = $paymentvatstatic->id; $tabpay[$obj->rowid]["paymentvatid"] = $paymentvatstatic->id;
$tabtp[$obj->rowid][$account_pay_vat] += $obj->amount; $tabtp[$obj->rowid][$account_pay_vat] += $amounttouse;
} elseif ($links[$key]['type'] == 'payment_salary') { } elseif ($links[$key]['type'] == 'payment_salary') {
$paymentsalstatic->id = $links[$key]['url_id']; $paymentsalstatic->id = $links[$key]['url_id'];
$paymentsalstatic->ref = $links[$key]['url_id']; $paymentsalstatic->ref = $links[$key]['url_id'];
@ -438,7 +445,7 @@ if ($result) {
if (empty($obj->typeop_user)) { // Add test to avoid to add amount twice if a link already exists also on user. if (empty($obj->typeop_user)) { // Add test to avoid to add amount twice if a link already exists also on user.
$compta_user = $userstatic->accountancy_code; $compta_user = $userstatic->accountancy_code;
if ($compta_user) { if ($compta_user) {
$tabtp[$obj->rowid][$compta_user] += $obj->amount; $tabtp[$obj->rowid][$compta_user] += $amounttouse;
$tabuser[$obj->rowid] = array( $tabuser[$obj->rowid] = array(
'id' => $userstatic->id, 'id' => $userstatic->id,
'name' => dolGetFirstLastname($userstatic->firstname, $userstatic->lastname), 'name' => dolGetFirstLastname($userstatic->firstname, $userstatic->lastname),
@ -465,14 +472,14 @@ if ($result) {
$account_various = (!empty($paymentvariousstatic->accountancy_code) ? $paymentvariousstatic->accountancy_code : 'NotDefined'); // NotDefined is a reserved word $account_various = (!empty($paymentvariousstatic->accountancy_code) ? $paymentvariousstatic->accountancy_code : 'NotDefined'); // NotDefined is a reserved word
$account_subledger = (!empty($paymentvariousstatic->subledger_account) ? $paymentvariousstatic->subledger_account : ''); // NotDefined is a reserved word $account_subledger = (!empty($paymentvariousstatic->subledger_account) ? $paymentvariousstatic->subledger_account : ''); // NotDefined is a reserved word
$tabpay[$obj->rowid]["account_various"] = $account_various; $tabpay[$obj->rowid]["account_various"] = $account_various;
$tabtp[$obj->rowid][$account_subledger] += $obj->amount; $tabtp[$obj->rowid][$account_subledger] += $amounttouse;
} elseif ($links[$key]['type'] == 'payment_loan') { } elseif ($links[$key]['type'] == 'payment_loan') {
$paymentloanstatic->id = $links[$key]['url_id']; $paymentloanstatic->id = $links[$key]['url_id'];
$paymentloanstatic->ref = $links[$key]['url_id']; $paymentloanstatic->ref = $links[$key]['url_id'];
$paymentloanstatic->fk_loan = $links[$key]['url_id']; $paymentloanstatic->fk_loan = $links[$key]['url_id'];
$tabpay[$obj->rowid]["lib"] .= ' '.$paymentloanstatic->getNomUrl(2); $tabpay[$obj->rowid]["lib"] .= ' '.$paymentloanstatic->getNomUrl(2);
$tabpay[$obj->rowid]["paymentloanid"] = $paymentloanstatic->id; $tabpay[$obj->rowid]["paymentloanid"] = $paymentloanstatic->id;
//$tabtp[$obj->rowid][$account_pay_loan] += $obj->amount; //$tabtp[$obj->rowid][$account_pay_loan] += $amounttouse;
$sqlmid = 'SELECT pl.amount_capital, pl.amount_insurance, pl.amount_interest, l.accountancy_account_capital, l.accountancy_account_insurance, l.accountancy_account_interest'; $sqlmid = 'SELECT pl.amount_capital, pl.amount_insurance, pl.amount_interest, l.accountancy_account_capital, l.accountancy_account_insurance, l.accountancy_account_interest';
$sqlmid .= ' FROM '.MAIN_DB_PREFIX.'payment_loan as pl, '.MAIN_DB_PREFIX.'loan as l'; $sqlmid .= ' FROM '.MAIN_DB_PREFIX.'payment_loan as pl, '.MAIN_DB_PREFIX.'loan as l';
$sqlmid .= ' WHERE l.rowid = pl.fk_loan AND pl.fk_bank = '.((int) $obj->rowid); $sqlmid .= ' WHERE l.rowid = pl.fk_loan AND pl.fk_bank = '.((int) $obj->rowid);
@ -488,14 +495,14 @@ if ($result) {
} elseif ($links[$key]['type'] == 'banktransfert') { } elseif ($links[$key]['type'] == 'banktransfert') {
$accountLinestatic->fetch($links[$key]['url_id']); $accountLinestatic->fetch($links[$key]['url_id']);
$tabpay[$obj->rowid]["lib"] .= ' '.$langs->trans("BankTransfer").'- '.$accountLinestatic ->getNomUrl(1); $tabpay[$obj->rowid]["lib"] .= ' '.$langs->trans("BankTransfer").'- '.$accountLinestatic ->getNomUrl(1);
$tabtp[$obj->rowid][$account_transfer] += $obj->amount; $tabtp[$obj->rowid][$account_transfer] += $amounttouse;
$bankaccountstatic->fetch($tabpay[$obj->rowid]['fk_bank_account']); $bankaccountstatic->fetch($tabpay[$obj->rowid]['fk_bank_account']);
$tabpay[$obj->rowid]["soclib"] = $bankaccountstatic->getNomUrl(2); $tabpay[$obj->rowid]["soclib"] = $bankaccountstatic->getNomUrl(2);
} }
} }
} }
$tabbq[$obj->rowid][$compta_bank] += $obj->amount; $tabbq[$obj->rowid][$compta_bank] += $amounttouse;
// If no links were found to know the amount on thirdparty, we try to guess it. // If no links were found to know the amount on thirdparty, we try to guess it.
// This may happens on bank entries without the links lines to 'company'. // This may happens on bank entries without the links lines to 'company'.
@ -542,7 +549,7 @@ if ($result) {
} }
}*/ }*/
// if($obj->socid)$tabtp[$obj->rowid][$compta_soc] += $obj->amount; // if($obj->socid)$tabtp[$obj->rowid][$compta_soc] += $amounttouse;
$i++; $i++;
} }
@ -1057,7 +1064,7 @@ if (empty($action) || $action == 'view') {
} }
print '<div class="tabsAction tabsActionNoBottom">'; print '<div class="tabsAction tabsActionNoBottom centerimp">';
if (!empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL) && $in_bookkeeping == 'notyet') { if (!empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL) && $in_bookkeeping == 'notyet') {
print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />'; print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />';

View File

@ -521,7 +521,7 @@ if (empty($action) || $action == 'view') {
print $desc; print $desc;
print '</div>'; print '</div>';
} }
print '<div class="tabsAction tabsActionNoBottom">'; print '<div class="tabsAction tabsActionNoBottom centerimp">';
if (!empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL) && $in_bookkeeping == 'notyet') { if (!empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL) && $in_bookkeeping == 'notyet') {
print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />'; print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />';

View File

@ -774,7 +774,7 @@ if (empty($action) || $action == 'view') {
print $desc; print $desc;
print '</div>'; print '</div>';
} }
print '<div class="tabsAction tabsActionNoBottom">'; print '<div class="tabsAction tabsActionNoBottom centerimp">';
if (!empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL) && $in_bookkeeping == 'notyet') { if (!empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL) && $in_bookkeeping == 'notyet') {
print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />'; print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />';
} }

View File

@ -412,8 +412,13 @@ if ($action == 'writebookkeeping') {
$bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
$bookkeeping->thirdparty_code = $companystatic->code_client; $bookkeeping->thirdparty_code = $companystatic->code_client;
$bookkeeping->subledger_account = ''; if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT')) {
$bookkeeping->subledger_label = ''; $bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
$bookkeeping->subledger_label = $tabcompany[$key]['name'];
} else {
$bookkeeping->subledger_account = '';
$bookkeeping->subledger_label = '';
}
$bookkeeping->numero_compte = $k; $bookkeeping->numero_compte = $k;
$bookkeeping->label_compte = $label_account; $bookkeeping->label_compte = $label_account;
@ -716,7 +721,7 @@ if (empty($action) || $action == 'view') {
print $desc; print $desc;
print '</div>'; print '</div>';
} }
print '<div class="tabsAction tabsActionNoBottom">'; print '<div class="tabsAction tabsActionNoBottom centerimp">';
if (!empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL) && $in_bookkeeping == 'notyet') { if (!empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL) && $in_bookkeeping == 'notyet') {
print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />'; print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />';
} }
@ -886,6 +891,13 @@ if (empty($action) || $action == 'view') {
print "</td>"; print "</td>";
// Subledger account // Subledger account
print "<td>"; print "<td>";
if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT')) {
if (($accountoshow == "") || $accountoshow == 'NotDefined') {
print '<span class="error">'.$langs->trans("ThirdpartyAccountNotDefined").'</span>';
} else {
print length_accounta($tabcompany[$key]['code_compta']);
}
}
print '</td>'; print '</td>';
$companystatic->id = $tabcompany[$key]['id']; $companystatic->id = $tabcompany[$key]['id'];
$companystatic->name = $tabcompany[$key]['name']; $companystatic->name = $tabcompany[$key]['name'];

View File

@ -0,0 +1,313 @@
<?php
/* Copyright (C) 2021-2022 Open-DSI <support@open-dsi.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* 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 <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/accountancy/journal/variousjournal.php
* \ingroup Accountancy (Double entries)
* \brief Page of a journal
*/
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
// Load translation files required by the page
$langs->loadLangs(array("banks", "accountancy", "compta", "other", "errors"));
$id_journal = GETPOST('id_journal', 'int');
$action = GETPOST('action', 'aZ09');
$date_startmonth = GETPOST('date_startmonth');
$date_startday = GETPOST('date_startday');
$date_startyear = GETPOST('date_startyear');
$date_endmonth = GETPOST('date_endmonth');
$date_endday = GETPOST('date_endday');
$date_endyear = GETPOST('date_endyear');
$in_bookkeeping = GETPOST('in_bookkeeping');
if ($in_bookkeeping == '') {
$in_bookkeeping = 'notyet';
}
// Security check
if (empty($conf->accounting->enabled)) {
accessforbidden();
}
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->mouvements->lire)) {
accessforbidden();
}
// Get information of journal
$object = new AccountingJournal($db);
$result = $object->fetch($id_journal);
if ($result > 0) {
$id_journal = $object->id;
} elseif ($result < 0) {
dol_print_error('', $object->error, $object->errors);
} elseif ($result == 0) {
accessforbidden($langs->trans('ErrorRecordNotFound'));
}
$hookmanager->initHooks(array('globaljournal', $object->nature_text . 'journal'));
$parameters = array();
$date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear);
$date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear);
if (empty($date_startmonth) || empty($date_endmonth)) {
// Period by default on transfer
$dates = getDefaultDatesForTransfer();
$date_start = $dates['date_start'];
$date_end = $dates['date_end'];
$pastmonthyear = $dates['pastmonthyear'];
$pastmonth = $dates['pastmonth'];
}
if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) { // We define date_start and date_end, only if we did not submit the form
$date_start = dol_get_first_day($pastmonthyear, $pastmonth, false);
$date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
}
$data_type = 'view';
if ($action == 'writebookkeeping') $data_type = 'bookkeeping';
if ($action == 'exportcsv') $data_type = 'csv';
$journal_data = $object->getData($user, $data_type, $date_start, $date_end, $in_bookkeeping);
if (!is_array($journal_data)) {
setEventMessages($object->error, $object->errors, 'errors');
}
/*
* Actions
*/
$reshook = $hookmanager->executeHooks('doActions', $parameters, $user, $action); // Note that $action and $object may have been modified by some hooks
$reload = false;
// Bookkeeping Write
if ($action == 'writebookkeeping') {
$error = 0;
$result = $object->writeIntoBookkeeping($user, $journal_data);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
$error = abs($result);
}
$nb_elements = count($journal_data);
if (empty($error) && $nb_elements > 0) {
setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs');
} elseif ($nb_elements == $error) {
setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings');
} else {
setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings');
}
$reload = true;
} elseif ($action == 'exportcsv') {
// Export CSV
$result = $object->exportCsv($journal_data, $date_end);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
$reload = true;
} else {
$filename = 'journal';
$type_export = 'journal';
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php';
print $result;
$db->close();
exit();
}
}
// Must reload data, so we make a redirect
if ($reload) {
$param = 'id_journal=' . $id_journal;
$param .= '&date_startday=' . $date_startday;
$param .= '&date_startmonth=' . $date_startmonth;
$param .= '&date_startyear=' . $date_startyear;
$param .= '&date_endday=' . $date_endday;
$param .= '&date_endmonth=' . $date_endmonth;
$param .= '&date_endyear=' . $date_endyear;
$param .= '&in_bookkeeping=' . $in_bookkeeping;
header("Location: " . $_SERVER['PHP_SELF'] . ($param ? '?' . $param : ''));
exit;
}
/*
* View
*/
$form = new Form($db);
if ($object->nature == 2) {
$title = $langs->trans("SellsJournal");
$some_mandatory_steps_of_setup_were_not_done = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == "" || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1';
$account_accounting_not_defined = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == "" || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1';
} elseif ($object->nature == 3) {
$title = $langs->trans("PurchasesJournal");
$some_mandatory_steps_of_setup_were_not_done = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == "" || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1';
$account_accounting_not_defined = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == "" || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1';
} elseif ($object->nature == 4) {
$title = $langs->trans("FinanceJournal");
$some_mandatory_steps_of_setup_were_not_done = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == "" || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1'
|| $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == "" || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1'
|| empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) || $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT == '-1';
$account_accounting_not_defined = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == "" || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1'
|| $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == "" || $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER == '-1';
} elseif ($object->nature == 5) {
$title = $langs->trans("ExpenseReportsJournal");
$some_mandatory_steps_of_setup_were_not_done = empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) || $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT == '-1';
$account_accounting_not_defined = empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) || $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT == '-1';
} else {
$title = $object->getLibType();
$some_mandatory_steps_of_setup_were_not_done = false;
$account_accounting_not_defined = false;
}
$nom = $title . ' | ' . $object->getNomUrl(0, 1, 1, '', 1);
$nomlink = '';
$periodlink = '';
$exportlink = '';
$builddate = dol_now();
$description = $langs->trans("DescJournalOnlyBindedVisible") . '<br>';
if ($object->nature == 2 || $object->nature == 3) {
if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
$description .= $langs->trans("DepositsAreNotIncluded");
} else {
$description .= $langs->trans("DepositsAreIncluded");
}
}
$listofchoices = array('notyet' => $langs->trans("NotYetInGeneralLedger"), 'already' => $langs->trans("AlreadyInGeneralLedger"));
$period = $form->selectDate($date_start ? $date_start : -1, 'date_start', 0, 0, 0, '', 1, 0) . ' - ' . $form->selectDate($date_end ? $date_end : -1, 'date_end', 0, 0, 0, '', 1, 0);
$period .= ' - ' . $langs->trans("JournalizationInLedgerStatus") . ' ' . $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
$varlink = 'id_journal=' . $id_journal;
llxHeader('', $title);
journalHead($nom, $nomlink, $period, $periodlink, $description, $builddate, $exportlink, array('action' => ''), '', $varlink);
if ($object->nature == 4) { // Bank journal
// 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";
$sql .= " FROM " . MAIN_DB_PREFIX . "bank_account";
$sql .= " WHERE entity = " . (int) $conf->entity;
$sql .= " AND fk_accountancy_journal IS NULL";
$sql .= " AND clos=0";
$resql = $db->query($sql);
if ($resql) {
$obj = $db->fetch_object($resql);
if ($obj->nb > 0) {
print '<br>' . img_warning() . ' ' . $langs->trans("TheJournalCodeIsNotDefinedOnSomeBankAccount");
print ' : ' . $langs->trans("AccountancyAreaDescBank", 9, '<strong>' . $langs->transnoentitiesnoconv("MenuAccountancy") . '-' . $langs->transnoentitiesnoconv("Setup") . "-" . $langs->transnoentitiesnoconv("BankAccounts") . '</strong>');
}
} else dol_print_error($db);
}
// Button to write into Ledger
if ($some_mandatory_steps_of_setup_were_not_done) {
print '<br><div class="warning">' . img_warning() . ' ' . $langs->trans("SomeMandatoryStepsOfSetupWereNotDone");
print ' : ' . $langs->trans("AccountancyAreaDescMisc", 4, '<strong>' . $langs->transnoentitiesnoconv("MenuAccountancy") . '-' . $langs->transnoentitiesnoconv("Setup") . "-" . $langs->transnoentitiesnoconv("MenuDefaultAccounts") . '</strong>');
print '</div>';
}
print '<div class="tabsAction tabsActionNoBottom">';
if (!empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL) && $in_bookkeeping == 'notyet') {
print '<input type="button" class="butAction" name="exportcsv" value="' . $langs->trans("ExportDraftJournal") . '" onclick="launch_export();" />';
}
if ($account_accounting_not_defined) {
print '<input type="button" class="butActionRefused classfortooltip" title="' . dol_escape_htmltag($langs->trans("SomeMandatoryStepsOfSetupWereNotDone")) . '" value="' . $langs->trans("WriteBookKeeping") . '" />';
} else {
if ($in_bookkeeping == 'notyet') {
print '<input type="button" class="butAction" name="writebookkeeping" value="' . $langs->trans("WriteBookKeeping") . '" onclick="writebookkeeping();" />';
} else {
print '<a href="#" class="butActionRefused classfortooltip" name="writebookkeeping">' . $langs->trans("WriteBookKeeping") . '</a>';
}
}
print '</div>';
// TODO Avoid using js. We can use a direct link with $param
print '
<script type="text/javascript">
function launch_export() {
$("div.fiche form input[name=\"action\"]").val("exportcsv");
$("div.fiche form input[type=\"submit\"]").click();
$("div.fiche form input[name=\"action\"]").val("");
}
function writebookkeeping() {
console.log("click on writebookkeeping");
$("div.fiche form input[name=\"action\"]").val("writebookkeeping");
$("div.fiche form input[type=\"submit\"]").click();
$("div.fiche form input[name=\"action\"]").val("");
}
</script>';
$object_label = $langs->trans("ObjectsRef");
if ($object->nature == 2 || $object->nature == 3) $object_label = $langs->trans("InvoiceRef");
if ($object->nature == 5) $object_label = $langs->trans("ExpenseReportRef");
/*
* Show result array
*/
print '<br>';
print '<div class="div-table-responsive">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>' . $langs->trans("Date") . '</td>';
print '<td>' . $langs->trans("Piece") . ' (' . $object_label . ')</td>';
print '<td>' . $langs->trans("AccountAccounting") . '</td>';
print '<td>' . $langs->trans("SubledgerAccount") . '</td>';
print '<td>' . $langs->trans("LabelOperation") . '</td>';
if ($object->nature == 4) print '<td class="center">' . $langs->trans("PaymentMode") . '</td>'; // bank
print '<td class="right">' . $langs->trans("Debit") . '</td>';
print '<td class="right">' . $langs->trans("Credit") . '</td>';
print "</tr>\n";
foreach ($journal_data as $element_id => $element) {
foreach ($element['blocks'] as $lines) {
foreach ($lines as $line) {
print '<tr class="oddeven">';
print '<td>' . $line['date'] . '</td>';
print '<td>' . $line['piece'] . '</td>';
print '<td>' . $line['account_accounting'] . '</td>';
print '<td>' . $line['subledger_account'] . '</td>';
print '<td>' . $line['label_operation'] . '</td>';
if ($object->nature == 4) print '<td class="center">' . $line['payment_mode'] . '</td>';
print '<td class="right nowraponall">' . $line['debit'] . '</td>';
print '<td class="right nowraponall">' . $line['credit'] . '</td>';
print '</tr>';
}
}
}
print '</table>';
print '</div>';
llxFooter();
$db->close();

View File

@ -117,6 +117,9 @@ if (($action == 'clean' || $action == 'validatehistory') && $user->rights->accou
if ($action == 'validatehistory') { if ($action == 'validatehistory') {
$error = 0; $error = 0;
$nbbinddone = 0;
$notpossible = 0;
$db->begin(); $db->begin();
// Now make the binding. Bind automatically only for product with a dedicated account that exists into chart of account, others need a manual bind // Now make the binding. Bind automatically only for product with a dedicated account that exists into chart of account, others need a manual bind
@ -152,7 +155,6 @@ if ($action == 'validatehistory') {
} else { } else {
$sql .= " s.accountancy_code_buy as company_code_buy"; $sql .= " s.accountancy_code_buy as company_code_buy";
} }
$sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc";
if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) {
@ -170,8 +172,7 @@ if ($action == 'validatehistory') {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa2 ON " . $alias_product_perentity . ".accountancy_code_buy_intra = aa2.account_number AND aa2.active = 1 AND aa2.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa2.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa2 ON " . $alias_product_perentity . ".accountancy_code_buy_intra = aa2.account_number AND aa2.active = 1 AND aa2.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa2.entity = ".$conf->entity;
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa3 ON " . $alias_product_perentity . ".accountancy_code_buy_export = aa3.account_number AND aa3.active = 1 AND aa3.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa3.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa3 ON " . $alias_product_perentity . ".accountancy_code_buy_export = aa3.account_number AND aa3.active = 1 AND aa3.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa3.entity = ".$conf->entity;
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON " . $alias_societe_perentity . ".accountancy_code_buy = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON " . $alias_societe_perentity . ".accountancy_code_buy = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity;
$sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; $sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0 AND l.product_type <= 2 AND f.entity = ".((int) $conf->entity);
$sql .= " AND l.product_type <= 2";
if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) { if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) {
$sql .= " AND f.datef >= '".$db->idate($conf->global->ACCOUNTING_DATE_START_BINDING)."'"; $sql .= " AND f.datef >= '".$db->idate($conf->global->ACCOUNTING_DATE_START_BINDING)."'";
} }
@ -210,7 +211,7 @@ if ($action == 'validatehistory') {
$thirdpartystatic->email = $objp->email; $thirdpartystatic->email = $objp->email;
$thirdpartystatic->country_code = $objp->country_code; $thirdpartystatic->country_code = $objp->country_code;
$thirdpartystatic->tva_intra = $objp->tva_intra; $thirdpartystatic->tva_intra = $objp->tva_intra;
$thirdpartystatic->code_compta = $objp->company_code_sell; $thirdpartystatic->code_compta_product = $objp->company_code_buy; // The accounting account for product stored on thirdparty object (for level3 suggestion)
$product_static->ref = $objp->product_ref; $product_static->ref = $objp->product_ref;
$product_static->id = $objp->product_id; $product_static->id = $objp->product_id;
@ -229,7 +230,7 @@ if ($action == 'validatehistory') {
$facture_static->ref = $objp->ref; $facture_static->ref = $objp->ref;
$facture_static->id = $objp->facid; $facture_static->id = $objp->facid;
$facture_static->type = $objp->ftype; $facture_static->type = $objp->ftype;
$facture_static->datef = $objp->datef; $facture_static->date = $objp->datef;
$facture_static_det->id = $objp->rowid; $facture_static_det->id = $objp->rowid;
$facture_static_det->total_ht = $objp->total_ht; $facture_static_det->total_ht = $objp->total_ht;
@ -273,18 +274,25 @@ if ($action == 'validatehistory') {
$error++; $error++;
setEventMessages($db->lasterror(), null, 'errors'); setEventMessages($db->lasterror(), null, 'errors');
break; break;
} else {
$nbbinddone++;
} }
} else {
$notpossible++;
} }
$i++; $i++;
} }
if ($num_lines > 10000) {
$notpossible += ($num_lines - 10000);
}
} }
if ($error) { if ($error) {
$db->rollback(); $db->rollback();
} else { } else {
$db->commit(); $db->commit();
setEventMessages($langs->trans('AutomaticBindingDone'), null, 'mesgs'); setEventMessages($langs->trans('AutomaticBindingDone', $nbbinddone, $notpossible), null, 'mesgs');
} }
} }
@ -366,6 +374,7 @@ $sql .= " AND ffd.product_type <= 2";
$sql .= " AND ff.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy $sql .= " AND ff.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy
$sql .= " AND aa.account_number IS NULL"; $sql .= " AND aa.account_number IS NULL";
$sql .= " GROUP BY ffd.fk_code_ventilation,aa.account_number,aa.label"; $sql .= " GROUP BY ffd.fk_code_ventilation,aa.account_number,aa.label";
$sql .= ' ORDER BY aa.account_number';
dol_syslog('htdocs/accountancy/supplier/index.php'); dol_syslog('htdocs/accountancy/supplier/index.php');
$resql = $db->query($sql); $resql = $db->query($sql);

View File

@ -1,9 +1,9 @@
<?php <?php
/* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com> /* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2021 Alexandre Spangaro <aspangaro@open-dsi.fr> * Copyright (C) 2013-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2014-2015 Ari Elbaz (elarifr) <github@accedinfo.com> * Copyright (C) 2014-2015 Ari Elbaz (elarifr) <github@accedinfo.com>
* Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro> * Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -49,6 +49,7 @@ $search_societe = GETPOST('search_societe', 'alpha');
$search_lineid = GETPOST('search_lineid', 'int'); $search_lineid = GETPOST('search_lineid', 'int');
$search_ref = GETPOST('search_ref', 'alpha'); $search_ref = GETPOST('search_ref', 'alpha');
$search_invoice = GETPOST('search_invoice', 'alpha'); $search_invoice = GETPOST('search_invoice', 'alpha');
$search_ref_supplier = GETPOST('search_ref_supplier', 'alpha');
$search_label = GETPOST('search_label', 'alpha'); $search_label = GETPOST('search_label', 'alpha');
$search_desc = GETPOST('search_desc', 'alpha'); $search_desc = GETPOST('search_desc', 'alpha');
$search_amount = GETPOST('search_amount', 'alpha'); $search_amount = GETPOST('search_amount', 'alpha');
@ -112,6 +113,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
$search_lineid = ''; $search_lineid = '';
$search_ref = ''; $search_ref = '';
$search_invoice = ''; $search_invoice = '';
$search_ref_supplier = '';
$search_label = ''; $search_label = '';
$search_desc = ''; $search_desc = '';
$search_amount = ''; $search_amount = '';
@ -140,9 +142,9 @@ if (is_array($changeaccount) && count($changeaccount) > 0 && $user->rights->acco
if (!$error) { if (!$error) {
$db->begin(); $db->begin();
$sql1 = "UPDATE ".MAIN_DB_PREFIX."facture_fourn_det as l"; $sql1 = "UPDATE ".MAIN_DB_PREFIX."facture_fourn_det";
$sql1 .= " SET l.fk_code_ventilation=".(GETPOST('account_parent', 'int') > 0 ? GETPOST('account_parent', 'int') : '0'); $sql1 .= " SET fk_code_ventilation=".(GETPOST('account_parent', 'int') > 0 ? GETPOST('account_parent', 'int') : '0');
$sql1 .= ' WHERE l.rowid IN ('.$db->sanitize(implode(',', $changeaccount)).')'; $sql1 .= ' WHERE rowid IN ('.$db->sanitize(implode(',', $changeaccount)).')';
dol_syslog('accountancy/supplier/lines.php::changeaccount sql= '.$sql1); dol_syslog('accountancy/supplier/lines.php::changeaccount sql= '.$sql1);
$resql1 = $db->query($sql1); $resql1 = $db->query($sql1);
@ -236,6 +238,9 @@ if ($search_lineid) {
if (strlen(trim($search_invoice))) { if (strlen(trim($search_invoice))) {
$sql .= natural_search("f.ref", $search_invoice); $sql .= natural_search("f.ref", $search_invoice);
} }
if (strlen(trim($search_ref_supplier))) {
$sql .= natural_search("f.ref_supplier", $search_ref_supplier);
}
if (strlen(trim($search_label))) { if (strlen(trim($search_label))) {
$sql .= natural_search("f.libelle", $search_label); $sql .= natural_search("f.libelle", $search_label);
} }
@ -328,6 +333,9 @@ if ($result) {
if ($search_ref) { if ($search_ref) {
$param .= "&search_ref=".urlencode($search_ref); $param .= "&search_ref=".urlencode($search_ref);
} }
if ($search_ref_supplier) {
$param .= '&search_ref_supplier='.urlencode($search_ref_supplier);
}
if ($search_label) { if ($search_label) {
$param .= "&search_label=".urlencode($search_label); $param .= "&search_label=".urlencode($search_label);
} }
@ -392,6 +400,7 @@ if ($result) {
print '<tr class="liste_titre_filter">'; print '<tr class="liste_titre_filter">';
print '<td class="liste_titre"><input type="text" class="flat maxwidth25" name="search_lineid" value="'.dol_escape_htmltag($search_lineid).'"></td>'; print '<td class="liste_titre"><input type="text" class="flat maxwidth25" name="search_lineid" value="'.dol_escape_htmltag($search_lineid).'"></td>';
print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_invoice" value="'.dol_escape_htmltag($search_invoice).'"></td>'; print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_invoice" value="'.dol_escape_htmltag($search_invoice).'"></td>';
print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_ref_supplier" value="'.dol_escape_htmltag($search_ref_supplier).'"></td>';
print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="'.dol_escape_htmltag($search_label).'"></td>'; print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_label" value="'.dol_escape_htmltag($search_label).'"></td>';
print '<td class="liste_titre center">'; print '<td class="liste_titre center">';
print '<div class="nowrap">'; print '<div class="nowrap">';
@ -420,6 +429,7 @@ if ($result) {
print '<tr class="liste_titre">'; print '<tr class="liste_titre">';
print_liste_field_titre("LineId", $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("LineId", $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder);
print_liste_field_titre("Invoice", $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Invoice", $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder);
print_liste_field_titre("RefSupplier", $_SERVER["PHP_SELF"], "f.ref_supplier", "", $param, '', $sortfield, $sortorder);
print_liste_field_titre("InvoiceLabel", $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("InvoiceLabel", $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder);
print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, '', $sortfield, $sortorder, 'center '); print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, '', $sortfield, $sortorder, 'center ');
print_liste_field_titre("ProductRef", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("ProductRef", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder);
@ -446,6 +456,9 @@ if ($result) {
$facturefournisseur_static->ref = $objp->ref; $facturefournisseur_static->ref = $objp->ref;
$facturefournisseur_static->id = $objp->facid; $facturefournisseur_static->id = $objp->facid;
$facturefournisseur_static->type = $objp->ftype;
$facturefournisseur_static->ref_supplier = $objp->ref_supplier;
$facturefournisseur_static->label = $objp->invoice_label;
$thirdpartystatic->id = $objp->socid; $thirdpartystatic->id = $objp->socid;
$thirdpartystatic->name = $objp->name; $thirdpartystatic->name = $objp->name;
@ -465,8 +478,8 @@ if ($result) {
$productstatic->status = $objp->tosell; $productstatic->status = $objp->tosell;
$productstatic->status_buy = $objp->tobuy; $productstatic->status_buy = $objp->tobuy;
$productstatic->accountancy_code_buy = $objp->accountancy_code_buy; $productstatic->accountancy_code_buy = $objp->accountancy_code_buy;
$productstatic->accountancy_code_buy_intra = $objp->accountancy_code_sell_buy; $productstatic->accountancy_code_buy_intra = $objp->accountancy_code_sell_buy_intra;
$productstatic->accountancy_code_buy_export = $objp->accountancy_code_sell_buy; $productstatic->accountancy_code_buy_export = $objp->accountancy_code_sell_buy_export;
$accountingaccountstatic->rowid = $objp->fk_compte; $accountingaccountstatic->rowid = $objp->fk_compte;
$accountingaccountstatic->label = $objp->label_account; $accountingaccountstatic->label = $objp->label_account;
@ -481,7 +494,13 @@ if ($result) {
// Ref Invoice // Ref Invoice
print '<td class="nowraponall">'.$facturefournisseur_static->getNomUrl(1).'</td>'; print '<td class="nowraponall">'.$facturefournisseur_static->getNomUrl(1).'</td>';
print '<td class="tdoverflowonsmartphone">'; // Ref supplier invoice
print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($objp->ref_supplier).'">';
print $objp->ref_supplier;
print '</td>';
// Supplier invoice label
print '<td class="tdoverflowonsmartphone small" title="'.dol_escape_htmltag($objp->invoice_label).'">';
print $objp->invoice_label; print $objp->invoice_label;
print '</td>'; print '</td>';
@ -501,8 +520,8 @@ if ($result) {
} }
print '</td>'; print '</td>';
print '<td class="tdoverflowonsmartphone">'; print '<td class="tdoverflowonsmartphone small">';
$text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description)); $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description, 1));
$trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION;
print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description); print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description);
print '</td>'; print '</td>';
@ -521,7 +540,7 @@ if ($result) {
} }
print '</td>'; print '</td>';
print '<td>'.$objp->tva_intra.'</td>'; print '<td class="tdoverflowmax80" title="'.dol_escape_htmltag($objp->tva_intra).'">'.dol_escape_htmltag($objp->tva_intra).'</td>';
print '<td>'; print '<td>';
print $accountingaccountstatic->getNomUrl(0, 1, 1, '', 1); print $accountingaccountstatic->getNomUrl(0, 1, 1, '', 1);

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