Merge branch 'develop' into 14_fix_sql_extrafields

This commit is contained in:
Laurent Destailleur 2022-02-10 10:13:24 +01:00 committed by GitHub
commit 11bef4e681
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4651 changed files with 125843 additions and 57566 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
@ -116,13 +117,13 @@ a process to follow to optimize the chance to have PRs merged efficiently...
Also, some code changes need a prior approbation: Also, some code changes need a prior approbation:
* if you want to include a new external library (into htdocs/includes directory), please ask before to the core project manager (mention @dolibarr-yoda in your issue) to see if such a library can be accepted. * if you want to include a new external library (into htdocs/includes directory), please ask before to the core project manager (mention @dolibarr-jedi in your issue) to see if such a library can be accepted.
* if you add a new table, you must first create a page on https://wiki.dolibarr.org/index.php/Category:Table_SQL (copy an existing page changing its name to see it into this index page). Then ask the project manager (@dolibarr-yoda) if the new data model you plan to add is compatible with curent and future works in progress and can be accepted as you suggest. * if you add a new tables or fields, you MUST first submit a standalone PR with the data structure changes you plan to add/modify (and only data structure changes). Start development only once this data structure has been accepted.
Once a PR has been submitted, you may need to wait for its integration. It is common that the project leader let the PR open for a long delay to allow every developer discuss about the PR (A label is added in such a case). Once a PR has been submitted, you may need to wait for its integration. It is common that the project leader let the PR open for a long delay to allow every developer discuss about the PR (A label is added in such a case).
If the label of PR start with "Draft" or "WIP" (Work In Progress), it will not be analyzed for merging until you change the label of PR (but it can be analyzed for discussion). If the label of PR start with "Draft" or "WIP" (Work In Progress), it will not be analyzed for merging until you change the label of the PR (but it can be analyzed for discussion).
If your PR has errors reported by the Continuous Integration Platform, it means your PR is not valid and nothing will be done with it. It will be kept open to allow developers to fix this, or it may be closed several month later. Don't expect anything on your PR if you have such errors, you MUST first fix the Continuous Integration error to have it taken into consideration. If your PR has errors reported by the Continuous Integration Platform, it means your PR is not valid and nothing will be done with it. It will be kept open to allow developers to fix this, or it may be closed several month later. Don't expect anything on your PR if you have such errors, you MUST first fix the Continuous Integration error to have it taken into consideration.

2
.github/FUNDING.yml vendored
View File

@ -2,4 +2,4 @@
open_collective: dolibarr open_collective: dolibarr
custom: https://wiki.dolibarr.org/index.php/Subscribe custom: https://wiki.dolibarr.org/index.php/Subscribe
# github: [eldy] github: [eldy]

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

@ -1,18 +1,18 @@
# Instructions # Instructions
*This is a template to help you make good pull requests. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report.* *This is a template to help you make good pull requests. 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:* *Please:*
- *only keep the "Fix", "Close" or "New" section* - *only keep the "FIX", "CLOSE" or "NEW" section* (use uppercase to have the PR appears into the ChangeLog, lowercase will not appears)
- *follow the project [contributing guidelines](/.github/CONTRIBUTING.md)* - *follow the project [contributing guidelines](/.github/CONTRIBUTING.md)*
- *replace the bracket enclosed textswith meaningful informations* - *replace the bracket enclosed texts with meaningful information*
# Fix #[*issue_number Short description*] # FIX|Fix #[*issue_number Short description*]
[*Long description*] [*Long description*]
# Close #[*issue_number Short description*] # CLOSE|Close #[*issue_number Short description*]
[*Long description*] [*Long description*]
# New [*Short description*] # NEW|New [*Short description*]
[*Long description*] [*Long description*]

View File

@ -57,7 +57,7 @@ jobs:
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
@ -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

@ -170,12 +170,6 @@ source_file = htdocs/langs/en_US/hrm.lang
source_lang = en_US source_lang = en_US
type = MOZILLAPROPERTIES type = MOZILLAPROPERTIES
[dolibarr.intracommreport]
file_filter = htdocs/langs/<lang>/intracommreport.lang
source_file = htdocs/langs/en_US/intracommreport.lang
source_lang = en_US
type = MOZILLAPROPERTIES
[dolibarr.install] [dolibarr.install]
file_filter = htdocs/langs/<lang>/install.lang file_filter = htdocs/langs/<lang>/install.lang
source_file = htdocs/langs/en_US/install.lang source_file = htdocs/langs/en_US/install.lang
@ -188,6 +182,12 @@ source_file = htdocs/langs/en_US/interventions.lang
source_lang = en_US source_lang = en_US
type = MOZILLAPROPERTIES type = MOZILLAPROPERTIES
[dolibarr.intracommreport]
file_filter = htdocs/langs/<lang>/intracommreport.lang
source_file = htdocs/langs/en_US/intracommreport.lang
source_lang = en_US
type = MOZILLAPROPERTIES
[dolibarr.knowledgemanagement] [dolibarr.knowledgemanagement]
file_filter = htdocs/langs/<lang>/knowledgemanagement.lang file_filter = htdocs/langs/<lang>/knowledgemanagement.lang
source_file = htdocs/langs/en_US/knowledgemanagement.lang source_file = htdocs/langs/en_US/knowledgemanagement.lang
@ -392,18 +392,18 @@ source_file = htdocs/langs/en_US/stripe.lang
source_lang = en_US source_lang = en_US
type = MOZILLAPROPERTIES type = MOZILLAPROPERTIES
[dolibarr.suppliers]
file_filter = htdocs/langs/<lang>/suppliers.lang
source_file = htdocs/langs/en_US/suppliers.lang
source_lang = en_US
type = MOZILLAPROPERTIES
[dolibarr.supplier_proposal] [dolibarr.supplier_proposal]
file_filter = htdocs/langs/<lang>/supplier_proposal.lang file_filter = htdocs/langs/<lang>/supplier_proposal.lang
source_file = htdocs/langs/en_US/supplier_proposal.lang source_file = htdocs/langs/en_US/supplier_proposal.lang
source_lang = en_US source_lang = en_US
type = MOZILLAPROPERTIES type = MOZILLAPROPERTIES
[dolibarr.suppliers]
file_filter = htdocs/langs/<lang>/suppliers.lang
source_file = htdocs/langs/en_US/suppliers.lang
source_lang = en_US
type = MOZILLAPROPERTIES
[dolibarr.ticket] [dolibarr.ticket]
file_filter = htdocs/langs/<lang>/ticket.lang file_filter = htdocs/langs/<lang>/ticket.lang
source_file = htdocs/langs/en_US/ticket.lang source_file = htdocs/langs/en_US/ticket.lang

168
ChangeLog
View File

@ -3,6 +3,164 @@ English Dolibarr ChangeLog
-------------------------------------------------------------- --------------------------------------------------------------
***** ChangeLog for 15.0.0 compared to 14.0.0 *****
For users:
---------------
NEW: Online proposal signature
NEW: Can define some max limit on expense report (per period, per type or expense, ...)
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: #18401 Add __NEWREF__ subtitute to get new object reference.
NEW: #18403 Add __URL_SHIPMENT__ substitute to get the URL of a shipment
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: #18046 Add tags on ticket/categories
NEW: #18326 Workflow: Close order on shipment closing.
NEW: #18770 Can enter the buying price (for Weighted Average Price update) on lines during the reception step
NEW: #18814 Add legal form for Sweden
NEW: #18820 Accountancy - Add product account in import/export of thirdparty (level 3)
NEW: Accountancy - Format FEC/FEC2 - Add column NumFacture
NEW: Add $dolibarr_main_db_readonly in conf.php for readonly access.
NEW: add auto creation of agenda event on supplier_order cancellation
NEW: Add a PDF document template for Manufacturing Orders
NEW: Add budget field into task #18986
NEW: add cancel button to `classify reception` form on supplier_orders
NEW: Added address field into contacts list
NEW: Added documents page and send mail possibility in payments
NEW: Add edit option in propal
NEW: Added linked files page and send mail possibility in payments
NEW: Add field date from/to in customer and supplier payment list
NEW: Add filter from date to date into action/evt list
NEW: Add import / export of MO and BOMLines - Close #18499
NEW: Adding accounting export model for iSuite Expert
NEW: add link to an element by ref
NEW: add missing printFieldListFrom hook call on several lists
NEW: add MRP into Object Linked Box
NEW: Add option to hide customer code on PDF documents
NEW: Add param $nolog to avoid logging into dol_delete_recursive_dir()
NEW: Add sale representative in order and invoice list
NEW: add a setting to create PDF in PDF/A - 1b format #18990
NEW: Add `SOCIETE_SHOW_VAT_IN_LIST` to display VAT number in combo list of thirdparties
NEW: Add sortorder on units list
NEW: Adds PDF_HIDE_PRODUCT_LABEL_IN_SUPPLIER_LINES to hide product label in supplier order lines
NEW: Add STOCK_MOVEMENT_LIST_HIDE_UNIT_PRICE to hide unit price on some pages
NEW: add support for zstd compression
NEW: Allow drag and drop on kits
NEW: Allow exporting supplier order validation date + validation user
NEW: Allows product ref generation after the form is validated with PRODUCT_GENERATE_REF_AFTER_FORM
NEW: autocomplete account group when editing an account card
NEW: Auto create invoice for payment done on an order with online payment link of order
NEW: Can edit fields of proposal when proposal is not yet signed
NEW: Can edit the translation key of an overwrote translation key.
NEW: can enable/disable external calendar by default
NEW: Can hide sender name on PDF documents
NEW: Can select lot from a combo list of existing batch numbers (in MRP consumtion)
NEW: Can set the default BOM on a product
NEW: Can set/unset the usual working day of the week (friday, saturday, sunday)
NEW: Can show progression of task into combo list of tasks
NEW: can upload the odt file for the product doc template
NEW: Contract - Add From/to input on search date
NEW: Customer Display with TakePOS
NEW: Split Sale in TakePOS
NEW: Customer invoice template list - Add input date from/to
NEW: date filter on project list and task list From->To
NEW: display shipping method and tracking url on shipment list
NEW: expense reports: conf to force amounts to be entered only including taxes
NEW: expense reports: conf to pre-fill start/end dates with bounds of current month
NEW: expense reports: show link to already existing overlapping expense report
NEW: expense reports: can make project field mandatory on lines
NEW: Expose bank account holder, label and number
NEW: feature #18986
NEW: field and behavior in product object
NEW: generate intervention from time spent
NEW: holiday: handle monthly balance updates with cronjob
NEW: HRM integration, source code
NEW: HRM admin - Add tabs
NEW: HRM - Include more options to manage/custom dashboard
NEW: Increase size of params of actions for emailcollector
NEW: Invoice list - Use complete country select field with EEC or not
NEW: mass action delete, no more break if at least one object has child
NEW: mass action paid on customer invoice list
NEW: massaction validate on supplier orders list
NEW: Mass action send email to all attendees of an event.
NEW: expense reports: conf to pre-fill start/end dates with bounds of current month
NEW: Option "Add a link on the PDF to make the online payment"
NEW: More options to generate PDF (show Frame option, width of picture option)
NEW: Preview of pdf files of expense report lines
NEW: print without details
NEW: project time spent: conf to prevent recording time after X months
NEW: rewrite bind accountancy code finding on customer and sales invoice
NEW: Societe - Add perentity functionality on customer/supplier accountancy auxiliary account
NEW: Survey - Add a clickable link in email send
NEW: Social Contributions - Add from/to filter on list
NEW: Supplier order and proposal - Add From/to input on search date
NEW: Task - Add From/to input on search date
NEW: Add theme option THEME_ELDY_USEBORDERONTABLE
NEW: The Anti-CSRF protection MAIN_SECURITY_CSRF_WITH_TOKEN is on to value 1 by default
NEW: Update SQL : install and migration
NEW: Use an ajax call for the clicktodial feature instead of href link.
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: Editing a page in website module keep old page with name .back
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:
---------------
NEW: Introduce method hasRight
NEW: Can use textarea field into a confirm popup.
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: Add API /approve and /makeOrder for purchase orders.
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 code codebar column on serial/lot structure
NEW: Add date_valid and date_approve columns in the list of supplier orders
NEW: add hook `beforeBodyClose`
NEW: Add hook hookGetEntity.
NEW: add hookmanager on note pages
NEW: add hook 'menuLeftMenuItems' to filter the leftmenu items
NEW: Add the property "copytoclipboard" in modulebuilder
NEW: api for knowledgemanagement
NEW: API get list of legal form of business
NEW: API list of staff units
NEW: hook after rank update
NEW: printFieldListFrom hook call on several lists
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: 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:
* 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.
* 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 'action=delete&file=...' has been replaced with 'action=deletefile&file=...' to avoid confusion with deletion of object lines.
* 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
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 ***** ***** ChangeLog for 14.0.5 compared to 14.0.4 *****
FIX: 13.0: printFieldListWhere called twice on same query FIX: 13.0: printFieldListWhere called twice on same query
@ -502,7 +660,7 @@ Following changes may create regressions for some external modules, but were nec
* The ICS value for direct debit or credit transfer is now stored on each bank account instead of into the global setup. * The ICS value for direct debit or credit transfer is now stored on each bank account instead of into the global setup.
* API /setup/shipment_methods has been replaced with API /setup/shipping_methods * API /setup/shipment_methods has been replaced with API /setup/shipping_methods
* Field "total" renamed into "total_ht" for table llx_facture, llx_facture_rec for better field name consistency * Field "total" renamed into "total_ht" for table llx_facture, llx_facture_rec for better field name consistency
* Field "tva" renamed into "total_tva" for table llx_propal, llx_supplier_proposal, llx_commande, llx_commande_fournisseur for better field name consistency * Field "tva" renamed into "total_tva" for llx_facture, table llx_propal, llx_supplier_proposal, llx_commande, llx_commande_fournisseur for better field name consistency
* Field "total" renamed into "total_ttc" for table llx_propal, llx_supplier_proposal for better field name consistency * Field "total" renamed into "total_ttc" for table llx_propal, llx_supplier_proposal for better field name consistency
* If your database is PostgreSQL, you must use version 9.1.0 or more (Dolibarr need the SQL function CONCAT) * If your database is PostgreSQL, you must use version 9.1.0 or more (Dolibarr need the SQL function CONCAT)
* If your database is MySQL or MariaDB, you need at least version 5.1 * If your database is MySQL or MariaDB, you need at least version 5.1
@ -547,11 +705,11 @@ FIX: wrong users count in multicompany transverse mode
***** ChangeLog for 13.0.4 compared to 13.0.3 ***** ***** ChangeLog for 13.0.4 compared to 13.0.3 *****
FIX: Allow disabling of a module (not a dangerous action) even if there is problem with token (due to bugged modules). FIX: Allow disabling of a module (not a dangerous action) even if there is problem with token (due to bugged modules).
FIX: 13.0 - fatal - missing inclusion of ajax.lib.php for calling `ajax_autocompleter()` FIX: 13.0 - fatal - missing inclusion of ajax.lib.php for calling 'ajax_autocompleter()'
FIX: #17919 pictures in docs. FIX: #17919 pictures in docs
FIX: #18006 FIX: #18006
FIX: Accountancy - if we define a date start, automatic binding try to continue to solve old binding FIX: Accountancy - if we define a date start, automatic binding try to continue to solve old binding
FIX: Accoutancy Limit date payment not registered on purchases operations FIX: Accountancy - Limit date payment not registered on purchases operations
FIX: Can't edit replacement invoice FIX: Can't edit replacement invoice
FIX: deposit can create credit note in payment conf FIX: deposit can create credit note in payment conf
FIX: division by zero on create FIX: division by zero on create
@ -655,7 +813,7 @@ FIX: File attachment on lots/batches
FIX: handling $heightforinfotot when he's superior to a page height on Supplier Invoice FIX: handling $heightforinfotot when he's superior to a page height on Supplier Invoice
FIX: hourglass and hide button to pay FIX: hourglass and hide button to pay
FIX: massaction validate invoice do not regenerate PDF FIX: massaction validate invoice do not regenerate PDF
FIX: missing mp4 video mime FIX: #16627 fix missing mp4 video mime
FIX: picto on shipment to reset qty to 0. Some quantities were not reset. FIX: picto on shipment to reset qty to 0. Some quantities were not reset.
FIX: Protection to avoid #16504 FIX: Protection to avoid #16504
FIX: rounding amount on card updating FIX: rounding amount on card updating

View File

@ -8,12 +8,10 @@ Il est simple d'utilisation et modulaire, vous permettant de n'activez que les f
![ScreenShot](https://www.dolibarr.org/medias/dolibarr_screenshot1_1920x1080.jpg) ![ScreenShot](https://www.dolibarr.org/medias/dolibarr_screenshot1_1920x1080.jpg)
## LICENCE ## LICENCE
Dolibarr est distribué sous les termes de la licence GNU General Public License v3+ ou supérieure. Dolibarr est distribué sous les termes de la licence GNU General Public License v3+ ou supérieure.
## INSTALLER DOLIBARR ## INSTALLER DOLIBARR
### Configuration simple ### Configuration simple
@ -54,7 +52,6 @@ Vous pouvez aussi utiliser un serveur Web et une base de données prise en charg
- Suivez les instructions de l'installateur - Suivez les instructions de l'installateur
## METTRE A JOUR DOLIBARR ## METTRE A JOUR DOLIBARR
Pour mettre à jour Dolibarr depuis une vieille version vers celle ci: Pour mettre à jour Dolibarr depuis une vieille version vers celle ci:
@ -65,14 +62,12 @@ Pour mettre à jour Dolibarr depuis une vieille version vers celle ci:
- Au prochain accès, Dolibarr proposera la page de "mise à jour" des données (si nécessaire). - Au prochain accès, Dolibarr proposera la page de "mise à jour" des données (si nécessaire).
Si un fichier install.lock existe pour verrouiller le processus de mise à jour, il sera demandé de le supprimer manuellement (vous devriez trouver le fichier install.lock dans le répertoire utilisé pour stocker les documents générés ou transférés sur le serveur. Dans la plupart des cas, c'est le répertoire appelé "documents") Si un fichier install.lock existe pour verrouiller le processus de mise à jour, il sera demandé de le supprimer manuellement (vous devriez trouver le fichier install.lock dans le répertoire utilisé pour stocker les documents générés ou transférés sur le serveur. Dans la plupart des cas, c'est le répertoire appelé "documents")
*Note: Le processus de migration peut être lancé manuellement et plusieurs fois, sans risque, en appelant la page /install/* Note: *Le processus de migration peut être lancé manuellement et plusieurs fois, sans risque, en appelant la page /install/*
## CE QUI EST NOUVEAU ## CE QUI EST NOUVEAU
See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) file. See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) file.
## CE QUE DOLIBARR PEUT FAIRE ## CE QUE DOLIBARR PEUT FAIRE
### Modules principaux (tous optionnels) ### Modules principaux (tous optionnels)
@ -122,7 +117,7 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
- Peux être multi-société par ajout du module externe multi-société. - Peux être multi-société par ajout du module externe multi-société.
- Plusieurs thèmes visuels. - Plusieurs thèmes visuels.
- Application simple à utiliser. - Application simple à utiliser.
- Requiert PHP et MariaDb, Mysql ou Postgresql (Voir versions exactes sur https://wiki.dolibarr.org/index.php/Prérequis). - Requiert PHP et MariaDb, Mysql ou Postgresql (Voir versions exactes sur [https://wiki.dolibarr.org/index.php/Prérequis](https://wiki.dolibarr.org/index.php/Prérequis)).
- Compatible avec toutes les offres Cloud du marché respectant les prérequis de base de données et PHP. - Compatible avec toutes les offres Cloud du marché respectant les prérequis de base de données et PHP.
- APIs. - APIs.
- Génération PDF et ODT des éléments (factures, propositions commerciales, commandes, bons expéditions, etc...) - Génération PDF et ODT des éléments (factures, propositions commerciales, commandes, bons expéditions, etc...)
@ -142,7 +137,6 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
Dolibarr peut aussi être étendu à volonté avec l'ajout de module/applications externes développées par des développeus tiers, disponible sur [DoliStore](https://www.dolistore.com). Dolibarr peut aussi être étendu à volonté avec l'ajout de module/applications externes développées par des développeus tiers, disponible sur [DoliStore](https://www.dolistore.com).
## CE QUE DOLIBARR NE PEUT PAS (ENCORE) FAIRE ## CE QUE DOLIBARR NE PEUT PAS (ENCORE) FAIRE
Voici un liste de fonctionnalités pas encore gérées par Dolibarr: Voici un liste de fonctionnalités pas encore gérées par Dolibarr:
@ -152,18 +146,15 @@ Voici un liste de fonctionnalités pas encore gérées par Dolibarr:
- Dolibarr n'embarque pas de Webmail intégré nativement. - Dolibarr n'embarque pas de Webmail intégré nativement.
- Dolibarr ne fait pas le café (pas encore). - Dolibarr ne fait pas le café (pas encore).
## DOCUMENTATION ## DOCUMENTATION
La documentation utilisateur, développeur et traducteur est disponible sous forme de ressources de la communauté via le site [Wiki](https://wiki.dolibarr.org). La documentation utilisateur, développeur et traducteur est disponible sous forme de ressources de la communauté via le site [Wiki](https://wiki.dolibarr.org).
## CONTRIBUER ## CONTRIBUER
Ce projet existe grâce à ses nombreux contributeurs [[Contribuer](https://github.com/Dolibarr/dolibarr/blob/develop/.github/CONTRIBUTING.md)]. Ce projet existe grâce à ses nombreux contributeurs [[Contribuer](https://github.com/Dolibarr/dolibarr/blob/develop/.github/CONTRIBUTING.md)].
<a href="https://github.com/Dolibarr/dolibarr/graphs/contributors"><img src="https://opencollective.com/dolibarr/contributors.svg?width=890&button=false" /></a> [![Dolibarr](https://opencollective.com/dolibarr/contributors.svg?width=890&button=false)](https://github.com/Dolibarr/dolibarr/graphs/contributors)
## CREDITS ## CREDITS
@ -171,7 +162,6 @@ Dolibarr est le résultat du travail de nombreux contributeurs depuis des année
Voir le fichier [COPYRIGHT](https://github.com/Dolibarr/dolibarr/blob/develop/COPYRIGHT) Voir le fichier [COPYRIGHT](https://github.com/Dolibarr/dolibarr/blob/develop/COPYRIGHT)
## ACTUALITES ET RESEAUX SOCIAUX ## ACTUALITES ET RESEAUX SOCIAUX
Suivez le projet Dolibarr project sur les réseaux francophones Suivez le projet Dolibarr project sur les réseaux francophones

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…).
@ -43,7 +44,7 @@ You can use a web server and a supported database (MariaDB, MySQL or PostgreSQL)
On GNU/Linux, first check if your distribution has already packaged Dolibarr. On GNU/Linux, first check if your distribution has already packaged Dolibarr.
#### Generic install steps: #### Generic install steps
- Check that your installed PHP version is supported [see PHP support](https://wiki.dolibarr.org/index.php/Releases). - Check that your installed PHP version is supported [see PHP support](https://wiki.dolibarr.org/index.php/Releases).
@ -71,28 +72,24 @@ On GNU/Linux, first check if your distribution has already packaged Dolibarr.
- Follow the installer instructions - Follow the installer instructions
### Saas/Cloud setup ### Saas/Cloud setup
If you don't have time to install it yourself, you can try some commercial 'ready to use' Cloud offers (See https://saas.dolibarr.org). However, this third solution is not free. If you don't have time to install it yourself, you can try some commercial 'ready to use' Cloud offers (See [https://saas.dolibarr.org](https://saas.dolibarr.org)). However, this third solution is not free.
## UPGRADING ## UPGRADING
Dolibarr supports upgrading usually wihtout the need for any (commercial) support (depending on if you use any commercial extensions) and supports upgrading all the way from any version after 2.8 without breakage. This is unique in the ERP ecosystem and a benefit our users highly appreciate! Dolibarr supports upgrading, usually without the need for any (commercial) support (depending on if you use any commercial extensions). It supports upgrading all the way from any version after 2.8 without breakage. This is unique in the ERP ecosystem and a benefit our users highly appreciate!
- At first make a backup of your Dolibarr files & than [see](https://wiki.dolibarr.org/index.php/Installation_-_Upgrade#Upgrade_Dolibarr) - At first make a backup of your Dolibarr files & then [see](https://wiki.dolibarr.org/index.php/Installation_-_Upgrade#Upgrade_Dolibarr)
- Check that your installed PHP version is supported by the new version [see PHP support](./doc/phpmatrix.md). - Check that your installed PHP version is supported by the new version [see PHP support](./doc/phpmatrix.md).
- Overwrite all old files from 'dolibarr' directory with files provided into the new version's package. - Overwrite all old files from 'dolibarr' directory with files provided into the new version's package.
- At first next access, Dolibarr will redirect you to the "install/" page to follow the upgrade process. - At first next access, Dolibarr will redirect you to the "install/" page to follow the upgrade process.
 If an `install.lock` file exists to lock any other upgrade process, the application will ask you to remove the file manually (you should find the `install.lock` file in the directory used to store generated and uploaded documents, in most cases, it is the directory called "*documents*").  If an `install.lock` file exists to lock any other upgrade process, the application will ask you to remove the file manually (you should find the `install.lock` file in the directory used to store generated and uploaded documents, in most cases, it is the directory called "*documents*").
## WHAT'S NEW ## WHAT'S NEW
See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) file. See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) file.
## FEATURES ## FEATURES
### Main application/modules (all optional) ### Main application/modules (all optional)
@ -101,6 +98,7 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
- Members/Membership/Foundation management - Members/Membership/Foundation management
Product Management Product Management
- Products and/or Services catalog - Products and/or Services catalog
- Stock / Warehouse management + Inventory - Stock / Warehouse management + Inventory
- Barcodes - Barcodes
@ -110,6 +108,7 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
- Manufacturing Orders - Manufacturing Orders
Customer/Sales Management Customer/Sales Management
- Customers/Prospects + Contacts management - Customers/Prospects + Contacts management
- Opportunities or Leads management - Opportunities or Leads management
- Commercial proposals management - Commercial proposals management
@ -122,6 +121,7 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
- Point of Sale (POS) - Point of Sale (POS)
Supplier/Purchase Management Supplier/Purchase Management
- Suppliers/Vendors + Contacts - Suppliers/Vendors + Contacts
- Supplier (price) requests - Supplier (price) requests
- Purchase Orders management - Purchase Orders management
@ -130,6 +130,7 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
- INCOTERMS - INCOTERMS
Finance / Accounting Finance / Accounting
- Invoices / Payments - Invoices / Payments
- Bank accounts management - Bank accounts management
- Direct debit orders management (European SEPA) - Direct debit orders management (European SEPA)
@ -140,18 +141,19 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
- Reports - Reports
Collaboration Collaboration
- Shared calendar/agenda (with ical and vcal export for third party tools integration) - Shared calendar/agenda (with ical and vcal export for third party tools integration)
- Projects & Tasks management - Projects & Tasks management
- Ticket System - Ticket System
- Surveys - Surveys
HR HR
- Employee's leave requests management - Employee's leave requests management
- Expense reports - Expense reports
- Recruitment management - Recruitment management
- Timesheets - Timesheets
### Other application/modules ### Other application/modules
- Electronic Document Management (EDM) - Electronic Document Management (EDM)
@ -171,7 +173,6 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
(around 100 modules available by default, 1000+ on the addon market place) (around 100 modules available by default, 1000+ on the addon market place)
### Other general features ### Other general features
- Localization in most major languages - Localization in most major languages
@ -190,13 +191,12 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
- Canadian double taxes (federal/province) and other countries using cumulative VAT - Canadian double taxes (federal/province) and other countries using cumulative VAT
- Tunisian tax stamp - Tunisian tax stamp
- Argentina invoice numbering using A,B,C... - Argentina invoice numbering using A,B,C...
- Compatible with [European directives] (https://europa.eu/legislation_summaries/taxation/l31057_en.htm) (2006/112/CE ... 2010/45/UE) - Compatible with [European directives](https://europa.eu/legislation_summaries/taxation/l31057_en.htm) (2006/112/CE ... 2010/45/UE)
- Compatible with European GDPR rules - Compatible with European GDPR rules
- ... - ...
- Flexible PDF & ODT generation for invoices, proposals, orders... - Flexible PDF & ODT generation for invoices, proposals, orders...
- ... - ...
### System Environment / Requirements ### System Environment / Requirements
- PHP - PHP
@ -205,12 +205,10 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
See exact requirements on the [Wiki](https://wiki.dolibarr.org/index.php/Prerequisite) See exact requirements on the [Wiki](https://wiki.dolibarr.org/index.php/Prerequisite)
### Extending ### Extending
Dolibarr can be extended with a lot of other external application or modules from third party developers available at the [DoliStore](https://www.dolistore.com). Dolibarr can be extended with a lot of other external application or modules from third party developers available at the [DoliStore](https://www.dolistore.com).
## WHAT DOLIBARR CAN'T DO YET ## WHAT DOLIBARR CAN'T DO YET
These are features that Dolibarr does **not** yet fully support: These are features that Dolibarr does **not** yet fully support:
@ -220,12 +218,10 @@ These are features that Dolibarr does **not** yet fully support:
- No native embedded Webmail, but you can send email to contacts in Dolibarr with e.g. offers, invoices, etc. - No native embedded Webmail, but you can send email to contacts in Dolibarr with e.g. offers, invoices, etc.
- Dolibarr can't do coffee (yet) - Dolibarr can't do coffee (yet)
## DOCUMENTATION ## DOCUMENTATION
Administrator, user, developer and translator's documentations are available along with other community resources in the [Wiki](https://wiki.dolibarr.org). Administrator, user, developer and translator's documentations are available along with other community resources in the [Wiki](https://wiki.dolibarr.org).
## CONTRIBUTING ## CONTRIBUTING
This project exists thanks to all the people who contribute. This project exists thanks to all the people who contribute.
@ -233,8 +229,7 @@ Please read the instructions how to contribute (report a bug/error, a feature re
A view on Contributors: A view on Contributors:
<a href="https://github.com/Dolibarr/dolibarr/graphs/contributors"><img src="https://opencollective.com/dolibarr/contributors.svg?width=890&button=false" /></a> [![Dolibarr](https://opencollective.com/dolibarr/contributors.svg?width=890&button=false)](https://github.com/Dolibarr/dolibarr/graphs/contributors)
## CREDITS ## CREDITS
@ -242,7 +237,6 @@ Dolibarr is the work of many contributors over the years and uses some fine PHP
See [COPYRIGHT](https://github.com/Dolibarr/dolibarr/blob/develop/COPYRIGHT) file. See [COPYRIGHT](https://github.com/Dolibarr/dolibarr/blob/develop/COPYRIGHT) file.
## NEWS AND SOCIAL NETWORKS ## NEWS AND SOCIAL NETWORKS
Follow Dolibarr project on: Follow Dolibarr project on:
@ -253,8 +247,6 @@ Follow Dolibarr project on:
- [YouTube](https://www.youtube.com/user/DolibarrERPCRM) - [YouTube](https://www.youtube.com/user/DolibarrERPCRM)
- [GitHub](https://github.com/Dolibarr/dolibarr) - [GitHub](https://github.com/Dolibarr/dolibarr)
### Sponsors ### Sponsors
Support this project by becoming a sponsor. Your logo will show up here. 🙏 [[Become a sponsor/backer](https://opencollective.com/dolibarr#backer)] Support this project by becoming a sponsor. Your logo will show up here. 🙏 [[Become a sponsor/backer](https://opencollective.com/dolibarr#backer)]

View File

@ -5,15 +5,15 @@ This file contains some policies about the security reports on Dolibarr ERP CRM
## Supported Versions for security reports ## Supported Versions for security reports
| Version | Supported | | Version | Supported |
| --------- | ------------------ | | ---------- | ---------------------- |
| <= 12.* | :x: | | <= 14.0.4 | :x: |
| >= 13.* | :white_check_mark: | | >= 14.0.5+ | :white_check_mark: except CSRF attacks|
| >= 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 (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
@ -23,7 +23,7 @@ If you believe you've found a security bug in our service, we are happy to work
Any type of denial of service attacks is strictly forbidden, as well as any interference with network equipment and Dolibarr infrastructure. Any type of denial of service attacks is strictly forbidden, as well as any interference with network equipment and Dolibarr infrastructure.
We recommand to install Dolibarr ERP CRM on your own server (as most Open Source software, download and use is free: https://www.dolibarr.org/download) to get access on every side of application. We recommand to install Dolibarr ERP CRM on your own server (as most Open Source software, download and use is free: [https://www.dolibarr.org/download](https://www.dolibarr.org/download)) to get access on every side of application.
### User Agent ### User Agent
@ -31,8 +31,7 @@ If you try to find bug on Dolibarr, we recommend to append to your user-agent he
### Account access ### Account access
You can install the web application yourself on your own platform/server so you get full access to application and sources. Download the zip of the files to put into your own web server virtual host from https://www.dolibarr.org/download You can install the web application yourself on your own platform/server so you get full access to application and sources. Download the zip of the files to put into your own web server virtual host from [https://www.dolibarr.org/download](https://www.dolibarr.org/download)
## Eligibility and Responsible Disclosure ## Eligibility and Responsible Disclosure
@ -46,7 +45,6 @@ You must avoid tests that could cause degradation or interruption of our service
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.
## Scope for qualified vulnerabilities ## Scope for qualified vulnerabilities
ONLY vulnerabilities discovered, when the following setup on test platform is used, are "valid": ONLY vulnerabilities discovered, when the following setup on test platform is used, are "valid":
@ -54,23 +52,22 @@ ONLY vulnerabilities discovered, when the following setup on test platform is us
* $dolibarr_main_prod must be set to 1 into conf.php * $dolibarr_main_prod must be set to 1 into conf.php
* $dolibarr_nocsrfcheck must be kept to the value 0 into conf.php (this is the default value) * $dolibarr_nocsrfcheck must be kept to the value 0 into conf.php (this is the default value)
* $dolibarr_main_force_https must be set to something else than 0. * $dolibarr_main_force_https must be set to something else than 0.
* The constant MAIN_SECURITY_CSRF_WITH_TOKEN must be set to 1 into backoffice menu Home - Setup - Other (this protection should be set to 1 soon by default) * The constant MAIN_SECURITY_CSRF_WITH_TOKEN must be set to 3 into backoffice menu Home - Setup - Other (this protection should be set to 3 soon by default)
* 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 only the documents directory is in write mode. The root directory called htdocs must be readonly.
* CSRF attacks are accepted when using a POST URL, but when using GET URL, they are validated only for creating, updating or deleting data resctricted from pages restricted to admin users. * 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.
Scope is the web application (back office) and the APIs. Scope is the web application (back office) and the APIs.
## Qualifying vulnerabilities for reporting ## Qualifying vulnerabilities for reporting
* 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
@ -81,7 +78,6 @@ Scope is the web application (back office) and the APIs.
* Software version disclosure (for non admin users only) * Software version disclosure (for non admin users only)
* Stack traces or path disclosure (for non admin users only) * Stack traces or path disclosure (for non admin users only)
## Non-qualifying vulnerabilities for reporting ## Non-qualifying vulnerabilities for reporting
* "Self" XSS * "Self" XSS
@ -90,9 +86,8 @@ Scope is the web application (back office) and the APIs.
* Clickjacking/UI redressing * Clickjacking/UI redressing
* Physical or social engineering attempts or issues that require physical access to a victim’s computer/device * Physical or social engineering attempts or issues that require physical access to a victim’s computer/device
* Presence of autocomplete attribute on web forms * Presence of autocomplete attribute on web forms
* Vulnerabilities affecting outdated browsers or platforms * Vulnerabilities affecting outdated browsers or platforms, or vulnerabilities inside browsers themself.
* Logout and other instances of low-severity Cross-Site Request Forgery * Logout and other instances of low-severity Cross-Site Request Forgery
* Missing cookie flags
* Missing security-related HTTP headers which do not lead directly to a vulnerability * Missing security-related HTTP headers which do not lead directly to a vulnerability
* Reports from automated web vulnerability scanners (Acunetix, Vega, etc.) that have not been validated * Reports from automated web vulnerability scanners (Acunetix, Vega, etc.) that have not been validated
* Invalid or missing SPF (Sender Policy Framework) records (Incomplete or missing SPF/DKIM/DMARC) * Invalid or missing SPF (Sender Policy Framework) records (Incomplete or missing SPF/DKIM/DMARC)
@ -100,4 +95,3 @@ Scope is the web application (back office) and the APIs.
* Software version or private IP disclosure when logged user is admin * Software version or private IP disclosure when logged user is admin
* Stack traces or path disclosure when logged user is admin * Stack traces or path disclosure when logged user is admin
* Any vulnerabilities due to a configuration different than the one defined into chapter "Scope for qualified vulnerabilities". * Any vulnerabilities due to a configuration different than the one defined into chapter "Scope for qualified vulnerabilities".

View File

@ -55,7 +55,6 @@ RUN echo "host mail" >> /etc/msmtprc
RUN echo "from local@localdomain.com" >> /etc/msmtprc RUN echo "from local@localdomain.com" >> /etc/msmtprc
RUN echo "domain localhost.localdomain" >> /etc/msmtprc RUN echo "domain localhost.localdomain" >> /etc/msmtprc
RUN echo "sendmail_path=/usr/bin/msmtp -t" >> /usr/local/etc/php/conf.d/php-sendmail.ini RUN echo "sendmail_path=/usr/bin/msmtp -t" >> /usr/local/etc/php/conf.d/php-sendmail.ini
RUN echo "localhost localhost.localdomain" >> /etc/hosts
EXPOSE 80 EXPOSE 80

View File

@ -35,7 +35,7 @@
"nnnick/chartjs" : "^2.9", "nnnick/chartjs" : "^2.9",
"stripe/stripe-php" : "6.43.1", "stripe/stripe-php" : "6.43.1",
"maximebf/debugbar" : "1.15.1", "maximebf/debugbar" : "1.15.1",
"symfony/var-dumper" : "3" "symfony/var-dumper" : "3.2"
}, },
"require-dev" : { "require-dev" : {
"php-parallel-lint/php-parallel-lint" : "^0", "php-parallel-lint/php-parallel-lint" : "^0",

4
composer.lock generated
View File

@ -591,7 +591,7 @@
}, },
{ {
"name": "symfony/var-dumper", "name": "symfony/var-dumper",
"version": "v3.0.0", "version": "v3.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-dumper.git", "url": "https://github.com/symfony/var-dumper.git",
@ -616,7 +616,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "3.0-dev" "dev-master": "3.2-dev"
} }
}, },
"autoload": { "autoload": {

View File

@ -200,6 +200,11 @@ with:
with with
} elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1]) >= 2)) { } elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1]) >= 2)) {
* Fix php fatal error on php 8.0 on tcpdi.php
while (list($k, $v) = each($value[1])) {
with
foreach ($value[1] as $k => $v) {
JSGANTT: JSGANTT:
@ -230,11 +235,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

@ -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...";;

View File

@ -171,7 +171,10 @@ if [ $res -ne 0 ]; then
fi fi
if [ -s "$mydir/initdemopostsql.sql" ]; then if [ -s "$mydir/initdemopostsql.sql" ]; then
echo A file initdemopostsql.sql was found, we execute it.
mysql -P$port $base < "$mydir/initdemopostsql.sql" mysql -P$port $base < "$mydir/initdemopostsql.sql"
else
echo No file initdemopostsql.sql found, we extra sql action done.
fi fi

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

@ -4,7 +4,7 @@
* *
* 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
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,

View File

@ -4,7 +4,7 @@
* *
* 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
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,

View File

@ -0,0 +1,13 @@
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)
-----------------------------------------
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

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

Binary file not shown.

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"
<Directory /home/.../htdocs/>
AllowOverride None AllowOverride None
Options -Indexes -MultiViews +FollowSymLinks -ExecCGI Options -Indexes -MultiViews +FollowSymLinks -ExecCGI
Require all granted Require all granted
</Directory>
<Directory "/home/../htdocs/cache"> # To restrict access by a HTTP basic auth
Deny from all #AuthType Basic
RemoveHandler .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml #AuthName "Authenticate to backoffice"
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 #AuthUserFile /etc/apache2/.htpasswd
</Directory> #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

@ -50,6 +50,10 @@ then
then then
aaupper="SA" aaupper="SA"
fi fi
if [ $bb = "IQ" ]
then
aaupper="SA"
fi
bblower=`echo $dirshort | nawk -F"_" '{ print tolower($2) }'` bblower=`echo $dirshort | nawk -F"_" '{ print tolower($2) }'`
@ -57,7 +61,12 @@ then
if [ "$aa" != "$bblower" -a "$dirshort" != "en_US" ] if [ "$aa" != "$bblower" -a "$dirshort" != "en_US" ]
then then
reflang="htdocs/langs/"$aa"_"$aaupper reflang="htdocs/langs/"$aa"_"$aaupper
if [ -d $reflang -a $aa"_"$bb != $aa"_"$aaupper ] echo $reflang" "$aa"_"$bb != $aa"_"$aaupper
# If $reflang is a main language to use to sanitize the alternative file
if [ -d $reflang ]
then
if [ $aa"_"$bb != $aa"_"$aaupper ]
then then
echo "***** Search original into "$reflang echo "***** Search original into "$reflang
echo $dirshort is an alternative language of $reflang echo $dirshort is an alternative language of $reflang
@ -75,5 +84,6 @@ then
done done
fi fi
fi fi
fi
done; done;
fi fi

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"

145
dev/tools/spider.php Normal file
View File

@ -0,0 +1,145 @@
#!/usr/bin/env php
<?php
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file dev/tools/spider.php
* \brief Script to spider Dolibarr app.
*
* To use it:
* - Disable module "bookmark"
* - Exclude param optioncss, token, sortfield, sortorder
*/
$crawledLinks=array();
const MAX_DEPTH=2;
/**
* @param string $url URL
* @param string $depth Depth
* @return string String
*/
function followLink($url, $depth = 0)
{
global $crawledLinks;
$crawling=array();
if ($depth>MAX_DEPTH) {
echo "<div style='color:red;'>The Crawler is giving up!</div>";
return;
}
$options=array(
'http'=>array(
'method'=>"GET",
'user-agent'=>"gfgBot/0.1\n"
)
);
$context=stream_context_create($options);
$doc=new DomDocument();
@$doc->loadHTML(file_get_contents($url, false, $context));
$links=$doc->getElementsByTagName('a');
$pageTitle=getDocTitle($doc, $url);
$metaData=getDocMetaData($doc);
foreach ($links as $i) {
$link=$i->getAttribute('href');
if (ignoreLink($link)) continue;
$link=convertLink($url, $link);
if (!in_array($link, $crawledLinks)) {
$crawledLinks[]=$link;
$crawling[]=$link;
insertIntoDatabase($link, $pageTitle, $metaData, $depth);
}
}
foreach ($crawling as $crawlURL)
followLink($crawlURL, $depth+1);
}
/**
* @param string $site Site
* @param string $path Path
* @return string String
*/
function convertLink($site, $path)
{
if (substr_compare($path, "//", 0, 2)==0)
return parse_url($site)['scheme'].$path;
elseif (substr_compare($path, "http://", 0, 7)==0 or
substr_compare($path, "https://", 0, 8)==0 or
substr_compare($path, "www.", 0, 4)==0)
return $path;
else return $site.'/'.$path;
}
/**
* @param string $url URL
* @return boolean
*/
function ignoreLink($url)
{
return $url[0]=="#" or substr($url, 0, 11) == "javascript:";
}
/**
* @param string $link URL
* @param string $title Title
* @param string $metaData Array
* @param int $depth Depth
* @return void
*/
function insertIntoDatabase($link, $title, &$metaData, $depth)
{
//global $crawledLinks;
echo "Inserting new record {URL= ".$link.", Title = '$title', Description = '".$metaData['description']."', Keywords = ' ".$metaData['keywords']."'}<br/><br/><br/>";
//²$crawledLinks[]=$link;
}
/**
* @param string $doc Doc
* @param string $url URL
* @return string URL/Title
*/
function getDocTitle(&$doc, $url)
{
$titleNodes=$doc->getElementsByTagName('title');
if (count($titleNodes)==0 or !isset($titleNodes[0]->nodeValue))
return $url;
$title=str_replace('', '\n', $titleNodes[0]->nodeValue);
return (strlen($title)<1)?$url:$title;
}
/**
* @param string $doc Doc
* @return array Array
*/
function getDocMetaData(&$doc)
{
$metaData=array();
$metaNodes=$doc->getElementsByTagName('meta');
foreach ($metaNodes as $node)
$metaData[$node->getAttribute("name")] = $node->getAttribute("content");
if (!isset($metaData['description']))
$metaData['description']='No Description Available';
if (!isset($metaData['keywords'])) $metaData['keywords']='';
return array(
'keywords'=>str_replace('', '\n', $metaData['keywords']),
'description'=>str_replace('', '\n', $metaData['description'])
);
}
followLink("http://localhost/dolibarr_dev/htdocs");

View File

@ -6,7 +6,7 @@
* *
* 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
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,

View File

@ -5,7 +5,7 @@
* *
* 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
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
@ -177,7 +177,7 @@ foreach ($filesToProcess as $fileToProcess) {
// Start reading and parsing English // Start reading and parsing English
$aEnglish = array();
if ($handle = fopen($lEnglishFile, 'r')) { if ($handle = fopen($lEnglishFile, 'r')) {
print "Read English File $lEnglishFile:\n"; print "Read English File $lEnglishFile:\n";
$cnt = 0; $cnt = 0;
@ -246,6 +246,9 @@ foreach ($filesToProcess as $fileToProcess) {
fwrite($oh, "# Dolibarr language file - Source file is en_US - ".(preg_replace('/\.lang$/', '', $fileToProcess))."\n"); fwrite($oh, "# Dolibarr language file - Source file is en_US - ".(preg_replace('/\.lang$/', '', $fileToProcess))."\n");
$fileFirstFound = array();
$lineFirstFound = array();
$cnt = 0; $cnt = 0;
while (($line = fgets($handle)) !== false) { while (($line = fgets($handle)) !== false) {
$cnt++; $cnt++;
@ -299,6 +302,7 @@ foreach ($filesToProcess as $fileToProcess) {
} }
// String exists in both files and value into alternative language differs from main language but also from english files // String exists in both files and value into alternative language differs from main language but also from english files
// so we keep it.
if ((! empty($aSecondary[$key]) && $aSecondary[$key] != $aPrimary[$key] if ((! empty($aSecondary[$key]) && $aSecondary[$key] != $aPrimary[$key]
&& ! empty($aEnglish[$key]) && $aSecondary[$key] != $aEnglish[$key]) && ! empty($aEnglish[$key]) && $aSecondary[$key] != $aEnglish[$key])
|| in_array($key, $arrayofkeytoalwayskeep) || preg_match('/^FormatDate/', $key) || preg_match('/^FormatHour/', $key) || in_array($key, $arrayofkeytoalwayskeep) || preg_match('/^FormatDate/', $key) || preg_match('/^FormatHour/', $key)

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

@ -38,6 +38,7 @@ $cancel = GETPOST('cancel', 'alpha');
$id = GETPOST('id', 'int'); $id = GETPOST('id', 'int');
$rowid = GETPOST('rowid', 'int'); $rowid = GETPOST('rowid', 'int');
$massaction = GETPOST('massaction', 'aZ09'); $massaction = GETPOST('massaction', 'aZ09');
$optioncss = GETPOST('optioncss', 'alpha');
$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'accountingaccountlist'; // To manage different context of search $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'accountingaccountlist'; // To manage different context of search
$search_account = GETPOST('search_account', 'alpha'); $search_account = GETPOST('search_account', 'alpha');
@ -51,14 +52,14 @@ $confirm = GETPOST('confirm', 'alpha');
$chartofaccounts = GETPOST('chartofaccounts', 'int'); $chartofaccounts = GETPOST('chartofaccounts', 'int');
$permissiontoadd = $user->rights->accounting->chartofaccount; $permissiontoadd = !empty($user->rights->accounting->chartofaccount);
$permissiontodelete = $user->rights->accounting->chartofaccount; $permissiontodelete = !empty($user->rights->accounting->chartofaccount);
// Security check // Security check
if ($user->socid > 0) { if ($user->socid > 0) {
accessforbidden(); accessforbidden();
} }
if (!$user->rights->accounting->chartofaccount) { if (empty($user->rights->accounting->chartofaccount)) {
accessforbidden(); accessforbidden();
} }
@ -195,7 +196,7 @@ if (empty($reshook)) {
} elseif ($action == 'enable' && $permissiontoadd) { } elseif ($action == 'enable' && $permissiontoadd) {
if ($accounting->fetch($id)) { if ($accounting->fetch($id)) {
$mode = GETPOST('mode', 'int'); $mode = GETPOST('mode', 'int');
$result = $accounting->account_activate($id, $mode); $result = $accounting->accountActivate($id, $mode);
} }
$action = 'update'; $action = 'update';
if ($result < 0) { if ($result < 0) {
@ -362,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")." : ";
@ -392,7 +393,7 @@ if ($resql) {
} }
print "</select>"; print "</select>";
print ajax_combobox("chartofaccounts"); print ajax_combobox("chartofaccounts");
print '<input type="'.(empty($conf->use_javascript_ajax) ? 'submit' : 'button').'" class="button" name="change_chart" id="change_chart" value="'.dol_escape_htmltag($langs->trans("ChangeAndLoad")).'">'; print '<input type="'.(empty($conf->use_javascript_ajax) ? 'submit' : 'button').'" class="button button-edit" name="change_chart" id="change_chart" value="'.dol_escape_htmltag($langs->trans("ChangeAndLoad")).'">';
print '<br>'; print '<br>';
print '<br>'; print '<br>';
@ -403,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";
@ -438,44 +444,33 @@ if ($resql) {
print $searchpicto; print $searchpicto;
print '</td>'; print '</td>';
print '</tr>'; print '</tr>';
$totalarray = array();
print '<tr class="liste_titre">'; print '<tr class="liste_titre">';
if (!empty($arrayfields['aa.account_number']['checked'])) { if (!empty($arrayfields['aa.account_number']['checked'])) {
print_liste_field_titre($arrayfields['aa.account_number']['label'], $_SERVER["PHP_SELF"], "aa.account_number", "", $param, '', $sortfield, $sortorder); print_liste_field_titre($arrayfields['aa.account_number']['label'], $_SERVER["PHP_SELF"], "aa.account_number", "", $param, '', $sortfield, $sortorder);
$totalarray['nbfield']++;
} }
if (!empty($arrayfields['aa.label']['checked'])) { if (!empty($arrayfields['aa.label']['checked'])) {
print_liste_field_titre($arrayfields['aa.label']['label'], $_SERVER["PHP_SELF"], "aa.label", "", $param, '', $sortfield, $sortorder); print_liste_field_titre($arrayfields['aa.label']['label'], $_SERVER["PHP_SELF"], "aa.label", "", $param, '', $sortfield, $sortorder);
$totalarray['nbfield']++;
} }
if (!empty($arrayfields['aa.labelshort']['checked'])) { if (!empty($arrayfields['aa.labelshort']['checked'])) {
print_liste_field_titre($arrayfields['aa.labelshort']['label'], $_SERVER["PHP_SELF"], "aa.labelshort", "", $param, '', $sortfield, $sortorder); print_liste_field_titre($arrayfields['aa.labelshort']['label'], $_SERVER["PHP_SELF"], "aa.labelshort", "", $param, '', $sortfield, $sortorder);
$totalarray['nbfield']++;
} }
if (!empty($arrayfields['aa.account_parent']['checked'])) { if (!empty($arrayfields['aa.account_parent']['checked'])) {
print_liste_field_titre($arrayfields['aa.account_parent']['label'], $_SERVER["PHP_SELF"], "aa.account_parent", "", $param, '', $sortfield, $sortorder, 'left '); print_liste_field_titre($arrayfields['aa.account_parent']['label'], $_SERVER["PHP_SELF"], "aa.account_parent", "", $param, '', $sortfield, $sortorder, 'left ');
$totalarray['nbfield']++;
} }
if (!empty($arrayfields['aa.pcg_type']['checked'])) { if (!empty($arrayfields['aa.pcg_type']['checked'])) {
print_liste_field_titre($arrayfields['aa.pcg_type']['label'], $_SERVER["PHP_SELF"], 'aa.pcg_type,aa.account_number', '', $param, '', $sortfield, $sortorder, '', $arrayfields['aa.pcg_type']['help'], 1); print_liste_field_titre($arrayfields['aa.pcg_type']['label'], $_SERVER["PHP_SELF"], 'aa.pcg_type,aa.account_number', '', $param, '', $sortfield, $sortorder, '', $arrayfields['aa.pcg_type']['help'], 1);
$totalarray['nbfield']++;
} }
if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { if ($conf->global->MAIN_FEATURES_LEVEL >= 2) {
if (!empty($arrayfields['aa.reconcilable']['checked'])) { if (!empty($arrayfields['aa.reconcilable']['checked'])) {
print_liste_field_titre($arrayfields['aa.reconcilable']['label'], $_SERVER["PHP_SELF"], 'aa.reconcilable', '', $param, '', $sortfield, $sortorder); print_liste_field_titre($arrayfields['aa.reconcilable']['label'], $_SERVER["PHP_SELF"], 'aa.reconcilable', '', $param, '', $sortfield, $sortorder);
$totalarray['nbfield']++;
} }
} }
if (!empty($arrayfields['aa.active']['checked'])) { if (!empty($arrayfields['aa.active']['checked'])) {
print_liste_field_titre($arrayfields['aa.active']['label'], $_SERVER["PHP_SELF"], 'aa.active', '', $param, '', $sortfield, $sortorder); print_liste_field_titre($arrayfields['aa.active']['label'], $_SERVER["PHP_SELF"], 'aa.active', '', $param, '', $sortfield, $sortorder);
$totalarray['nbfield']++;
} }
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);
$i = 0; $i = 0;
while ($i < min($num, $limit)) { while ($i < min($num, $limit)) {
$obj = $db->fetch_object($resql); $obj = $db->fetch_object($resql);
@ -620,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

@ -78,7 +78,7 @@ $search_country_id = GETPOST('search_country_id', 'int');
if ($user->socid > 0) { if ($user->socid > 0) {
accessforbidden(); accessforbidden();
} }
if (!$user->rights->accounting->chartofaccount) { if (empty($user->rights->accounting->chartofaccount)) {
accessforbidden(); accessforbidden();
} }
@ -495,7 +495,7 @@ if ($id) {
if ($valuetoshow != '') { if ($valuetoshow != '') {
print '<td class="'.$class.'">'; print '<td class="'.$class.'">';
if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) {
print '<a href="'.$tabhelp[$id][$value].'" target="_blank">'.$valuetoshow.' '.img_help(1, $valuetoshow).'</a>'; print '<a href="'.$tabhelp[$id][$value].'">'.$valuetoshow.' '.img_help(1, $valuetoshow).'</a>';
} elseif (!empty($tabhelp[$id][$value])) { } elseif (!empty($tabhelp[$id][$value])) {
print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]); print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]);
} else { } else {
@ -535,7 +535,7 @@ if ($id) {
} }
print '<td colspan="3" class="right">'; print '<td colspan="3" class="right">';
print '<input type="submit" class="button" name="actionadd" value="'.$langs->trans("Add").'">'; print '<input type="submit" class="button button-add" name="actionadd" value="'.$langs->trans("Add").'">';
print '</td>'; print '</td>';
print "</tr>"; print "</tr>";
@ -553,16 +553,16 @@ if ($id) {
$num = $db->num_rows($resql); $num = $db->num_rows($resql);
$i = 0; $i = 0;
$param = '&id='.$id; $param = '&id='.urlencode($id);
if ($search_country_id > 0) { if ($search_country_id > 0) {
$param .= '&search_country_id='.$search_country_id; $param .= '&search_country_id='.urlencode($search_country_id);
} }
$paramwithsearch = $param; $paramwithsearch = $param;
if ($sortorder) { if ($sortorder) {
$paramwithsearch .= '&sortorder='.$sortorder; $paramwithsearch .= '&sortorder='.urlencode($sortorder);
} }
if ($sortfield) { if ($sortfield) {
$paramwithsearch .= '&sortfield='.$sortfield; $paramwithsearch .= '&sortfield='.urlencode($sortfield);
} }
// There is several pages // There is several pages
@ -631,7 +631,7 @@ if ($id) {
fieldListAccountModel($fieldlist, $obj, $tabname[$id], 'edit'); fieldListAccountModel($fieldlist, $obj, $tabname[$id], 'edit');
} }
print '<td colspan="3" class="right"><a name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'">&nbsp;</a><input type="submit" class="button" name="actionmodify" value="'.$langs->trans("Modify").'">'; print '<td colspan="3" class="right"><a name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'">&nbsp;</a><input type="submit" class="button button-edit" name="actionmodify" value="'.$langs->trans("Modify").'">';
print '&nbsp;<input type="submit" class="button button-cancel" name="actioncancel" value="'.$langs->trans("Cancel").'"></td>'; print '&nbsp;<input type="submit" class="button button-cancel" name="actioncancel" value="'.$langs->trans("Cancel").'"></td>';
} else { } else {
$tmpaction = 'view'; $tmpaction = 'view';

View File

@ -48,7 +48,7 @@ $label = GETPOST('label', 'alpha');
if ($user->socid > 0) { if ($user->socid > 0) {
accessforbidden(); accessforbidden();
} }
if (!$user->rights->accounting->chartofaccount) { if (empty($user->rights->accounting->chartofaccount)) {
accessforbidden(); accessforbidden();
} }
@ -61,7 +61,7 @@ $object = new AccountingAccount($db);
*/ */
if (GETPOST('cancel', 'alpha')) { if (GETPOST('cancel', 'alpha')) {
$urltogo = $backtopage ? $backtopage : dol_buildpath('/accountancy/admin/account.php', 1); $urltogo = $backtopage ? $backtopage : DOL_URL_ROOT.'/accountancy/admin/account.php';
header("Location: ".$urltogo); header("Location: ".$urltogo);
exit; exit;
} }
@ -75,7 +75,7 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors'); setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors');
$action = 'create'; $action = 'create';
} else { } else {
$sql = 'SELECT pcg_version FROM ' . MAIN_DB_PREFIX . 'accounting_system WHERE rowid='.((int) $conf->global->CHARTOFACCOUNTS); $sql = "SELECT pcg_version FROM " . MAIN_DB_PREFIX . "accounting_system WHERE rowid = ".((int) $conf->global->CHARTOFACCOUNTS);
dol_syslog('accountancy/admin/card.php:: $sql=' . $sql); dol_syslog('accountancy/admin/card.php:: $sql=' . $sql);
$result = $db->query($sql); $result = $db->query($sql);
@ -121,7 +121,7 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) {
} }
if (!$error) { if (!$error) {
setEventMessages("RecordCreatedSuccessfully", null, 'mesgs'); setEventMessages("RecordCreatedSuccessfully", null, 'mesgs');
$urltogo = $backtopage ? $backtopage : dol_buildpath('/accountancy/admin/account.php', 1); $urltogo = $backtopage ? $backtopage : DOL_URL_ROOT.'/accountancy/admin/account.php';
header("Location: " . $urltogo); header("Location: " . $urltogo);
exit; exit;
} }
@ -138,7 +138,7 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) {
} else { } else {
$result = $object->fetch($id); $result = $object->fetch($id);
$sql = 'SELECT pcg_version FROM '.MAIN_DB_PREFIX.'accounting_system WHERE rowid='.((int) $conf->global->CHARTOFACCOUNTS); $sql = "SELECT pcg_version FROM ".MAIN_DB_PREFIX."accounting_system WHERE rowid=".((int) $conf->global->CHARTOFACCOUNTS);
dol_syslog('accountancy/admin/card.php:: $sql=' . $sql); dol_syslog('accountancy/admin/card.php:: $sql=' . $sql);
$result2 = $db->query($sql); $result2 = $db->query($sql);
@ -257,7 +257,20 @@ if ($action == 'create') {
print $form->textwithpicto($langs->trans("Pcgtype"), $langs->transnoentitiesnoconv("PcgtypeDesc")); print $form->textwithpicto($langs->trans("Pcgtype"), $langs->transnoentitiesnoconv("PcgtypeDesc"));
print '</td>'; print '</td>';
print '<td>'; print '<td>';
print '<input type="text" name="pcg_type" value="'.dol_escape_htmltag(GETPOSTISSET('pcg_type') ? GETPOST('pcg_type', 'alpha') : $object->pcg_type).'">'; print '<input type="text" name="pcg_type" list="pcg_type_datalist" value="'.dol_escape_htmltag(GETPOSTISSET('pcg_type') ? GETPOST('pcg_type', 'alpha') : $object->pcg_type).'">';
// autosuggest from existing account types if found
print '<datalist id="pcg_type_datalist">';
$sql = "SELECT DISTINCT pcg_type FROM " . MAIN_DB_PREFIX . "accounting_account";
$sql .= " WHERE fk_pcg_version = '" . $db->escape($accountsystem->ref) . "'";
$sql .= ' AND entity in ('.getEntity('accounting_account', 0).')'; // Always limit to current entity. No sharing in accountancy.
$sql .= ' LIMIT 50000'; // just as a sanity check
$resql = $db->query($sql);
if ($resql) {
while ($obj = $db->fetch_object($resql)) {
print '<option value="' . dol_escape_htmltag($obj->pcg_type) . '">';
}
}
print '</datalist>';
print '</td></tr>'; print '</td></tr>';
// Category // Category
@ -320,7 +333,20 @@ if ($action == 'create') {
print $form->textwithpicto($langs->trans("Pcgtype"), $langs->transnoentitiesnoconv("PcgtypeDesc")); print $form->textwithpicto($langs->trans("Pcgtype"), $langs->transnoentitiesnoconv("PcgtypeDesc"));
print '</td>'; print '</td>';
print '<td>'; print '<td>';
print '<input type="text" name="pcg_type" value="'.dol_escape_htmltag(GETPOSTISSET('pcg_type') ? GETPOST('pcg_type', 'alpha') : $object->pcg_type).'">'; print '<input type="text" name="pcg_type" list="pcg_type_datalist" value="'.dol_escape_htmltag(GETPOSTISSET('pcg_type') ? GETPOST('pcg_type', 'alpha') : $object->pcg_type).'">';
// autosuggest from existing account types if found
print '<datalist id="pcg_type_datalist">';
$sql = 'SELECT DISTINCT pcg_type FROM ' . MAIN_DB_PREFIX . 'accounting_account';
$sql .= " WHERE fk_pcg_version = '" . $db->escape($accountsystem->ref) . "'";
$sql .= ' AND entity in ('.getEntity('accounting_account', 0).')'; // Always limit to current entity. No sharing in accountancy.
$sql .= ' LIMIT 50000'; // just as a sanity check
$resql = $db->query($sql);
if ($resql) {
while ($obj = $db->fetch_object($resql)) {
print '<option value="' . dol_escape_htmltag($obj->pcg_type) . '">';
}
}
print '</datalist>';
print '</td></tr>'; print '</td></tr>';
// Category // Category
@ -335,11 +361,7 @@ if ($action == 'create') {
print dol_get_fiche_end(); print dol_get_fiche_end();
print '<div class="center">'; print $form->buttonsSaveCancel();
print '<input type="submit" class="button button-save" value="'.$langs->trans("Save").'">';
print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
print '<input type="submit" name="cancel" class="button button-cancel" value="'.$langs->trans("Cancel").'">';
print '</div>';
print '</form>'; print '</form>';
} else { } else {
@ -395,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

@ -110,7 +110,7 @@ print '<table class="border centpercent">';
print '<tr><td class="titlefield">'.$langs->trans("AccountingCategory").'</td>'; print '<tr><td class="titlefield">'.$langs->trans("AccountingCategory").'</td>';
print '<td>'; print '<td>';
$formaccounting->select_accounting_category($cat_id, 'account_category', 1, 0, 0, 1); $formaccounting->select_accounting_category($cat_id, 'account_category', 1, 0, 0, 1);
print '<input class="button" type="submit" value="'.$langs->trans("Select").'">'; print '<input type="submit" class="button" value="'.$langs->trans("Select").'">';
print '</td></tr>'; print '</td></tr>';
// Select the accounts // Select the accounts
@ -137,7 +137,7 @@ if (!empty($cat_id)) {
print '</select><br>'; print '</select><br>';
print ajax_combobox('cpt_bk'); print ajax_combobox('cpt_bk');
*/ */
print '<input class="button" type="submit" id="" class="action-delete" value="'.$langs->trans("Add").'"> '; print '<input type="submit" class="button button-add" id="" class="action-delete" value="'.$langs->trans("Add").'"> ';
} }
print '</td></tr>'; print '</td></tr>';
} }

View File

@ -520,7 +520,7 @@ if ($tabname[$id]) {
if ($valuetoshow != '') { if ($valuetoshow != '') {
print '<td class="'.$class.'">'; print '<td class="'.$class.'">';
if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) {
print '<a href="'.$tabhelp[$id][$value].'" target="_blank">'.$valuetoshow.' '.img_help(1, $valuetoshow).'</a>'; print '<a href="'.$tabhelp[$id][$value].'">'.$valuetoshow.' '.img_help(1, $valuetoshow).'</a>';
} elseif (!empty($tabhelp[$id][$value])) { } elseif (!empty($tabhelp[$id][$value])) {
print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]); print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]);
} else { } else {
@ -561,7 +561,7 @@ if ($tabname[$id]) {
} }
print '<td colspan="4" class="right">'; print '<td colspan="4" class="right">';
print '<input type="submit" class="button" name="actionadd" value="'.$langs->trans("Add").'">'; print '<input type="submit" class="button button-add" name="actionadd" value="'.$langs->trans("Add").'">';
print '</td>'; print '</td>';
print "</tr>"; print "</tr>";
@ -583,7 +583,7 @@ if ($resql) {
$param = '&id='.$id; $param = '&id='.$id;
if ($search_country_id > 0) { if ($search_country_id > 0) {
$param .= '&search_country_id='.$search_country_id; $param .= '&search_country_id='.urlencode($search_country_id);
} }
$paramwithsearch = $param; $paramwithsearch = $param;
if ($sortorder) { if ($sortorder) {
@ -737,14 +737,14 @@ if ($resql) {
print '<td class="center">'; print '<td class="center">';
print '<input type="hidden" name="page" value="'.$page.'">'; print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="rowid" value="'.$rowid.'">'; print '<input type="hidden" name="rowid" value="'.$rowid.'">';
print '<input type="submit" class="button" name="actionmodify" value="'.$langs->trans("Modify").'">'; print '<input type="submit" class="button button-edit" name="actionmodify" value="'.$langs->trans("Modify").'">';
print '<div name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'"></div>'; print '<div name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'"></div>';
print '<input type="submit" class="button button-cancel" name="actioncancel" value="'.$langs->trans("Cancel").'">'; print '<input type="submit" class="button button-cancel" name="actioncancel" value="'.$langs->trans("Cancel").'">';
print '</td>'; print '</td>';
print '<td></td>'; print '<td></td>';
} else { } else {
$tmpaction = 'view'; $tmpaction = 'view';
$parameters = array('var'=>$var, 'fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); $parameters = array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]);
$reshook = $hookmanager->executeHooks('viewDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks $reshook = $hookmanager->executeHooks('viewDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
$error = $hookmanager->error; $errors = $hookmanager->errors; $error = $hookmanager->error; $errors = $hookmanager->errors;
@ -814,7 +814,7 @@ if ($resql) {
// Modify link // Modify link
if ($canbemodified) { if ($canbemodified) {
print '<td class="center"><a class="reposition editfielda" href="'.$url.'action=edit">'.img_edit().'</a></td>'; print '<td class="center"><a class="reposition editfielda" href="'.$url.'action=edit&token='.newToken().'">'.img_edit().'</a></td>';
} else { } else {
print '<td>&nbsp;</td>'; print '<td>&nbsp;</td>';
} }
@ -823,7 +823,7 @@ if ($resql) {
if ($iserasable) { if ($iserasable) {
print '<td class="center">'; print '<td class="center">';
if ($user->admin) { if ($user->admin) {
print '<a href="'.$url.'action=delete">'.img_delete().'</a>'; print '<a href="'.$url.'action=delete&token='.newToken().'">'.img_delete().'</a>';
} }
//else print '<a href="#">'.img_delete().'</a>'; // Some dictionary can be edited by other profile than admin //else print '<a href="#">'.img_delete().'</a>'; // Some dictionary can be edited by other profile than admin
print '</td>'; print '</td>';

View File

@ -109,7 +109,7 @@ foreach ($list_account_main as $key) {
print '</td>'; print '</td>';
// Value // Value
print '<td>'; // Do not force class=right, or it align also the content of the select box print '<td>'; // Do not force class=right, or it align also the content of the select box
print $formaccounting->select_account($conf->global->$key, $key, 1, '', 1, 1); print $formaccounting->select_account(getDolGlobalString($key), $key, 1, '', 1, 1);
print '</td>'; print '</td>';
print '</tr>'; print '</tr>';
} }
@ -124,7 +124,7 @@ print '</td></tr>';
print "</table>\n"; print "</table>\n";
print '<div class="center"><input type="submit" class="button" value="'.$langs->trans('Modify').'" name="button"></div>'; print '<div class="center"><input type="submit" class="button button-edit" name="button" value="'.$langs->trans('Modify').'"></div>';
print '</form>'; print '</form>';

View File

@ -52,6 +52,7 @@ $list_account_main = array(
); );
$list_account = array(); $list_account = array();
$list_account[] = '---Product---'; $list_account[] = '---Product---';
$list_account[] = 'ACCOUNTING_PRODUCT_SOLD_ACCOUNT'; $list_account[] = 'ACCOUNTING_PRODUCT_SOLD_ACCOUNT';
if ($mysoc->isInEEC()) { if ($mysoc->isInEEC()) {
@ -63,6 +64,7 @@ if ($mysoc->isInEEC()) {
$list_account[] = 'ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT'; $list_account[] = 'ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT';
} }
$list_account[] = 'ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT'; $list_account[] = 'ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT';
$list_account[] = '---Service---'; $list_account[] = '---Service---';
$list_account[] = 'ACCOUNTING_SERVICE_SOLD_ACCOUNT'; $list_account[] = 'ACCOUNTING_SERVICE_SOLD_ACCOUNT';
if ($mysoc->isInEEC()) { if ($mysoc->isInEEC()) {
@ -74,11 +76,11 @@ if ($mysoc->isInEEC()) {
$list_account[] = 'ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT'; $list_account[] = 'ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT';
} }
$list_account[] = 'ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT'; $list_account[] = 'ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT';
$list_account[] = '---Others---'; $list_account[] = '---Others---';
$list_account[] = 'ACCOUNTING_VAT_BUY_ACCOUNT'; $list_account[] = 'ACCOUNTING_VAT_BUY_ACCOUNT';
$list_account[] = 'ACCOUNTING_VAT_SOLD_ACCOUNT'; $list_account[] = 'ACCOUNTING_VAT_SOLD_ACCOUNT';
$list_account[] = 'ACCOUNTING_VAT_PAY_ACCOUNT'; $list_account[] = 'ACCOUNTING_VAT_PAY_ACCOUNT';
$list_account[] = 'ACCOUNTING_ACCOUNT_SUSPENSE';
if ($conf->banque->enabled) { if ($conf->banque->enabled) {
$list_account[] = 'ACCOUNTING_ACCOUNT_TRANSFER_CASH'; $list_account[] = 'ACCOUNTING_ACCOUNT_TRANSFER_CASH';
} }
@ -96,6 +98,7 @@ if ($conf->loan->enabled) {
if ($conf->societe->enabled) { if ($conf->societe->enabled) {
$list_account[] = 'ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT'; $list_account[] = 'ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT';
} }
$list_account[] = 'ACCOUNTING_ACCOUNT_SUSPENSE';
/* /*
* Actions * Actions
@ -154,6 +157,7 @@ print '<input type="hidden" name="action" value="update">';
// Define main accounts for thirdparty // Define main accounts for thirdparty
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">'; print '<table class="noborder centpercent">';
print '<tr class="liste_titre"><td>'.$langs->trans("ThirdParties").' | '.$langs->trans("Users").'</td><td></td></tr>'; print '<tr class="liste_titre"><td>'.$langs->trans("ThirdParties").' | '.$langs->trans("Users").'</td><td></td></tr>';
@ -164,17 +168,29 @@ foreach ($list_account_main as $key) {
$keydesc = $key.'_Desc'; $keydesc = $key.'_Desc';
$htmltext = $langs->trans($keydesc); $htmltext = $langs->trans($keydesc);
print '<td class="fieldrequired" width="50%">'; print '<td class="fieldrequired">';
if ($key == 'ACCOUNTING_ACCOUNT_CUSTOMER') {
print img_picto('', 'company', 'class="pictofixedwidth"');
} elseif ($key == 'ACCOUNTING_ACCOUNT_SUPPLIER') {
print img_picto('', 'company', 'class="pictofixedwidth"');
} else {
print img_picto('', 'user', 'class="pictofixedwidth"');
}
print $form->textwithpicto($label, $htmltext); print $form->textwithpicto($label, $htmltext);
print '</td>'; print '</td>';
// Value // Value
print '<td>'; // Do not force class=right, or it align also the content of the select box print '<td class="right">'; // Do not force class=right, or it align also the content of the select box
print $formaccounting->select_account($conf->global->$key, $key, 1, '', 1, 1, 'minwidth100 maxwidth300 maxwidthonsmartphone', 'accountsmain'); print $formaccounting->select_account($conf->global->$key, $key, 1, '', 1, 1, 'minwidth100 maxwidth300 maxwidthonsmartphone', 'accountsmain');
print '</td>'; print '</td>';
print '</tr>'; print '</tr>';
} }
print "</table>\n";
print "</div>\n";
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
foreach ($list_account as $key) { foreach ($list_account as $key) {
$reg = array(); $reg = array();
if (preg_match('/---(.*)---/', $key, $reg)) { if (preg_match('/---(.*)---/', $key, $reg)) {
@ -183,10 +199,33 @@ foreach ($list_account as $key) {
print '<tr class="oddeven value">'; print '<tr class="oddeven value">';
// Param // Param
$label = $langs->trans($key); $label = $langs->trans($key);
print '<td width="50%">'.$label.'</td>'; print '<td>';
if (preg_match('/^ACCOUNTING_PRODUCT/', $key)) {
print img_picto('', 'product', 'class="pictofixedwidth"');
} elseif (preg_match('/^ACCOUNTING_SERVICE/', $key)) {
print img_picto('', 'service', 'class="pictofixedwidth"');
} elseif (preg_match('/^ACCOUNTING_VAT_PAY_ACCOUNT/', $key)) {
print img_picto('', 'payment_vat', 'class="pictofixedwidth"');
} elseif (preg_match('/^ACCOUNTING_VAT/', $key)) {
print img_picto('', 'vat', 'class="pictofixedwidth"');
} elseif (preg_match('/^ACCOUNTING_ACCOUNT_CUSTOMER/', $key)) {
print img_picto('', 'bill', 'class="pictofixedwidth"');
} elseif (preg_match('/^LOAN_ACCOUNTING_ACCOUNT/', $key)) {
print img_picto('', 'loan', 'class="pictofixedwidth"');
} elseif (preg_match('/^DONATION_ACCOUNTING/', $key)) {
print img_picto('', 'donation', 'class="pictofixedwidth"');
} elseif (preg_match('/^ADHERENT_SUBSCRIPTION/', $key)) {
print img_picto('', 'member', 'class="pictofixedwidth"');
} elseif (preg_match('/^ACCOUNTING_ACCOUNT_TRANSFER/', $key)) {
print img_picto('', 'bank_account', 'class="pictofixedwidth"');
} elseif (preg_match('/^ACCOUNTING_ACCOUNT_SUSPENSE/', $key)) {
print img_picto('', 'question', 'class="pictofixedwidth"');
}
print $label;
print '</td>';
// Value // Value
print '<td>'; // Do not force class=right, or it align also the content of the select box print '<td class="right">'; // Do not force class=right, or it align also the content of the select box
print $formaccounting->select_account($conf->global->$key, $key, 1, '', 1, 1, 'minwidth100 maxwidth300 maxwidthonsmartphone', 'accounts'); print $formaccounting->select_account(getDolGlobalString($key), $key, 1, '', 1, 1, 'minwidth100 maxwidth300 maxwidthonsmartphone', 'accounts');
print '</td>'; print '</td>';
print '</tr>'; print '</tr>';
} }
@ -194,9 +233,9 @@ foreach ($list_account as $key) {
print "</table>\n"; print "</table>\n";
print "</div>\n";
print '<div class="center"><input type="submit" class="button button-edit" name="button" value="'.$langs->trans('Modify').'"></div>';
print '<div class="center"><input type="submit" class="button" value="'.$langs->trans('Modify').'" name="button"></div>';
print '</form>'; print '</form>';

View File

@ -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

@ -52,7 +52,7 @@ $langs->loadLangs(array("admin", "compta"));
if ($user->socid > 0) { if ($user->socid > 0) {
accessforbidden(); accessforbidden();
} }
if (!$user->rights->accounting->fiscalyear->write) { // If we can read accounting records, we should be able to see fiscal year. if (empty($user->rights->accounting->fiscalyear->write)) { // If we can read accounting records, we should be able to see fiscal year.
accessforbidden(); accessforbidden();
} }
@ -127,7 +127,6 @@ if ($result) {
$title = $langs->trans('AccountingPeriods'); $title = $langs->trans('AccountingPeriods');
print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $params, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy', 0, $addbutton, '', $limit, 1); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $params, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy', 0, $addbutton, '', $limit, 1);
// Load attribute_label
print '<div class="div-table-responsive">'; print '<div class="div-table-responsive">';
print '<table class="tagtable liste centpercent">'; print '<table class="tagtable liste centpercent">';
print '<tr class="liste_titre">'; print '<tr class="liste_titre">';

View File

@ -242,11 +242,7 @@ if ($action == 'create') {
print '</table>'; print '</table>';
print '<br><div class="center">'; print $form->buttonsSaveCancel();
print '<input type="submit" class="button button-save" value="'.$langs->trans("Save").'">';
print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
print '<input type="submit" name="cancel" class="button button-cancel" value="'.$langs->trans("Cancel").'">';
print '</div>';
print '</form>'; print '</form>';

View File

@ -33,7 +33,7 @@ $langs->loadLangs(array("admin", "compta"));
if ($user->socid > 0) { if ($user->socid > 0) {
accessforbidden(); accessforbidden();
} }
if (!$user->rights->accounting->fiscalyear->write) { if (empty($user->rights->accounting->fiscalyear->write)) {
accessforbidden(); accessforbidden();
} }

View File

@ -462,7 +462,7 @@ print '</tr>';
print '</table>'; print '</table>';
print '<div class="center"><input type="submit" class="button" value="'.$langs->trans('Modify').'" name="button"></div>'; print '<div class="center"><input type="submit" class="button button-edit" name="button" value="'.$langs->trans('Modify').'"></div>';
print '</form>'; print '</form>';

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;
@ -453,7 +453,7 @@ if ($id) {
if ($valuetoshow != '') { if ($valuetoshow != '') {
print '<td class="'.$class.'">'; print '<td class="'.$class.'">';
if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) {
print '<a href="'.$tabhelp[$id][$value].'" target="_blank">'.$valuetoshow.' '.img_help(1, $valuetoshow).'</a>'; print '<a href="'.$tabhelp[$id][$value].'">'.$valuetoshow.' '.img_help(1, $valuetoshow).'</a>';
} elseif (!empty($tabhelp[$id][$value])) { } elseif (!empty($tabhelp[$id][$value])) {
print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]); print $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]);
} else { } else {
@ -494,7 +494,7 @@ if ($id) {
} }
print '<td colspan="4" class="right">'; print '<td colspan="4" class="right">';
print '<input type="submit" class="button" name="actionadd" value="'.$langs->trans("Add").'">'; print '<input type="submit" class="button button-add" name="actionadd" value="'.$langs->trans("Add").'">';
print '</td>'; print '</td>';
print "</tr>"; print "</tr>";
@ -512,7 +512,7 @@ if ($id) {
$param = '&id='.$id; $param = '&id='.$id;
if ($search_country_id > 0) { if ($search_country_id > 0) {
$param .= '&search_country_id='.$search_country_id; $param .= '&search_country_id='.urlencode($search_country_id);
} }
$paramwithsearch = $param; $paramwithsearch = $param;
if ($sortorder) { if ($sortorder) {
@ -606,13 +606,13 @@ if ($id) {
print '<td class="center" colspan="4">'; print '<td class="center" colspan="4">';
print '<input type="hidden" name="page" value="'.$page.'">'; print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="rowid" value="'.$rowid.'">'; print '<input type="hidden" name="rowid" value="'.$rowid.'">';
print '<input type="submit" class="button" name="actionmodify" value="'.$langs->trans("Modify").'">'; print '<input type="submit" class="button button-edit" name="actionmodify" value="'.$langs->trans("Modify").'">';
print '<input type="submit" class="button button-cancel" name="actioncancel" value="'.$langs->trans("Cancel").'">'; print '<input type="submit" class="button button-cancel" name="actioncancel" value="'.$langs->trans("Cancel").'">';
print '<div name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'"></div>'; print '<div name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'"></div>';
print '</td>'; print '</td>';
} else { } else {
$tmpaction = 'view'; $tmpaction = 'view';
$parameters = array('var'=>$var, 'fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); $parameters = array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]);
$reshook = $hookmanager->executeHooks('viewDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks $reshook = $hookmanager->executeHooks('viewDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks
$error = $hookmanager->error; $errors = $hookmanager->errors; $error = $hookmanager->error; $errors = $hookmanager->errors;

View File

@ -4,6 +4,7 @@
* Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro> * Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015 Ari Elbaz (elarifr) <github@accedinfo.com> * Copyright (C) 2015 Ari Elbaz (elarifr) <github@accedinfo.com>
* Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.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
@ -41,15 +42,18 @@ $langs->loadLangs(array("companies", "compta", "accountancy", "products"));
if (empty($conf->accounting->enabled)) { if (empty($conf->accounting->enabled)) {
accessforbidden(); accessforbidden();
} }
if (!$user->rights->accounting->bind->write) { if (empty($user->rights->accounting->bind->write)) {
accessforbidden(); accessforbidden();
} }
// search & action GETPOST // search & action GETPOST
$action = GETPOST('action', 'aZ09'); $action = GETPOST('action', 'aZ09');
$massaction = GETPOST('massaction', 'alpha');
$codeventil_buy = GETPOST('codeventil_buy', 'array'); $codeventil_buy = GETPOST('codeventil_buy', 'array');
$codeventil_sell = GETPOST('codeventil_sell', 'array'); $codeventil_sell = GETPOST('codeventil_sell', 'array');
$chk_prod = GETPOST('chk_prod', 'array'); $chk_prod = GETPOST('chk_prod', 'array');
$default_account = GETPOST('default_account', 'int');
$confirm = GETPOST('confirm', 'alpha');
$account_number_buy = GETPOST('account_number_buy'); $account_number_buy = GETPOST('account_number_buy');
$account_number_sell = GETPOST('account_number_sell'); $account_number_sell = GETPOST('account_number_sell');
$changeaccount = GETPOST('changeaccount', 'array'); $changeaccount = GETPOST('changeaccount', 'array');
@ -68,16 +72,16 @@ $search_onsell = GETPOST('search_onsell', 'alpha');
$search_onpurchase = GETPOST('search_onpurchase', 'alpha'); $search_onpurchase = GETPOST('search_onpurchase', 'alpha');
$accounting_product_mode = GETPOST('accounting_product_mode', 'alpha'); $accounting_product_mode = GETPOST('accounting_product_mode', 'alpha');
$btn_changeaccount = GETPOST('changeaccount', 'alpha');
$btn_changetype = GETPOST('changetype', 'alpha'); $btn_changetype = GETPOST('changetype', 'alpha');
$optioncss = GETPOST('optioncss', 'alpha');
if (empty($accounting_product_mode)) { if (empty($accounting_product_mode)) {
$accounting_product_mode = 'ACCOUNTANCY_SELL'; $accounting_product_mode = 'ACCOUNTANCY_SELL';
} }
$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;
@ -164,7 +168,7 @@ if ($action == 'update') {
} }
} }
if (!empty($btn_changeaccount)) { if (!empty($chk_prod) && $massaction === 'changeaccount') {
//$msg = '<div><span class="accountingprocessing">' . $langs->trans("Processing") . '...</span></div>'; //$msg = '<div><span class="accountingprocessing">' . $langs->trans("Processing") . '...</span></div>';
if (!empty($chk_prod) && in_array($accounting_product_mode, $accounting_product_modes)) { if (!empty($chk_prod) && in_array($accounting_product_mode, $accounting_product_modes)) {
$accounting = new AccountingAccount($db); $accounting = new AccountingAccount($db);
@ -214,8 +218,10 @@ if ($action == 'update') {
$sql .= " WHERE rowid = ".((int) $productid); $sql .= " WHERE rowid = ".((int) $productid);
} }
dol_syslog("/accountancy/admin/productaccount.php", LOG_DEBUG);
$db->begin(); $db->begin();
dol_syslog("/accountancy/admin/productaccount.php sql=".$sql, LOG_DEBUG);
if ($db->query($sql)) { if ($db->query($sql)) {
$ok++; $ok++;
$db->commit(); $db->commit();
@ -251,35 +257,35 @@ $form = new FormAccounting($db);
// so we need to get those the rowid of those default value first // so we need to get those the rowid of those default value first
$accounting = new AccountingAccount($db); $accounting = new AccountingAccount($db);
// TODO: we should need to check if result is already exists accountaccount rowid..... // TODO: we should need to check if result is already exists accountaccount rowid.....
$aarowid_servbuy = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT, 1); $aarowid_servbuy = $accounting->fetch('', getDolGlobalString('ACCOUNTING_SERVICE_BUY_ACCOUNT'), 1);
$aarowid_servbuy_intra = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT, 1); $aarowid_servbuy_intra = $accounting->fetch('', getDolGlobalString('ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT'), 1);
$aarowid_servbuy_export = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT, 1); $aarowid_servbuy_export = $accounting->fetch('', getDolGlobalString('ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT'), 1);
$aarowid_prodbuy = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT, 1); $aarowid_prodbuy = $accounting->fetch('', getDolGlobalString('ACCOUNTING_PRODUCT_BUY_ACCOUNT'), 1);
$aarowid_prodbuy_intra = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT, 1); $aarowid_prodbuy_intra = $accounting->fetch('', getDolGlobalString('ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT'), 1);
$aarowid_prodbuy_export = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT, 1); $aarowid_prodbuy_export = $accounting->fetch('', getDolGlobalString('ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT'), 1);
$aarowid_servsell = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT, 1); $aarowid_servsell = $accounting->fetch('', getDolGlobalString('ACCOUNTING_SERVICE_SOLD_ACCOUNT'), 1);
$aarowid_servsell_intra = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT, 1); $aarowid_servsell_intra = $accounting->fetch('', getDolGlobalString('ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT'), 1);
$aarowid_servsell_export = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT, 1); $aarowid_servsell_export = $accounting->fetch('', getDolGlobalString('ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT'), 1);
$aarowid_prodsell = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT, 1); $aarowid_prodsell = $accounting->fetch('', getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_ACCOUNT'), 1);
$aarowid_prodsell_intra = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT, 1); $aarowid_prodsell_intra = $accounting->fetch('', getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT'), 1);
$aarowid_prodsell_export = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT, 1); $aarowid_prodsell_export = $accounting->fetch('', getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT'), 1);
$aacompta_servbuy = (!empty($conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT : $langs->trans("CodeNotDef")); $aacompta_servbuy = getDolGlobalString('ACCOUNTING_SERVICE_BUY_ACCOUNT', $langs->trans("CodeNotDef"));
$aacompta_servbuy_intra = (!empty($conf->global->ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT : $langs->trans("CodeNotDef")); $aacompta_servbuy_intra = getDolGlobalString('ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT', $langs->trans("CodeNotDef"));
$aacompta_servbuy_export = (!empty($conf->global->ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT : $langs->trans("CodeNotDef")); $aacompta_servbuy_export = getDolGlobalString('ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT', $langs->trans("CodeNotDef"));
$aacompta_prodbuy = (!empty($conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT : $langs->trans("CodeNotDef")); $aacompta_prodbuy = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_ACCOUNT', $langs->trans("CodeNotDef"));
$aacompta_prodbuy_intra = (!empty($conf->global->ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT : $langs->trans("CodeNotDef")); $aacompta_prodbuy_intra = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT', $langs->trans("CodeNotDef"));
$aacompta_prodbuy_export = (!empty($conf->global->ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT : $langs->trans("CodeNotDef")); $aacompta_prodbuy_export = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT', $langs->trans("CodeNotDef"));
$aacompta_servsell = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : $langs->trans("CodeNotDef")); $aacompta_servsell = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_ACCOUNT', $langs->trans("CodeNotDef"));
$aacompta_servsell_intra = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT : $langs->trans("CodeNotDef")); $aacompta_servsell_intra = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT', $langs->trans("CodeNotDef"));
$aacompta_servsell_export = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT : $langs->trans("CodeNotDef")); $aacompta_servsell_export = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT', $langs->trans("CodeNotDef"));
$aacompta_prodsell = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : $langs->trans("CodeNotDef")); $aacompta_prodsell = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_ACCOUNT', $langs->trans("CodeNotDef"));
$aacompta_prodsell_intra = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT : $langs->trans("CodeNotDef")); $aacompta_prodsell_intra = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT', $langs->trans("CodeNotDef"));
$aacompta_prodsell_export = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT : $langs->trans("CodeNotDef")); $aacompta_prodsell_export = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT', $langs->trans("CodeNotDef"));
llxHeader('', $langs->trans("ProductsBinding")); llxHeader('', $langs->trans("ProductsBinding"));
$pcgverid = $conf->global->CHARTOFACCOUNTS; $pcgverid = getDolGlobalString('CHARTOFACCOUNTS');
$pcgvercode = dol_getIdFromCode($db, $pcgverid, 'accounting_system', 'rowid', 'pcg_version'); $pcgvercode = dol_getIdFromCode($db, $pcgverid, 'accounting_system', 'rowid', 'pcg_version');
if (empty($pcgvercode)) { if (empty($pcgvercode)) {
$pcgvercode = $pcgverid; $pcgvercode = $pcgverid;
@ -346,7 +352,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
$sql .= $db->plimit($limit + 1, $offset); $sql .= $db->plimit($limit + 1, $offset);
dol_syslog("/accountancy/admin/productaccount.php:: sql=".$sql, LOG_DEBUG); dol_syslog("/accountancy/admin/productaccount.php", LOG_DEBUG);
$result = $db->query($sql); $result = $db->query($sql);
if ($result) { if ($result) {
$num = $db->num_rows($result); $num = $db->num_rows($result);
@ -433,11 +439,27 @@ if ($result) {
$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
if ($massaction !== 'set_default_account') {
$arrayofmassactions = array(
'changeaccount'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Save")
,'set_default_account'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("ConfirmPreselectAccount")
);
$massactionbutton = $form->selectMassAction('', $arrayofmassactions, 1);
}
$buttonsave = '<input type="submit" class="button button-save" id="changeaccount" name="changeaccount" value="'.$langs->trans("Save").'">'; $buttonsave = '<input type="submit" class="button button-save" id="changeaccount" name="changeaccount" value="'.$langs->trans("Save").'">';
//print '<br><div class="center">'.$buttonsave.'</div>'; //print '<br><div class="center">'.$buttonsave.'</div>';
$texte = $langs->trans("ListOfProductsServices"); $texte = $langs->trans("ListOfProductsServices");
print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $buttonsave, $num, $nbtotalofrecords, '', 0, '', '', $limit, 0, 0, 1); print_barre_liste($texte, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, '', 0, '', '', $limit, 0, 0, 1);
if ($massaction == 'set_default_account') {
$formquestion[]=array('type' => 'other',
'name' => 'set_default_account',
'label' => $langs->trans("AccountancyCode"),
'value' => $form->select_account('', 'default_account', 1, array(), 0, 0, 'maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone'));
print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmPreselectAccount"), $langs->trans("ConfirmPreselectAccountQuestion", count($chk_prod)), "confirm_set_default_account", $formquestion, 1, 0, 200, 500, 1);
}
print '<div class="div-table-responsive">'; print '<div class="div-table-responsive">';
print '<table class="liste '.($moreforfilter ? "listwithfilterbefore" : "").'">'; print '<table class="liste '.($moreforfilter ? "listwithfilterbefore" : "").'">';
@ -642,7 +664,7 @@ if ($result) {
if (!empty($obj->aaid)) { if (!empty($obj->aaid)) {
$defaultvalue = ''; // Do not suggest default new value is code is already valid $defaultvalue = ''; // Do not suggest default new value is code is already valid
} }
print $form->select_account($defaultvalue, 'codeventil_'.$product_static->id, 1, array(), 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect'); print $form->select_account(($default_account > 0 && $confirm === 'yes' && in_array($product_static->id, $chk_prod)) ? $default_account : $defaultvalue, 'codeventil_'.$product_static->id, 1, array(), 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect');
print '</td>'; print '</td>';
} elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_INTRA') { } elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_INTRA') {
// Accounting account buy intra (In EEC) // Accounting account buy intra (In EEC)
@ -656,7 +678,7 @@ if ($result) {
if (!empty($obj->aaid)) { if (!empty($obj->aaid)) {
$defaultvalue = ''; // Do not suggest default new value is code is already valid $defaultvalue = ''; // Do not suggest default new value is code is already valid
} }
print $form->select_account($defaultvalue, 'codeventil_'.$product_static->id, 1, array(), 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect'); print $form->select_account(($default_account > 0 && $confirm === 'yes' && in_array($product_static->id, $chk_prod)) ? $default_account : $defaultvalue, 'codeventil_'.$product_static->id, 1, array(), 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect');
print '</td>'; print '</td>';
} elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_EXPORT') { } elseif ($accounting_product_mode == 'ACCOUNTANCY_BUY_EXPORT') {
// Accounting account buy export (Out of EEC) // Accounting account buy export (Out of EEC)
@ -670,7 +692,7 @@ if ($result) {
if (!empty($obj->aaid)) { if (!empty($obj->aaid)) {
$defaultvalue = ''; // Do not suggest default new value is code is already valid $defaultvalue = ''; // Do not suggest default new value is code is already valid
} }
print $form->select_account($defaultvalue, 'codeventil_'.$product_static->id, 1, array(), 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect'); print $form->select_account(($default_account > 0 && $confirm === 'yes' && in_array($product_static->id, $chk_prod)) ? $default_account : $defaultvalue, 'codeventil_'.$product_static->id, 1, array(), 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect');
print '</td>'; print '</td>';
} elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL') { } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL') {
// Accounting account sell // Accounting account sell
@ -684,7 +706,7 @@ if ($result) {
if (!empty($obj->aaid)) { if (!empty($obj->aaid)) {
$defaultvalue = ''; // Do not suggest default new value is code is already valid $defaultvalue = ''; // Do not suggest default new value is code is already valid
} }
print $form->select_account($defaultvalue, 'codeventil_'.$product_static->id, 1, array(), 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect'); print $form->select_account(($default_account > 0 && $confirm === 'yes' && in_array($product_static->id, $chk_prod)) ? $default_account : $defaultvalue, 'codeventil_'.$product_static->id, 1, array(), 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect');
print '</td>'; print '</td>';
} elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') { } elseif ($accounting_product_mode == 'ACCOUNTANCY_SELL_INTRA') {
// Accounting account sell intra (In EEC) // Accounting account sell intra (In EEC)
@ -698,7 +720,7 @@ if ($result) {
if (!empty($obj->aaid)) { if (!empty($obj->aaid)) {
$defaultvalue = ''; // Do not suggest default new value is code is already valid $defaultvalue = ''; // Do not suggest default new value is code is already valid
} }
print $form->select_account($defaultvalue, 'codeventil_'.$product_static->id, 1, array(), 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect'); print $form->select_account(($default_account > 0 && $confirm === 'yes' && in_array($product_static->id, $chk_prod)) ? $default_account : $defaultvalue, 'codeventil_'.$product_static->id, 1, array(), 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect');
print '</td>'; print '</td>';
} else { } else {
// Accounting account sell export (Out of EEC) // Accounting account sell export (Out of EEC)
@ -711,20 +733,27 @@ if ($result) {
if (!empty($obj->aaid)) { if (!empty($obj->aaid)) {
$defaultvalue = ''; // Do not suggest default new value is code is already valid $defaultvalue = ''; // Do not suggest default new value is code is already valid
} }
print $form->select_account($defaultvalue, 'codeventil_'.$product_static->id, 1, array(), 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect'); print $form->select_account(($default_account > 0 && $confirm === 'yes' && in_array($product_static->id, $chk_prod)) ? $default_account : $defaultvalue, 'codeventil_'.$product_static->id, 1, array(), 1, 0, 'maxwidth300 maxwidthonsmartphone productforselect');
print '</td>'; print '</td>';
} }
if (!empty($chk_prod)) {
$ischecked = 0;
if (in_array($product_static->id, $chk_prod)) {
$ischecked=true;
}
}
// Checkbox select // Checkbox select
print '<td class="center">'; print '<td class="center">';
print '<input type="checkbox" class="checkforselect productforselectcodeventil_'.$product_static->id.'" name="chk_prod[]" value="'.$obj->rowid.'"/></td>'; print '<input type="checkbox" class="checkforselect productforselectcodeventil_'.$product_static->id.'" name="chk_prod[]" '.($ischecked ? "checked" : "").' value="'.$obj->rowid.'"/></td>';
print "</tr>"; print "</tr>";
$i++; $i++;
} }
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

@ -36,6 +36,7 @@ $cancel = GETPOST('cancel', 'alpha');
$id = GETPOST('id', 'int'); $id = GETPOST('id', 'int');
$rowid = GETPOST('rowid', 'int'); $rowid = GETPOST('rowid', 'int');
$massaction = GETPOST('massaction', 'aZ09'); $massaction = GETPOST('massaction', 'aZ09');
$optioncss = GETPOST('optioncss', 'alpha');
$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'accountingsubaccountlist'; // To manage different context of search $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'accountingsubaccountlist'; // To manage different context of search
$search_subaccount = GETPOST('search_subaccount', 'alpha'); $search_subaccount = GETPOST('search_subaccount', 'alpha');
@ -46,7 +47,7 @@ $search_type = GETPOST('search_type', 'int');
if ($user->socid > 0) { if ($user->socid > 0) {
accessforbidden(); accessforbidden();
} }
if (!$user->rights->accounting->chartofaccount) { if (empty($user->rights->accounting->chartofaccount)) {
accessforbidden(); accessforbidden();
} }
@ -367,6 +368,7 @@ if ($resql) {
print "</tr>\n"; print "</tr>\n";
$totalarray = array(); $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);
@ -439,13 +441,13 @@ if ($resql) {
$e = ''; $e = '';
// Customer // Customer
if ($obj->type == 1) { if ($obj->type == 1) {
$e .= '<a class="editfielda" title="'.$langs->trans("Customer").'" href="'.DOL_URL_ROOT.'/societe/card.php?action=edit&socid='.$obj->rowid.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'">'.img_edit().'</a>'; $e .= '<a class="editfielda" title="'.$langs->trans("Customer").'" href="'.DOL_URL_ROOT.'/societe/card.php?action=edit&token='.newToken().'&socid='.$obj->rowid.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'">'.img_edit().'</a>';
} elseif ($obj->type == 2) { } elseif ($obj->type == 2) {
// Supplier // Supplier
$e .= '<a class="editfielda" title="'.$langs->trans("Supplier").'" href="'.DOL_URL_ROOT.'/societe/card.php?action=edit&socid='.$obj->rowid.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'">'.img_edit().'</a>'; $e .= '<a class="editfielda" title="'.$langs->trans("Supplier").'" href="'.DOL_URL_ROOT.'/societe/card.php?action=edit&token='.newToken().'&socid='.$obj->rowid.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'">'.img_edit().'</a>';
} elseif ($obj->type == 3) { } elseif ($obj->type == 3) {
// User // User
$e .= '<a class="editfielda" title="'.$langs->trans("Employee").'" href="'.DOL_URL_ROOT.'/user/card.php?action=edit&id='.$obj->rowid.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'">'.img_edit().'</a>'; $e .= '<a class="editfielda" title="'.$langs->trans("Employee").'" href="'.DOL_URL_ROOT.'/user/card.php?action=edit&token='.newToken().'&id='.$obj->rowid.'&backtopage='.urlencode($_SERVER["PHP_SELF"]).'">'.img_edit().'</a>';
} }
print $e; print $e;
print '</td>'."\n"; print '</td>'."\n";

View File

@ -40,6 +40,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
$langs->loadLangs(array("accountancy", "compta")); $langs->loadLangs(array("accountancy", "compta"));
$action = GETPOST('action', 'aZ09'); $action = GETPOST('action', 'aZ09');
$contextpage = GETPOST('contextpage', 'aZ09');
// Load variable for pagination // Load variable for pagination
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
@ -120,19 +121,19 @@ if ($limit > 0 && $limit != $conf->liste_limit) {
$filter = array(); $filter = array();
if (!empty($search_date_start)) { if (!empty($search_date_start)) {
$filter['t.doc_date>='] = $search_date_start; $filter['t.doc_date>='] = $search_date_start;
$param .= '&amp;date_startmonth='.GETPOST('date_startmonth', 'int').'&amp;date_startday='.GETPOST('date_startday', 'int').'&amp;date_startyear='.GETPOST('date_startyear', 'int'); $param .= '&date_startmonth='.GETPOST('date_startmonth', 'int').'&date_startday='.GETPOST('date_startday', 'int').'&date_startyear='.GETPOST('date_startyear', 'int');
} }
if (!empty($search_date_end)) { if (!empty($search_date_end)) {
$filter['t.doc_date<='] = $search_date_end; $filter['t.doc_date<='] = $search_date_end;
$param .= '&amp;date_endmonth='.GETPOST('date_endmonth', 'int').'&amp;date_endday='.GETPOST('date_endday', 'int').'&amp;date_endyear='.GETPOST('date_endyear', 'int'); $param .= '&date_endmonth='.GETPOST('date_endmonth', 'int').'&date_endday='.GETPOST('date_endday', 'int').'&date_endyear='.GETPOST('date_endyear', 'int');
} }
if (!empty($search_accountancy_code_start)) { if (!empty($search_accountancy_code_start)) {
$filter['t.numero_compte>='] = $search_accountancy_code_start; $filter['t.numero_compte>='] = $search_accountancy_code_start;
$param .= '&amp;search_accountancy_code_start='.$search_accountancy_code_start; $param .= '&search_accountancy_code_start='.urlencode($search_accountancy_code_start);
} }
if (!empty($search_accountancy_code_end)) { if (!empty($search_accountancy_code_end)) {
$filter['t.numero_compte<='] = $search_accountancy_code_end; $filter['t.numero_compte<='] = $search_accountancy_code_end;
$param .= '&amp;search_accountancy_code_end='.$search_accountancy_code_end; $param .= '&search_accountancy_code_end='.urlencode($search_accountancy_code_end);
} }
if (!empty($search_ledger_code)) { if (!empty($search_ledger_code)) {
$filter['t.code_journal'] = $search_ledger_code; $filter['t.code_journal'] = $search_ledger_code;
@ -236,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();
@ -416,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;
@ -389,11 +396,7 @@ if ($action == 'create') {
print dol_get_fiche_end(); print dol_get_fiche_end();
print '<div class="center">'; print $form->buttonsSaveCancel("Create");
print '<input type="submit" class="button" value="'.$langs->trans("Create").'">';
print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
print '<input type="button" value="'.$langs->trans("Cancel").'" class="button button-cancel" onclick="history.go(-1)" />';
print '</div>';
print '</form>'; print '</form>';
} else { } else {
@ -437,7 +440,7 @@ if ($action == 'create') {
print $langs->trans('Docdate'); print $langs->trans('Docdate');
print '</td>'; print '</td>';
if ($action != 'editdate') { if ($action != 'editdate') {
print '<td class="right"><a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editdate&amp;piece_num='.$object->piece_num.'&amp;mode='.$mode.'">'.img_edit($langs->transnoentitiesnoconv('SetDate'), 1).'</a></td>'; print '<td class="right"><a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editdate&token='.newToken().'&piece_num='.urlencode($object->piece_num).'&mode='.urlencode($mode).'">'.img_edit($langs->transnoentitiesnoconv('SetDate'), 1).'</a></td>';
} }
print '</tr></table>'; print '</tr></table>';
print '</td><td colspan="3">'; print '</td><td colspan="3">';
@ -450,7 +453,7 @@ if ($action == 'create') {
print '<input type="hidden" name="action" value="setdate">'; print '<input type="hidden" name="action" value="setdate">';
print '<input type="hidden" name="mode" value="'.$mode.'">'; print '<input type="hidden" name="mode" value="'.$mode.'">';
print $form->selectDate($object->doc_date ? $object->doc_date : - 1, 'doc_date', '', '', '', "setdate"); print $form->selectDate($object->doc_date ? $object->doc_date : - 1, 'doc_date', '', '', '', "setdate");
print '<input type="submit" class="button" value="'.$langs->trans('Modify').'">'; print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
print '</form>'; print '</form>';
} else { } else {
print $object->doc_date ? dol_print_date($object->doc_date, 'day') : '&nbsp;'; print $object->doc_date ? dol_print_date($object->doc_date, 'day') : '&nbsp;';
@ -464,7 +467,7 @@ if ($action == 'create') {
print $langs->trans('Codejournal'); print $langs->trans('Codejournal');
print '</td>'; print '</td>';
if ($action != 'editjournal') { if ($action != 'editjournal') {
print '<td class="right"><a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editjournal&amp;piece_num='.$object->piece_num.'&amp;mode='.$mode.'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a></td>'; print '<td class="right"><a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editjournal&token='.newToken().'&piece_num='.urlencode($object->piece_num).'&mode='.urlencode($mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a></td>';
} }
print '</tr></table>'; print '</tr></table>';
print '</td><td>'; print '</td><td>';
@ -477,7 +480,7 @@ if ($action == 'create') {
print '<input type="hidden" name="action" value="setjournal">'; print '<input type="hidden" name="action" value="setjournal">';
print '<input type="hidden" name="mode" value="'.$mode.'">'; print '<input type="hidden" name="mode" value="'.$mode.'">';
print $formaccounting->select_journal($object->code_journal, 'code_journal', 0, 0, array(), 1, 1); print $formaccounting->select_journal($object->code_journal, 'code_journal', 0, 0, array(), 1, 1);
print '<input type="submit" class="button" value="'.$langs->trans('Modify').'">'; print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
print '</form>'; print '</form>';
} else { } else {
print $object->code_journal; print $object->code_journal;
@ -491,7 +494,7 @@ if ($action == 'create') {
print $langs->trans('Piece'); print $langs->trans('Piece');
print '</td>'; print '</td>';
if ($action != 'editdocref') { if ($action != 'editdocref') {
print '<td class="right"><a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editdocref&amp;piece_num='.$object->piece_num.'&amp;mode='.$mode.'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a></td>'; print '<td class="right"><a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editdocref&token='.newToken().'&piece_num='.urlencode($object->piece_num).'&mode='.urlencode($mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a></td>';
} }
print '</tr></table>'; print '</tr></table>';
print '</td><td>'; print '</td><td>';
@ -504,7 +507,7 @@ if ($action == 'create') {
print '<input type="hidden" name="action" value="setdocref">'; print '<input type="hidden" name="action" value="setdocref">';
print '<input type="hidden" name="mode" value="'.$mode.'">'; print '<input type="hidden" name="mode" value="'.$mode.'">';
print '<input type="text" size="20" name="doc_ref" value="'.dol_escape_htmltag($object->doc_ref).'">'; print '<input type="text" size="20" name="doc_ref" value="'.dol_escape_htmltag($object->doc_ref).'">';
print '<input type="submit" class="button" value="'.$langs->trans('Modify').'">'; print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
print '</form>'; print '</form>';
} else { } else {
print $object->doc_ref; print $object->doc_ref;
@ -516,10 +519,10 @@ if ($action == 'create') {
print '</div>'; print '</div>';
print '<div class="fichehalfright"><div class="ficheaddleft">'; print '<div class="fichehalfright">';
print '<div class="underbanner clearboth"></div>'; print '<div class="underbanner clearboth"></div>';
print '<table class="border tableforfield" width="100%">'; print '<table class="border tableforfield centpercent">';
// Doc type // Doc type
if (!empty($object->doc_type)) { if (!empty($object->doc_type)) {
@ -595,7 +598,7 @@ if ($action == 'create') {
*/ */
print "</table>\n"; print "</table>\n";
print '</div></div><!-ee-->'; print '</div>';
print dol_get_fiche_end(); print dol_get_fiche_end();
@ -622,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";
if (count($object->linesmvt) > 0) {
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">'; print '<table class="noborder centpercent">';
if (count($object->linesmvt) > 0) {
$total_debit = 0; $total_debit = 0;
$total_credit = 0; $total_credit = 0;
@ -674,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>';
@ -685,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)) {
@ -700,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";
@ -737,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">';
@ -757,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';
@ -526,23 +527,25 @@ $sqlwhere = array();
if (count($filter) > 0) { if (count($filter) > 0) {
foreach ($filter as $key => $value) { foreach ($filter as $key => $value) {
if ($key == 't.doc_date') { if ($key == 't.doc_date') {
$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<=' || $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.'\''.$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.'='.$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 \''.$db->escape($value).'%\''; $sqlwhere[] = $key." LIKE '".$db->escape($value)."%'";
} elseif ($key == 't.subledger_account') {
$sqlwhere[] = natural_search($key, $value, 0, 1);
} elseif ($key == 't.date_creation>=' || $key == 't.date_creation<=') { } elseif ($key == 't.date_creation>=' || $key == 't.date_creation<=') {
$sqlwhere[] = $key.'\''.$db->idate($value).'\''; $sqlwhere[] = $key."'".$db->idate($value)."'";
} elseif ($key == 't.tms>=' || $key == 't.tms<=') { } elseif ($key == 't.tms>=' || $key == 't.tms<=') {
$sqlwhere[] = $key.'\''.$db->idate($value).'\''; $sqlwhere[] = $key."'".$db->idate($value)."'";
} elseif ($key == 't.date_export>=' || $key == 't.date_export<=') { } elseif ($key == 't.date_export>=' || $key == 't.date_export<=') {
$sqlwhere[] = $key.'\''.$db->idate($value).'\''; $sqlwhere[] = $key."'".$db->idate($value)."'";
} elseif ($key == 't.date_validated>=' || $key == 't.date_validated<=') { } elseif ($key == 't.date_validated>=' || $key == 't.date_validated<=') {
$sqlwhere[] = $key.'\''.$db->idate($value).'\''; $sqlwhere[] = $key."'".$db->idate($value)."'";
} elseif ($key == 't.credit' || $key == 't.debit') { } elseif ($key == 't.credit' || $key == 't.debit') {
$sqlwhere[] = natural_search($key, $value, 1, 1); $sqlwhere[] = natural_search($key, $value, 1, 1);
} elseif ($key == 't.reconciled_option') { } elseif ($key == 't.reconciled_option') {
@ -606,7 +609,8 @@ if ($action == 'export_fileconfirm' && $user->rights->accounting->mouvements->ex
} }
$sql .= " WHERE rowid = ".((int) $movement->id); $sql .= " WHERE rowid = ".((int) $movement->id);
dol_syslog("/accountancy/bookkeeping/list.php Function export_file Specify movements as exported sql=".$sql, LOG_DEBUG); dol_syslog("/accountancy/bookkeeping/list.php Function export_file Specify movements as exported", LOG_DEBUG);
$result = $db->query($sql); $result = $db->query($sql);
if (!$result) { if (!$result) {
$error++; $error++;
@ -689,9 +693,11 @@ if ($action == 'export_file') {
$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');
@ -712,6 +718,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(
@ -729,7 +736,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
@ -762,7 +769,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)) {
@ -1244,7 +1251,7 @@ while ($i < min($num, $limit)) {
} }
if (empty($line->date_validation)) { if (empty($line->date_validation)) {
if ($user->rights->accounting->mouvements->supprimer) { if ($user->rights->accounting->mouvements->supprimer) {
print '<a class="reposition paddingleft marginrightonly" href="'.$_SERVER['PHP_SELF'].'?action=delmouv&mvt_num='.$line->piece_num.$param.'&page='.$page.($sortfield ? '&sortfield='.$sortfield : '').($sortorder ? '&sortorder='.$sortorder : '').'">'.img_delete().'</a>'; print '<a class="reposition paddingleft marginrightonly" href="'.$_SERVER['PHP_SELF'].'?action=delmouv&token='.newToken().'&mvt_num='.$line->piece_num.$param.'&page='.$page.($sortfield ? '&sortfield='.$sortfield : '').($sortorder ? '&sortorder='.$sortorder : '').'">'.img_delete().'</a>';
} }
} }
print '</td>'; print '</td>';
@ -1268,7 +1275,7 @@ print '</div>';
// TODO Replace this with mass delete action // TODO Replace this with mass delete action
if ($user->rights->accounting->mouvements->supprimer_tous) { if ($user->rights->accounting->mouvements->supprimer_tous) {
print '<div class="tabsAction tabsActionNoBottom">'."\n"; print '<div class="tabsAction tabsActionNoBottom">'."\n";
print '<a class="butActionDelete" name="button_delmvt" href="'.$_SERVER["PHP_SELF"].'?action=delbookkeepingyear'.($param ? '&'.$param : '').'">'.$langs->trans("DeleteMvt").'</a>'; print '<a class="butActionDelete" name="button_delmvt" href="'.$_SERVER["PHP_SELF"].'?action=delbookkeepingyear&token='.newToken().($param ? '&'.$param : '').'">'.$langs->trans("DeleteMvt").'</a>';
print '</div>'; print '</div>';
} }

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 {
@ -904,7 +904,7 @@ while ($i < min($num, $limit)) {
} }
if (empty($line->date_validation)) { if (empty($line->date_validation)) {
if ($user->rights->accounting->mouvements->supprimer) { if ($user->rights->accounting->mouvements->supprimer) {
print '<a class="reposition paddingleft marginrightonly" href="'.$_SERVER['PHP_SELF'].'?action=delmouv&mvt_num='.$line->piece_num.$param.'&page='.$page.($sortfield ? '&sortfield='.$sortfield : '').($sortorder ? '&sortorder='.$sortorder : '').'">'.img_delete().'</a>'; print '<a class="reposition paddingleft marginrightonly" href="'.$_SERVER['PHP_SELF'].'?action=delmouv&token='.newToken().'&mvt_num='.$line->piece_num.$param.'&page='.$page.($sortfield ? '&sortfield='.$sortfield : '').($sortorder ? '&sortorder='.$sortorder : '').'">'.img_delete().'</a>';
} }
} }
print '</td>'; print '</td>';
@ -957,7 +957,7 @@ print '</div>';
// TODO Replace this with mass delete action // TODO Replace this with mass delete action
if ($user->rights->accounting->mouvements->supprimer_tous) { if ($user->rights->accounting->mouvements->supprimer_tous) {
print '<div class="tabsAction tabsActionNoBottom">'."\n"; print '<div class="tabsAction tabsActionNoBottom">'."\n";
print '<a class="butActionDelete" name="button_delmvt" href="'.$_SERVER["PHP_SELF"].'?action=delbookkeepingyear'.($param ? '&'.$param : '').'">'.$langs->trans("DeleteMvt").'</a>'; print '<a class="butActionDelete" name="button_delmvt" href="'.$_SERVER["PHP_SELF"].'?action=delbookkeepingyear&token='.newToken().($param ? '&'.$param : '').'">'.$langs->trans("DeleteMvt").'</a>';
print '</div>'; print '</div>';
} }

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 {
@ -915,7 +915,7 @@ while ($i < min($num, $limit)) {
} }
if (empty($line->date_validation)) { if (empty($line->date_validation)) {
if ($user->rights->accounting->mouvements->supprimer) { if ($user->rights->accounting->mouvements->supprimer) {
print '<a class="reposition paddingleft marginrightonly" href="'.$_SERVER['PHP_SELF'].'?action=delmouv&mvt_num='.$line->piece_num.$param.'&page='.$page.($sortfield ? '&sortfield='.$sortfield : '').($sortorder ? '&sortorder='.$sortorder : '').'">'.img_delete().'</a>'; print '<a class="reposition paddingleft marginrightonly" href="'.$_SERVER['PHP_SELF'].'?action=delmouv&token='.newToken().'&mvt_num='.$line->piece_num.$param.'&page='.$page.($sortfield ? '&sortfield='.$sortfield : '').($sortorder ? '&sortorder='.$sortorder : '').'">'.img_delete().'</a>';
} }
} }
print '</td>'; print '</td>';
@ -968,7 +968,7 @@ print '</div>';
// TODO Replace this with mass delete action // TODO Replace this with mass delete action
if ($user->rights->accounting->mouvements->supprimer_tous) { if ($user->rights->accounting->mouvements->supprimer_tous) {
print '<div class="tabsAction tabsActionNoBottom">'."\n"; print '<div class="tabsAction tabsActionNoBottom">'."\n";
print '<a class="butActionDelete" name="button_delmvt" href="'.$_SERVER["PHP_SELF"].'?action=delbookkeepingyear'.($param ? '&'.$param : '').'">'.$langs->trans("DeleteMvt").'</a>'; print '<a class="butActionDelete" name="button_delmvt" href="'.$_SERVER["PHP_SELF"].'?action=delbookkeepingyear&token='.newToken().($param ? '&'.$param : '').'">'.$langs->trans("DeleteMvt").'</a>';
print '</div>'; print '</div>';
} }

View File

@ -48,8 +48,8 @@ $socid = GETPOSTINT("socid");
// if ($user->socid) $socid=$user->socid; // if ($user->socid) $socid=$user->socid;
$limit = GETPOSTISSET('limit') ? GETPOST('limit', 'int') : $conf->liste_limit; $limit = GETPOSTISSET('limit') ? GETPOST('limit', 'int') : $conf->liste_limit;
$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;

View File

@ -48,8 +48,8 @@ $socid = GETPOSTINT("socid");
$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
$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;

View File

@ -212,7 +212,7 @@ class AccountancyCategory // extends CommonObject
$sql .= " ".(!isset($this->position) ? 'NULL' : ((int) $this->position)).","; $sql .= " ".(!isset($this->position) ? 'NULL' : ((int) $this->position)).",";
$sql .= " ".(!isset($this->fk_country) ? 'NULL' : ((int) $this->fk_country)).","; $sql .= " ".(!isset($this->fk_country) ? 'NULL' : ((int) $this->fk_country)).",";
$sql .= " ".(!isset($this->active) ? 'NULL' : ((int) $this->active)); $sql .= " ".(!isset($this->active) ? 'NULL' : ((int) $this->active));
$sql .= ", ".$conf->entity; $sql .= ", ".((int) $conf->entity);
$sql .= ")"; $sql .= ")";
$this->db->begin(); $this->db->begin();
@ -433,7 +433,7 @@ class AccountancyCategory // extends CommonObject
$this->lines_display = array(); $this->lines_display = array();
dol_syslog(__METHOD__." sql=".$sql, LOG_DEBUG); dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if ($resql) { if ($resql) {
$num = $this->db->num_rows($resql); $num = $this->db->num_rows($resql);
@ -632,7 +632,7 @@ class AccountancyCategory // extends CommonObject
$sql .= " WHERE aa.rowid = ".((int) $cpt_id); $sql .= " WHERE aa.rowid = ".((int) $cpt_id);
$this->db->begin(); $this->db->begin();
dol_syslog(__METHOD__." sql=".$sql, LOG_DEBUG); dol_syslog(__METHOD__, LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if (!$resql) { if (!$resql) {
$error++; $error++;

View File

@ -59,6 +59,8 @@ class AccountancyExport
public static $EXPORT_TYPE_LDCOMPTA10 = 120; public static $EXPORT_TYPE_LDCOMPTA10 = 120;
public static $EXPORT_TYPE_GESTIMUMV3 = 130; public static $EXPORT_TYPE_GESTIMUMV3 = 130;
public static $EXPORT_TYPE_GESTIMUMV5 = 135; public static $EXPORT_TYPE_GESTIMUMV5 = 135;
public static $EXPORT_TYPE_ISUITEEXPERT = 200;
// Generic FEC after that
public static $EXPORT_TYPE_FEC = 1000; public static $EXPORT_TYPE_FEC = 1000;
public static $EXPORT_TYPE_FEC2 = 1010; public static $EXPORT_TYPE_FEC2 = 1010;
@ -85,11 +87,11 @@ class AccountancyExport
* *
* @param DoliDb $db Database handler * @param DoliDb $db Database handler
*/ */
public function __construct(DoliDB &$db) public function __construct(DoliDB $db)
{ {
global $conf; global $conf;
$this->db = &$db; $this->db = $db;
$this->separator = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV; $this->separator = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV;
$this->end_line = empty($conf->global->ACCOUNTING_EXPORT_ENDLINE) ? "\n" : ($conf->global->ACCOUNTING_EXPORT_ENDLINE == 1 ? "\n" : "\r\n"); $this->end_line = empty($conf->global->ACCOUNTING_EXPORT_ENDLINE) ? "\n" : ($conf->global->ACCOUNTING_EXPORT_ENDLINE == 1 ? "\n" : "\r\n");
} }
@ -123,6 +125,7 @@ class AccountancyExport
self::$EXPORT_TYPE_GESTIMUMV5 => $langs->trans('Modelcsv_Gestinumv5'), self::$EXPORT_TYPE_GESTIMUMV5 => $langs->trans('Modelcsv_Gestinumv5'),
self::$EXPORT_TYPE_FEC => $langs->trans('Modelcsv_FEC'), self::$EXPORT_TYPE_FEC => $langs->trans('Modelcsv_FEC'),
self::$EXPORT_TYPE_FEC2 => $langs->trans('Modelcsv_FEC2'), self::$EXPORT_TYPE_FEC2 => $langs->trans('Modelcsv_FEC2'),
self::$EXPORT_TYPE_ISUITEEXPERT => 'Export iSuite Expert',
); );
ksort($listofexporttypes, SORT_NUMERIC); ksort($listofexporttypes, SORT_NUMERIC);
@ -158,6 +161,7 @@ class AccountancyExport
self::$EXPORT_TYPE_GESTIMUMV5 => 'gestimumv5', self::$EXPORT_TYPE_GESTIMUMV5 => 'gestimumv5',
self::$EXPORT_TYPE_FEC => 'fec', self::$EXPORT_TYPE_FEC => 'fec',
self::$EXPORT_TYPE_FEC2 => 'fec2', self::$EXPORT_TYPE_FEC2 => 'fec2',
self::$EXPORT_TYPE_ISUITEEXPERT => 'isuiteexpert',
); );
return $formatcode[$type]; return $formatcode[$type];
@ -243,6 +247,10 @@ class AccountancyExport
'label' => $langs->trans('Modelcsv_FEC2'), 'label' => $langs->trans('Modelcsv_FEC2'),
'ACCOUNTING_EXPORT_FORMAT' => 'txt', 'ACCOUNTING_EXPORT_FORMAT' => 'txt',
), ),
self::$EXPORT_TYPE_ISUITEEXPERT => array(
'label' => 'iSuite Expert',
'ACCOUNTING_EXPORT_FORMAT' => 'csv',
),
), ),
'cr'=> array( 'cr'=> array(
'1' => $langs->trans("Unix"), '1' => $langs->trans("Unix"),
@ -334,6 +342,9 @@ class AccountancyExport
case self::$EXPORT_TYPE_FEC2: case self::$EXPORT_TYPE_FEC2:
$this->exportFEC2($TData); $this->exportFEC2($TData);
break; break;
case self::$EXPORT_TYPE_ISUITEEXPERT :
$this->exportiSuiteExpert($TData);
break;
default: default:
$this->errors[] = $langs->trans('accountancy_error_modelnotfound'); $this->errors[] = $langs->trans('accountancy_error_modelnotfound');
break; break;
@ -903,7 +914,8 @@ class AccountancyExport
print "ValidDate".$separator; print "ValidDate".$separator;
print "Montantdevise".$separator; print "Montantdevise".$separator;
print "Idevise".$separator; print "Idevise".$separator;
print "DateLimitReglmt"; print "DateLimitReglmt".$separator;
print "NumFacture";
print $end_line; print $end_line;
foreach ($objectLines as $line) { foreach ($objectLines as $line) {
@ -913,9 +925,26 @@ class AccountancyExport
$date_creation = dol_print_date($line->date_creation, '%Y%m%d'); $date_creation = dol_print_date($line->date_creation, '%Y%m%d');
$date_document = dol_print_date($line->doc_date, '%Y%m%d'); $date_document = dol_print_date($line->doc_date, '%Y%m%d');
$date_lettering = dol_print_date($line->date_lettering, '%Y%m%d'); $date_lettering = dol_print_date($line->date_lettering, '%Y%m%d');
$date_validation = dol_print_date($line->date_validated, '%Y%m%d'); $date_validation = dol_print_date($line->date_validation, '%Y%m%d');
$date_limit_payment = dol_print_date($line->date_lim_reglement, '%Y%m%d'); $date_limit_payment = dol_print_date($line->date_lim_reglement, '%Y%m%d');
$refInvoice = '';
if ($line->doc_type == 'customer_invoice') {
// Customer invoice
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
$invoice = new Facture($this->db);
$invoice->fetch($line->fk_doc);
$refInvoice = $invoice->ref;
} elseif ($line->doc_type == 'supplier_invoice') {
// Supplier invoice
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
$invoice = new FactureFournisseur($this->db);
$invoice->fetch($line->fk_doc);
$refInvoice = $invoice->ref_supplier;
}
// FEC:JournalCode // FEC:JournalCode
print $line->code_journal . $separator; print $line->code_journal . $separator;
@ -968,10 +997,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
print dol_trunc(self::toAnsi($refInvoice), 17, 'right', 'UTF-8', 1);
print $end_line; print $end_line;
} }
@ -1009,7 +1041,8 @@ class AccountancyExport
print "ValidDate".$separator; print "ValidDate".$separator;
print "Montantdevise".$separator; print "Montantdevise".$separator;
print "Idevise".$separator; print "Idevise".$separator;
print "DateLimitReglmt"; print "DateLimitReglmt".$separator;
print "NumFacture";
print $end_line; print $end_line;
foreach ($objectLines as $line) { foreach ($objectLines as $line) {
@ -1019,9 +1052,26 @@ class AccountancyExport
$date_creation = dol_print_date($line->date_creation, '%Y%m%d'); $date_creation = dol_print_date($line->date_creation, '%Y%m%d');
$date_document = dol_print_date($line->doc_date, '%Y%m%d'); $date_document = dol_print_date($line->doc_date, '%Y%m%d');
$date_lettering = dol_print_date($line->date_lettering, '%Y%m%d'); $date_lettering = dol_print_date($line->date_lettering, '%Y%m%d');
$date_validation = dol_print_date($line->date_validated, '%Y%m%d'); $date_validation = dol_print_date($line->date_validation, '%Y%m%d');
$date_limit_payment = dol_print_date($line->date_lim_reglement, '%Y%m%d'); $date_limit_payment = dol_print_date($line->date_lim_reglement, '%Y%m%d');
$refInvoice = '';
if ($line->doc_type == 'customer_invoice') {
// Customer invoice
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
$invoice = new Facture($this->db);
$invoice->fetch($line->fk_doc);
$refInvoice = $invoice->ref;
} elseif ($line->doc_type == 'supplier_invoice') {
// Supplier invoice
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
$invoice = new FactureFournisseur($this->db);
$invoice->fetch($line->fk_doc);
$refInvoice = $invoice->ref_supplier;
}
// FEC:JournalCode // FEC:JournalCode
print $line->code_journal . $separator; print $line->code_journal . $separator;
@ -1077,7 +1127,11 @@ 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
print dol_trunc(self::toAnsi($refInvoice), 17, 'right', 'UTF-8', 1);
print $end_line; print $end_line;
} }
@ -1806,6 +1860,62 @@ class AccountancyExport
} }
} }
/**
* Export format : iSuite Expert
*
* by OpenSolus [https://opensolus.fr]
*
* @param array $objectLines data
*
* @return void
*/
public function exportiSuiteExpert($objectLines)
{
$this->separator = ';';
$this->end_line = "\r\n";
foreach ($objectLines as $line) {
$tab = array();
$date = dol_print_date($line->doc_date, '%d/%m/%Y');
$tab[] = $line->piece_num;
$tab[] = $date;
$tab[] = substr($date, 6, 4);
$tab[] = substr($date, 3, 2);
$tab[] = substr($date, 0, 2);
$tab[] = $line->doc_ref;
//Conversion de chaine UTF8 en Latin9
$tab[] = mb_convert_encoding(str_replace(' - Compte auxiliaire', '', $line->label_operation), "Windows-1252", 'UTF-8');
//Calcul de la longueur des numéros de comptes
$taille_numero = strlen(length_accountg($line->numero_compte));
//Création du numéro de client générique
$numero_cpt_client = '411';
for ($i = 1; $i <= ($taille_numero - 3); $i++) {
$numero_cpt_client .= '0';
}
//Création des comptes auxiliaire des clients
if (length_accountg($line->numero_compte) == $numero_cpt_client) {
$tab[] = rtrim(length_accounta($line->subledger_account), "0");
} else {
$tab[] = length_accountg($line->numero_compte);
}
$nom_client = explode(" - ", $line->label_operation);
$tab[] = mb_convert_encoding($nom_client[0], "Windows-1252", 'UTF-8');
$tab[] = price($line->debit);
$tab[] = price($line->credit);
$tab[] = price($line->montant);
$tab[] = $line->code_journal;
$separator = $this->separator;
print implode($separator, $tab) . $this->end_line;
}
}
/** /**
* trunc * trunc
* *

View File

@ -105,7 +105,7 @@ class AccountancySystem
$sql .= " a.pcg_version = '".$this->db->escape($ref)."'"; $sql .= " a.pcg_version = '".$this->db->escape($ref)."'";
} }
dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG); dol_syslog(get_class($this)."::fetch", 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);
@ -143,9 +143,9 @@ class AccountancySystem
$sql = "INSERT INTO ".MAIN_DB_PREFIX."accounting_system"; $sql = "INSERT INTO ".MAIN_DB_PREFIX."accounting_system";
$sql .= " (date_creation, fk_user_author, numero, label)"; $sql .= " (date_creation, fk_user_author, numero, label)";
$sql .= " VALUES ('".$this->db->idate($now)."',".$user->id.",'".$this->db->escape($this->numero)."','".$this->db->escape($this->label)."')"; $sql .= " VALUES ('".$this->db->idate($now)."',".((int) $user->id).",'".$this->db->escape($this->numero)."','".$this->db->escape($this->label)."')";
dol_syslog(get_class($this)."::create sql=".$sql, LOG_DEBUG); dol_syslog(get_class($this)."::create", LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if ($resql) { if ($resql) {
$id = $this->db->last_insert_id(MAIN_DB_PREFIX."accounting_system"); $id = $this->db->last_insert_id(MAIN_DB_PREFIX."accounting_system");

View File

@ -1,7 +1,7 @@
<?php <?php
/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com> /* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2020 Alexandre Spangaro <aspangaro@open-dsi.fr> * Copyright (C) 2013-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2013-2014 Florian Henry <florian.henry@open-concept.pro> * Copyright (C) 2013-2021 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015 Ari Elbaz (elarifr) <github@accedinfo.com> * Copyright (C) 2015 Ari Elbaz (elarifr) <github@accedinfo.com>
* Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr> * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
@ -26,6 +26,10 @@
* \brief File of class to manage accounting accounts * \brief File of class to manage accounting accounts
*/ */
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.'/compta/facture/class/facture.class.php';
/** /**
* Class to manage accounting accounts * Class to manage accounting accounts
*/ */
@ -105,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
*/ */
@ -140,6 +149,16 @@ class AccountingAccount extends CommonObject
*/ */
public $reconcilable; public $reconcilable;
/**
* @var array cache array
*/
private $accountingaccount_codetotid_cache = array();
const STATUS_ENABLED = 1;
const STATUS_DISABLED = 0;
/** /**
* Constructor * Constructor
* *
@ -150,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='.$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
} }
/** /**
@ -158,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
*/ */
@ -179,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 sql=".$sql, 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);
@ -259,7 +279,7 @@ class AccountingAccount extends CommonObject
// Put here code to add control on parameters values // Put here code to add control on parameters values
// Insert request // Insert request
$sql = "INSERT INTO ".MAIN_DB_PREFIX."accounting_account("; $sql = "INSERT INTO " . MAIN_DB_PREFIX . "accounting_account(";
$sql .= "datec"; $sql .= "datec";
$sql .= ", entity"; $sql .= ", entity";
$sql .= ", fk_pcg_version"; $sql .= ", fk_pcg_version";
@ -274,7 +294,7 @@ class AccountingAccount extends CommonObject
$sql .= ", reconcilable"; $sql .= ", reconcilable";
$sql .= ") VALUES ("; $sql .= ") VALUES (";
$sql .= " '".$this->db->idate($now)."'"; $sql .= " '".$this->db->idate($now)."'";
$sql .= ", ".$conf->entity; $sql .= ", ".((int) $conf->entity);
$sql .= ", ".(empty($this->fk_pcg_version) ? 'NULL' : "'".$this->db->escape($this->fk_pcg_version)."'"); $sql .= ", ".(empty($this->fk_pcg_version) ? 'NULL' : "'".$this->db->escape($this->fk_pcg_version)."'");
$sql .= ", ".(empty($this->pcg_type) ? 'NULL' : "'".$this->db->escape($this->pcg_type)."'"); $sql .= ", ".(empty($this->pcg_type) ? 'NULL' : "'".$this->db->escape($this->pcg_type)."'");
$sql .= ", ".(empty($this->account_number) ? 'NULL' : "'".$this->db->escape($this->account_number)."'"); $sql .= ", ".(empty($this->account_number) ? 'NULL' : "'".$this->db->escape($this->account_number)."'");
@ -282,22 +302,22 @@ class AccountingAccount extends CommonObject
$sql .= ", ".(empty($this->label) ? "''" : "'".$this->db->escape($this->label)."'"); $sql .= ", ".(empty($this->label) ? "''" : "'".$this->db->escape($this->label)."'");
$sql .= ", ".(empty($this->labelshort) ? "''" : "'".$this->db->escape($this->labelshort)."'"); $sql .= ", ".(empty($this->labelshort) ? "''" : "'".$this->db->escape($this->labelshort)."'");
$sql .= ", ".(empty($this->account_category) ? 0 : (int) $this->account_category); $sql .= ", ".(empty($this->account_category) ? 0 : (int) $this->account_category);
$sql .= ", ".$user->id; $sql .= ", ".((int) $user->id);
$sql .= ", ".(int) $this->active; $sql .= ", ".(int) $this->active;
$sql .= ", ".(int) $this->reconcilable; $sql .= ", ".(int) $this->reconcilable;
$sql .= ")"; $sql .= ")";
$this->db->begin(); $this->db->begin();
dol_syslog(get_class($this)."::create sql=".$sql, LOG_DEBUG); dol_syslog(get_class($this)."::create", LOG_DEBUG);
$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();
} }
if (!$error) { if (!$error) {
$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."accounting_account"); $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "accounting_account");
// Uncomment this and change MYOBJECT to your own tag if you // Uncomment this and change MYOBJECT to your own tag if you
// want this action to call a trigger. // want this action to call a trigger.
@ -313,8 +333,8 @@ class AccountingAccount extends CommonObject
// Commit or rollback // Commit or rollback
if ($error) { if ($error) {
foreach ($this->errors as $errmsg) { foreach ($this->errors as $errmsg) {
dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR); dol_syslog(get_class($this) . "::create " . $errmsg, LOG_ERR);
$this->error .= ($this->error ? ', '.$errmsg : $errmsg); $this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
} }
$this->db->rollback(); $this->db->rollback();
return -1 * $error; return -1 * $error;
@ -339,20 +359,20 @@ class AccountingAccount extends CommonObject
$this->db->begin(); $this->db->begin();
$sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account "; $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account ";
$sql .= " SET fk_pcg_version = ".($this->fk_pcg_version ? "'".$this->db->escape($this->fk_pcg_version)."'" : "null"); $sql .= " SET fk_pcg_version = " . ($this->fk_pcg_version ? "'" . $this->db->escape($this->fk_pcg_version) . "'" : "null");
$sql .= " , pcg_type = ".($this->pcg_type ? "'".$this->db->escape($this->pcg_type)."'" : "null"); $sql .= " , pcg_type = " . ($this->pcg_type ? "'" . $this->db->escape($this->pcg_type) . "'" : "null");
$sql .= " , account_number = '".$this->db->escape($this->account_number)."'"; $sql .= " , account_number = '" . $this->db->escape($this->account_number) . "'";
$sql .= " , account_parent = ".(int) $this->account_parent; $sql .= " , account_parent = " . (int) $this->account_parent;
$sql .= " , label = ".($this->label ? "'".$this->db->escape($this->label)."'" : "''"); $sql .= " , label = " . ($this->label ? "'" . $this->db->escape($this->label) . "'" : "''");
$sql .= " , labelshort = ".($this->labelshort ? "'".$this->db->escape($this->labelshort)."'" : "''"); $sql .= " , labelshort = " . ($this->labelshort ? "'" . $this->db->escape($this->labelshort) . "'" : "''");
$sql .= " , fk_accounting_category = ".(empty($this->account_category) ? 0 : (int) $this->account_category); $sql .= " , fk_accounting_category = " . (empty($this->account_category) ? 0 : (int) $this->account_category);
$sql .= " , fk_user_modif = ".((int) $user->id); $sql .= " , fk_user_modif = " . ((int) $user->id);
$sql .= " , active = ".(int) $this->active; $sql .= " , active = " . (int) $this->active;
$sql .= " , reconcilable = ".(int) $this->reconcilable; $sql .= " , reconcilable = " . (int) $this->reconcilable;
$sql .= " WHERE rowid = ".((int) $this->id); $sql .= " WHERE rowid = " . ((int) $this->id);
dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG); dol_syslog(get_class($this)."::update", LOG_DEBUG);
$result = $this->db->query($sql); $result = $this->db->query($sql);
if ($result) { if ($result) {
$this->db->commit(); $this->db->commit();
@ -374,12 +394,12 @@ class AccountingAccount extends CommonObject
global $langs; global $langs;
$sql = "(SELECT fk_code_ventilation FROM ".MAIN_DB_PREFIX."facturedet"; $sql = "(SELECT fk_code_ventilation FROM ".MAIN_DB_PREFIX."facturedet";
$sql .= " WHERE fk_code_ventilation=".$this->id.")"; $sql .= " WHERE fk_code_ventilation=".((int) $this->id).")";
$sql .= "UNION"; $sql .= "UNION";
$sql .= " (SELECT fk_code_ventilation FROM ".MAIN_DB_PREFIX."facture_fourn_det"; $sql .= " (SELECT fk_code_ventilation FROM ".MAIN_DB_PREFIX."facture_fourn_det";
$sql .= " WHERE fk_code_ventilation=".$this->id.")"; $sql .= " WHERE fk_code_ventilation=".((int) $this->id).")";
dol_syslog(get_class($this)."::checkUsage sql=".$sql, LOG_DEBUG); dol_syslog(get_class($this)."::checkUsage", LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if ($resql) { if ($resql) {
@ -413,22 +433,22 @@ class AccountingAccount extends CommonObject
$this->db->begin(); $this->db->begin();
if (!$error) { if (!$error) {
$sql = "DELETE FROM ".MAIN_DB_PREFIX."accounting_account"; $sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_account";
$sql .= " WHERE rowid=".((int) $this->id); $sql .= " WHERE rowid=" . ((int) $this->id);
dol_syslog(get_class($this)."::delete sql=".$sql); dol_syslog(get_class($this) . "::delete sql=" . $sql);
$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();
} }
} }
// Commit or rollback // Commit or rollback
if ($error) { if ($error) {
foreach ($this->errors as $errmsg) { foreach ($this->errors as $errmsg) {
dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); dol_syslog(get_class($this) . "::delete " . $errmsg, LOG_ERR);
$this->error .= ($this->error ? ', '.$errmsg : $errmsg); $this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
} }
$this->db->rollback(); $this->db->rollback();
return -1 * $error; return -1 * $error;
@ -457,7 +477,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;
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)) {
$notooltip = 1; // Force disable tooltips $notooltip = 1; // Force disable tooltips
@ -465,15 +485,16 @@ class AccountingAccount extends CommonObject
$result = ''; $result = '';
$url = ''; $labelurl = ''; $url = '';
$labelurl = '';
if (empty($option) || $option == 'ledger') { if (empty($option) || $option == 'ledger') {
$url = DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?search_accountancy_code_start='.urlencode($this->account_number).'&search_accountancy_code_end='.urlencode($this->account_number); $url = DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?search_accountancy_code_start=' . urlencode($this->account_number) . '&search_accountancy_code_end=' . urlencode($this->account_number);
$labelurl = $langs->trans("ShowAccountingAccountInLedger"); $labelurl = $langs->trans("ShowAccountingAccountInLedger");
} elseif ($option == 'journals') { } elseif ($option == 'journals') {
$url = DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?search_accountancy_code_start='.urlencode($this->account_number).'&search_accountancy_code_end='.urlencode($this->account_number); $url = DOL_URL_ROOT . '/accountancy/bookkeeping/list.php?search_accountancy_code_start=' . urlencode($this->account_number) . '&search_accountancy_code_end=' . urlencode($this->account_number);
$labelurl = $langs->trans("ShowAccountingAccountInJournals"); $labelurl = $langs->trans("ShowAccountingAccountInJournals");
} elseif ($option == 'accountcard') { } elseif ($option == 'accountcard') {
$url = DOL_URL_ROOT.'/accountancy/admin/card.php?id='.urlencode($this->id); $url = DOL_URL_ROOT . '/accountancy/admin/card.php?id=' . urlencode($this->id);
$labelurl = $langs->trans("ShowAccountingAccount"); $labelurl = $langs->trans("ShowAccountingAccount");
} }
@ -486,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) {
@ -495,29 +516,29 @@ class AccountingAccount extends CommonObject
$labeltoshow = $this->labelshort; $labeltoshow = $this->labelshort;
} }
$label = '<u>'.$labelurl.'</u>'; $label = '<u>' . $labelurl . '</u>';
if (!empty($this->account_number)) { if (!empty($this->account_number)) {
$label .= '<br><b>'.$langs->trans('AccountAccounting').':</b> '.length_accountg($this->account_number); $label .= '<br><b>' . $langs->trans('AccountAccounting') . ':</b> ' . length_accountg($this->account_number);
} }
if (!empty($labeltoshow)) { if (!empty($labeltoshow)) {
$label .= '<br><b>'.$langs->trans('Label').':</b> '.$labeltoshow; $label .= '<br><b>' . $langs->trans('Label') . ':</b> ' . $labeltoshow;
} }
if ($moretitle) { if ($moretitle) {
$label .= ' - '.$moretitle; $label .= ' - ' . $moretitle;
} }
$linkclose = ''; $linkclose = '';
if (empty($notooltip)) { if (empty($notooltip)) {
if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
$label = $labelurl; $label = $labelurl;
$linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
} }
$linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"';
$linkclose .= ' class="classfortooltip"'; $linkclose .= ' class="classfortooltip"';
} }
$linkstart = '<a href="'.$url.'"'; $linkstart = '<a href="' . $url . '"';
$linkstart .= $linkclose.'>'; $linkstart .= $linkclose . '>';
$linkend = '</a>'; $linkend = '</a>';
if ($nourl) { if ($nourl) {
@ -528,17 +549,17 @@ class AccountingAccount extends CommonObject
$label_link = length_accountg($this->account_number); $label_link = length_accountg($this->account_number);
if ($withlabel) { if ($withlabel) {
$label_link .= ' - '.($nourl ? '<span class="opacitymedium">' : '').$labeltoshow.($nourl ? '</span>' : ''); $label_link .= ' - ' . ($nourl ? '<span class="opacitymedium">' : '') . $labeltoshow . ($nourl ? '</span>' : '');
} }
if ($withpicto) { if ($withpicto) {
$result .= ($linkstart.img_object(($notooltip ? '' : $label), $picto, ($notooltip ? '' : 'class="classfortooltip"'), 0, 0, $notooltip ? 0 : 1).$linkend); $result .= ($linkstart . img_object(($notooltip ? '' : $label), $picto, ($notooltip ? '' : 'class="classfortooltip"'), 0, 0, $notooltip ? 0 : 1) . $linkend);
} }
if ($withpicto && $withpicto != 2) { if ($withpicto && $withpicto != 2) {
$result .= ' '; $result .= ' ';
} }
if ($withpicto != 2) { if ($withpicto != 2) {
$result .= $linkstart.$label_link.$linkend; $result .= $linkstart . $label_link . $linkend;
} }
return $result; return $result;
} }
@ -546,16 +567,16 @@ class AccountingAccount extends CommonObject
/** /**
* 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)
{ {
$sql = 'SELECT a.rowid, a.datec, a.fk_user_author, a.fk_user_modif, a.tms'; $sql = 'SELECT a.rowid, a.datec, a.fk_user_author, a.fk_user_modif, a.tms';
$sql .= ' FROM '.MAIN_DB_PREFIX.'accounting_account as a'; $sql .= ' FROM ' . MAIN_DB_PREFIX . 'accounting_account as a';
$sql .= ' WHERE a.rowid = '.((int) $id); $sql .= ' WHERE a.rowid = ' . ((int) $id);
dol_syslog(get_class($this).'::info sql='.$sql); dol_syslog(get_class($this) . '::info sql=' . $sql);
$result = $this->db->query($sql); $result = $this->db->query($sql);
if ($result) { if ($result) {
@ -604,7 +625,7 @@ class AccountingAccount extends CommonObject
$sql .= "SET ".$fieldtouse." = '0'"; $sql .= "SET ".$fieldtouse." = '0'";
$sql .= " WHERE rowid = ".((int) $id); $sql .= " WHERE rowid = ".((int) $id);
dol_syslog(get_class($this)."::accountDeactivate ".$fieldtouse." sql=".$sql, LOG_DEBUG); dol_syslog(get_class($this)."::accountDeactivate ".$fieldtouse, LOG_DEBUG);
$result = $this->db->query($sql); $result = $this->db->query($sql);
if ($result) { if ($result) {
@ -620,7 +641,7 @@ class AccountingAccount extends CommonObject
} }
} }
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/** /**
* Account activated * Account activated
* *
@ -628,7 +649,7 @@ class AccountingAccount extends CommonObject
* @param int $mode 0=field active, 1=field reconcilable * @param int $mode 0=field active, 1=field reconcilable
* @return int <0 if KO, >0 if OK * @return int <0 if KO, >0 if OK
*/ */
public function account_activate($id, $mode = 0) public function accountActivate($id, $mode = 0)
{ {
// phpcs:enable // phpcs:enable
$this->db->begin(); $this->db->begin();
@ -642,7 +663,7 @@ class AccountingAccount extends CommonObject
$sql .= " SET ".$fieldtouse." = '1'"; $sql .= " SET ".$fieldtouse." = '1'";
$sql .= " WHERE rowid = ".((int) $id); $sql .= " WHERE rowid = ".((int) $id);
dol_syslog(get_class($this)."::account_activate ".$fieldtouse." sql=".$sql, LOG_DEBUG); dol_syslog(get_class($this)."::account_activate ".$fieldtouse, LOG_DEBUG);
$result = $this->db->query($sql); $result = $this->db->query($sql);
if ($result) { if ($result) {
$this->db->commit(); $this->db->commit();
@ -654,7 +675,6 @@ class AccountingAccount extends CommonObject
} }
} }
/** /**
* Retourne le libelle du statut d'un user (actif, inactif) * Retourne le libelle du statut d'un user (actif, inactif)
* *
@ -677,44 +697,207 @@ class AccountingAccount extends CommonObject
public function LibStatut($status, $mode = 0) public function LibStatut($status, $mode = 0)
{ {
// phpcs:enable // phpcs:enable
if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
global $langs; global $langs;
$langs->loadLangs(array("users")); $langs->load("users");
$this->labelStatus[self::STATUS_ENABLED] = $langs->transnoentitiesnoconv('Enabled');
$this->labelStatus[self::STATUS_DISABLED] = $langs->transnoentitiesnoconv('Disabled');
$this->labelStatusShort[self::STATUS_ENABLED] = $langs->transnoentitiesnoconv('Enabled');
$this->labelStatusShort[self::STATUS_DISABLED] = $langs->transnoentitiesnoconv('Disabled');
}
if ($mode == 0) { $statusType = 'status4';
if ($status == 1) { if ($status == self::STATUS_DISABLED) {
return $langs->trans('Enabled'); $statusType = 'status5';
} elseif ($status == 0) {
return $langs->trans('Disabled');
} }
} elseif ($mode == 1) {
if ($status == 1) { return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
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'); * Return Suggest accounting accounts to bind
} elseif ($status == 0) { *
return img_picto($langs->trans('Disabled'), 'statut5').' '.$langs->trans('Disabled'); * @param Societe $buyer Object buyer
* @param Societe $seller Object seller
* @param Product $product Product object sell or buy
* @param Facture|FactureFournisseur $facture Facture
* @param FactureLigne|SupplierInvoiceLine $factureDet Facture Det
* @param array $accountingAccount Array of Account account
* @param string $type Customer / Supplier
* @return array Accounting accounts suggested
*/
public function getAccountingCodeToBind(Societe $buyer, Societe $seller, Product $product, $facture, $factureDet, $accountingAccount = array(), $type = '')
{
global $conf;
global $hookmanager;
// Instantiate hooks for external modules
$hookmanager->initHooks(array('accoutancyBindingCalculation'));
// Execute hook accoutancyBindingCalculation
$parameters = array('buyer' => $buyer, 'seller' => $seller, 'product' => $product, 'facture' => $facture, 'factureDet' => $factureDet ,'accountingAccount'=>$accountingAccount, $type);
$reshook = $hookmanager->executeHooks('accoutancyBindingCalculation', $parameters); // Note that $action and $object may have been modified by some hooks
if (empty($reshook)) {
if ($type == 'customer') {
$const_name = "SOLD";
} elseif ($type == 'supplier') {
$const_name = "BUY";
} }
} elseif ($mode == 3) {
if ($status == 1) { require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
return img_picto($langs->trans('Enabled'), 'statut4'); $isBuyerInEEC = isInEEC($buyer);
} elseif ($status == 0) { $isSellerInEEC = isInEEC($seller);
return img_picto($langs->trans('Disabled'), 'statut5'); $code_l = ''; // Default value for generic product/service
$code_p = ''; // Value for the product/service in parameter ($product)
$code_t = ''; // Default value of product account for the thirdparty
$suggestedid = '';
// Level 1 (define $code_l): Search suggested default account for product/service
$suggestedaccountingaccountbydefaultfor = '';
if ($factureDet->product_type == 1) {
if ($buyer->country_code == $seller->country_code || empty($buyer->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country)
$code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'} : '');
$suggestedaccountingaccountbydefaultfor = '';
} else {
if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with a VAT
$code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'} : '');
$suggestedaccountingaccountbydefaultfor = 'eecwithvat';
} elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) { // European intravat sale, without VAT intra community number
$code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'} : '');
$suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber';
} elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale
$code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_INTRA_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_INTRA_ACCOUNT'} : '');
$suggestedaccountingaccountbydefaultfor = 'eec';
} else { // Foreign sale
$code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_EXPORT_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_EXPORT_ACCOUNT'} : '');
$suggestedaccountingaccountbydefaultfor = 'export';
} }
} 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) { } elseif ($factureDet->product_type == 0) {
if ($status == 1) { if ($buyer->country_code == $seller->country_code || empty($buyer->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country)
return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'), 'statut4'); $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'} : '');
} elseif ($status == 0) { $suggestedaccountingaccountbydefaultfor = '';
return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'), 'statut5'); } else {
if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with a VAT
$code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'} : '');
$suggestedaccountingaccountbydefaultfor = 'eecwithvat';
} elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) { // European intravat sale, without VAT intra community number
$code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'} : '');
$suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber';
} elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale
$code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_INTRA_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_INTRA_ACCOUNT'} : '');
$suggestedaccountingaccountbydefaultfor = 'eec';
} else {
$code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_EXPORT_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_EXPORT_ACCOUNT'} : '');
$suggestedaccountingaccountbydefaultfor = 'export';
}
}
}
if ($code_l == -1) {
$code_l = '';
}
// Level 2 (define $code_p): Search suggested account for product/service (similar code exists in page index.php to make automatic binding)
$suggestedaccountingaccountfor = '';
if ((($buyer->country_code == $seller->country_code) || empty($buyer->country_code))) {
// If buyer in same country than seller (if not defined, we assume it is same country)
if ($type=='customer' && !empty($product->accountancy_code_sell)) {
$code_p = $product->accountancy_code_sell;
} elseif ($type=='supplier' && !empty($product->accountancy_code_buy)) {
$code_p = $product->accountancy_code_buy;
}
$suggestedid = $accountingAccount['dom'];
$suggestedaccountingaccountfor = 'prodserv';
} else {
if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) {
// European intravat sale, but with VAT
if ($type=='customer' && !empty($product->accountancy_code_sell)) {
$code_p = $product->accountancy_code_sell;
} elseif ($type=='supplier' && !empty($product->accountancy_code_buy)) {
$code_p = $product->accountancy_code_buy;
}
$suggestedid = $accountingAccount['dom'];
$suggestedaccountingaccountfor = 'eecwithvat';
} elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) {
// European intravat sale, without VAT intra community number
if ($type=='customer' && !empty($product->accountancy_code_sell)) {
$code_p = $product->accountancy_code_sell;
} elseif ($type=='supplier' && !empty($product->accountancy_code_buy)) {
$code_p = $product->accountancy_code_buy;
}
$suggestedid = $accountingAccount['dom']; // There is a doubt for this case. Is it an error on vat or we just forgot to fill vat number ?
$suggestedaccountingaccountfor = 'eecwithoutvatnumber';
} elseif ($isSellerInEEC && $isBuyerInEEC && !empty($product->accountancy_code_sell_intra)) {
// European intravat sale
if ($type=='customer' && !empty($product->accountancy_code_sell_intra)) {
$code_p = $product->accountancy_code_sell_intra;
} elseif ($type=='supplier' && !empty($product->accountancy_code_buy_intra)) {
$code_p = $product->accountancy_code_buy_intra;
}
$suggestedid = $accountingAccount['intra'];
$suggestedaccountingaccountfor = 'eec';
} else {
// Foreign sale
if ($type=='customer' && !empty($product->accountancy_code_sell_export)) {
$code_p = $product->accountancy_code_sell_export;
} elseif ($type=='supplier' && !empty($product->accountancy_code_buy_export)) {
$code_p = $product->accountancy_code_buy_export;
}
$suggestedid = $accountingAccount['export'];
$suggestedaccountingaccountfor = 'export';
}
}
// 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($buyer->code_compta_product)) {
$code_t = $buyer->code_compta_product;
$suggestedid = $accountingAccount['thirdparty'];
$suggestedaccountingaccountfor = 'thridparty';
}
}
// Manage Deposit
if ($factureDet->desc == "(DEPOSIT)" || $facture->type == $facture::TYPE_DEPOSIT) {
$accountdeposittoventilated = new self($this->db);
$result = $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1);
if ($result < 0) {
return -1;
}
$code_l = $accountdeposittoventilated->ref;
$suggestedid = $accountdeposittoventilated->rowid;
$suggestedaccountingaccountfor = 'deposit';
}
// If $suggestedid could not be guessed yet, we set it from the generic default accounting code $code_l
if (empty($suggestedid) && empty($code_p) && !empty($code_l) && empty($conf->global->ACCOUNTANCY_DO_NOT_AUTOFILL_ACCOUNT_WITH_GENERIC)) {
if (empty($this->accountingaccount_codetotid_cache[$code_l])) {
$tmpaccount = new self($this->db);
$result = $tmpaccount->fetch(0, $code_l, 1);
if ($result < 0) {
return -1;
}
if ($tmpaccount->id > 0) {
$suggestedid = $tmpaccount->id;
}
$this->accountingaccount_codetotid_cache[$code_l] = $tmpaccount->id;
} else {
$suggestedid = $this->accountingaccount_codetotid_cache[$code_l];
}
}
return array(
'suggestedaccountingaccountbydefaultfor' => $suggestedaccountingaccountbydefaultfor,
'suggestedaccountingaccountfor' => $suggestedaccountingaccountfor,
'suggestedid' => $suggestedid,
'code_l' => $code_l,
'code_p' => $code_p,
'code_t' => $code_t,
);
} else {
if (is_array($hookmanager->resArray) && !empty($hookmanager->resArray)) {
return $hookmanager->resArray;
} }
} }
} }

View File

@ -113,7 +113,7 @@ class AccountingJournal extends CommonObject
$sql .= " AND entity = ".$conf->entity; $sql .= " AND entity = ".$conf->entity;
} }
dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG); dol_syslog(get_class($this)."::fetch", 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);
@ -170,18 +170,18 @@ class AccountingJournal extends CommonObject
$sql .= ' WHERE 1 = 1'; $sql .= ' WHERE 1 = 1';
$sql .= " AND entity IN (".getEntity('accountancy').")"; $sql .= " AND entity IN (".getEntity('accountancy').")";
if (count($sqlwhere) > 0) { if (count($sqlwhere) > 0) {
$sql .= ' AND '.implode(' '.$filtermode.' ', $sqlwhere); $sql .= " AND ".implode(" ".$filtermode." ", $sqlwhere);
} }
if (!empty($sortfield)) { if (!empty($sortfield)) {
$sql .= $this->db->order($sortfield, $sortorder); $sql .= $this->db->order($sortfield, $sortorder);
} }
if (!empty($limit)) { if (!empty($limit)) {
$sql .= ' '.$this->db->plimit($limit + 1, $offset); $sql .= $this->db->plimit($limit + 1, $offset);
} }
$this->lines = array(); $this->lines = array();
dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG); dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if ($resql) { if ($resql) {
$num = $this->db->num_rows($resql); $num = $this->db->num_rows($resql);

View File

@ -382,15 +382,15 @@ class BookKeeping extends CommonObject
$sql .= ", '".$this->db->escape($this->numero_compte)."'"; $sql .= ", '".$this->db->escape($this->numero_compte)."'";
$sql .= ", ".(!empty($this->label_compte) ? ("'".$this->db->escape($this->label_compte)."'") : "NULL"); $sql .= ", ".(!empty($this->label_compte) ? ("'".$this->db->escape($this->label_compte)."'") : "NULL");
$sql .= ", '".$this->db->escape($this->label_operation)."'"; $sql .= ", '".$this->db->escape($this->label_operation)."'";
$sql .= ", ".$this->debit; $sql .= ", ".((float) $this->debit);
$sql .= ", ".$this->credit; $sql .= ", ".((float) $this->credit);
$sql .= ", ".$this->montant; $sql .= ", ".((float) $this->montant);
$sql .= ", ".(!empty($this->sens) ? ("'".$this->db->escape($this->sens)."'") : "NULL"); $sql .= ", ".(!empty($this->sens) ? ("'".$this->db->escape($this->sens)."'") : "NULL");
$sql .= ", '".$this->db->escape($this->fk_user_author)."'"; $sql .= ", '".$this->db->escape($this->fk_user_author)."'";
$sql .= ", '".$this->db->idate($now)."'"; $sql .= ", '".$this->db->idate($now)."'";
$sql .= ", '".$this->db->escape($this->code_journal)."'"; $sql .= ", '".$this->db->escape($this->code_journal)."'";
$sql .= ", ".(!empty($this->journal_label) ? ("'".$this->db->escape($this->journal_label)."'") : "NULL"); $sql .= ", ".(!empty($this->journal_label) ? ("'".$this->db->escape($this->journal_label)."'") : "NULL");
$sql .= ", ".$this->db->escape($this->piece_num); $sql .= ", ".((int) $this->piece_num);
$sql .= ", ".(!isset($this->entity) ? $conf->entity : $this->entity); $sql .= ", ".(!isset($this->entity) ? $conf->entity : $this->entity);
$sql .= ")"; $sql .= ")";
@ -647,7 +647,7 @@ class BookKeeping extends CommonObject
$sql .= ' '.(!isset($this->credit) ? 'NULL' : $this->credit).','; $sql .= ' '.(!isset($this->credit) ? 'NULL' : $this->credit).',';
$sql .= ' '.(!isset($this->montant) ? 'NULL' : $this->montant).','; $sql .= ' '.(!isset($this->montant) ? 'NULL' : $this->montant).',';
$sql .= ' '.(!isset($this->sens) ? 'NULL' : "'".$this->db->escape($this->sens)."'").','; $sql .= ' '.(!isset($this->sens) ? 'NULL' : "'".$this->db->escape($this->sens)."'").',';
$sql .= ' '.$user->id.','; $sql .= ' '.((int) $user->id).',';
$sql .= ' '."'".$this->db->idate($now)."',"; $sql .= ' '."'".$this->db->idate($now)."',";
$sql .= ' '.(empty($this->code_journal) ? 'NULL' : "'".$this->db->escape($this->code_journal)."'").','; $sql .= ' '.(empty($this->code_journal) ? 'NULL' : "'".$this->db->escape($this->code_journal)."'").',';
$sql .= ' '.(empty($this->journal_label) ? 'NULL' : "'".$this->db->escape($this->journal_label)."'").','; $sql .= ' '.(empty($this->journal_label) ? 'NULL' : "'".$this->db->escape($this->journal_label)."'").',';
@ -883,21 +883,21 @@ class BookKeeping extends CommonObject
$sql .= ' WHERE 1 = 1'; $sql .= ' WHERE 1 = 1';
$sql .= " AND entity IN (".getEntity('accountancy').")"; $sql .= " AND entity IN (".getEntity('accountancy').")";
if (count($sqlwhere) > 0) { if (count($sqlwhere) > 0) {
$sql .= ' AND '.implode(' '.$filtermode.' ', $sqlwhere); $sql .= " AND ".implode(" ".$filtermode." ", $sqlwhere);
} }
// Affichage par compte comptable // Affichage par compte comptable
if (!empty($option)) { if (!empty($option)) {
$sql .= ' AND t.subledger_account IS NOT NULL'; $sql .= ' AND t.subledger_account IS NOT NULL';
$sql .= ' ORDER BY t.subledger_account ASC'; $sortfield = 't.subledger_account'.($sortfield ? ','.$sortfield : '');
$sortorder = 'ASC'.($sortfield ? ','.$sortfield : '');
} else { } else {
$sql .= ' ORDER BY t.numero_compte ASC'; $sortfield = 't.numero_compte'.($sortfield ? ','.$sortfield : '');
$sortorder = 'ASC'.($sortorder ? ','.$sortorder : '');
} }
if (!empty($sortfield)) { $sql .= $this->db->order($sortfield, $sortorder);
$sql .= ', '.$sortfield.' '.$sortorder;
}
if (!empty($limit)) { if (!empty($limit)) {
$sql .= ' '.$this->db->plimit($limit + 1, $offset); $sql .= $this->db->plimit($limit + 1, $offset);
} }
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
@ -1013,7 +1013,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<=') {
@ -1042,13 +1042,13 @@ class BookKeeping extends CommonObject
$sql .= " AND t.date_export IS NULL"; $sql .= " AND t.date_export IS NULL";
} }
if (count($sqlwhere) > 0) { if (count($sqlwhere) > 0) {
$sql .= ' AND '.implode(' '.$filtermode.' ', $sqlwhere); $sql .= ' AND '.implode(" ".$filtermode." ", $sqlwhere);
} }
if (!empty($sortfield)) { if (!empty($sortfield)) {
$sql .= $this->db->order($sortfield, $sortorder); $sql .= $this->db->order($sortfield, $sortorder);
} }
if (!empty($limit)) { if (!empty($limit)) {
$sql .= ' '.$this->db->plimit($limit + 1, $offset); $sql .= $this->db->plimit($limit + 1, $offset);
} }
$this->lines = array(); $this->lines = array();
@ -1135,17 +1135,17 @@ class BookKeeping extends CommonObject
if (count($filter) > 0) { if (count($filter) > 0) {
foreach ($filter as $key => $value) { foreach ($filter as $key => $value) {
if ($key == 't.doc_date') { if ($key == 't.doc_date') {
$sqlwhere[] = $key.'=\''.$this->db->idate($value).'\''; $sqlwhere[] = $key." = '".$this->db->idate($value)."'";
} elseif ($key == 't.doc_date>=' || $key == 't.doc_date<=') { } elseif ($key == 't.doc_date>=' || $key == 't.doc_date<=') {
$sqlwhere[] = $key.'\''.$this->db->idate($value).'\''; $sqlwhere[] = $key."'".$this->db->idate($value)."'";
} 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.subledger_label') { } elseif ($key == 't.subledger_label') {
$sqlwhere[] = $key.' LIKE \''.$this->db->escape($value).'%\''; $sqlwhere[] = $key." LIKE '".$this->db->escape($value)."%'";
} elseif ($key == 't.code_journal' && !empty($value)) { } elseif ($key == 't.code_journal' && !empty($value)) {
if (is_array($value)) { if (is_array($value)) {
$sqlwhere[] = natural_search("t.code_journal", join(',', $value), 3, 1); $sqlwhere[] = natural_search("t.code_journal", join(',', $value), 3, 1);
@ -1153,13 +1153,13 @@ class BookKeeping extends CommonObject
$sqlwhere[] = natural_search("t.code_journal", $value, 3, 1); $sqlwhere[] = natural_search("t.code_journal", $value, 3, 1);
} }
} else { } else {
$sqlwhere[] = $key.' LIKE \'%'.$this->db->escape($value).'%\''; $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'";
} }
} }
} }
$sql .= ' WHERE entity IN ('.getEntity('accountancy').')'; $sql .= ' WHERE entity IN ('.getEntity('accountancy').')';
if (count($sqlwhere) > 0) { if (count($sqlwhere) > 0) {
$sql .= ' AND '.implode(' '.$filtermode.' ', $sqlwhere); $sql .= " AND ".implode(" ".$filtermode." ", $sqlwhere);
} }
$sql .= ' GROUP BY t.numero_compte'; $sql .= ' GROUP BY t.numero_compte';
@ -1168,7 +1168,7 @@ class BookKeeping extends CommonObject
$sql .= $this->db->order($sortfield, $sortorder); $sql .= $this->db->order($sortfield, $sortorder);
} }
if (!empty($limit)) { if (!empty($limit)) {
$sql .= ' '.$this->db->plimit($limit + 1, $offset); $sql .= $this->db->plimit($limit + 1, $offset);
} }
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
@ -1345,8 +1345,9 @@ class BookKeeping extends CommonObject
$this->db->begin(); $this->db->begin();
$sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element.$mode; $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element.$mode;
$sql .= ' SET '.$field.'='.(is_numeric($value) ? $value : "'".$this->db->escape($value)."'"); $sql .= " SET ".$field." = ".(is_numeric($value) ? ((float) $value) : "'".$this->db->escape($value)."'");
$sql .= " WHERE piece_num = '".$this->db->escape($piece_num)."'"; $sql .= " WHERE piece_num = ".((int) $piece_num);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if (!$resql) { if (!$resql) {
@ -1635,7 +1636,7 @@ class BookKeeping extends CommonObject
$sql .= ", date_export"; $sql .= ", date_export";
} }
$sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element.$mode; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element.$mode;
$sql .= " WHERE piece_num = ".$piecenum; $sql .= " WHERE piece_num = ".((int) $piecenum);
$sql .= " AND entity IN (".getEntity('accountancy').")"; $sql .= " AND entity IN (".getEntity('accountancy').")";
dol_syslog(__METHOD__, LOG_DEBUG); dol_syslog(__METHOD__, LOG_DEBUG);
@ -1676,7 +1677,7 @@ class BookKeeping extends CommonObject
$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 IN (".getEntity('accountancy').")";
dol_syslog(get_class($this)."getNextNumMvt sql=".$sql, LOG_DEBUG); dol_syslog(get_class($this)."getNextNumMvt", LOG_DEBUG);
$result = $this->db->query($sql); $result = $this->db->query($sql);
if ($result) { if ($result) {
@ -1716,7 +1717,7 @@ class BookKeeping extends CommonObject
$sql .= ", date_export"; $sql .= ", date_export";
} }
$sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element.$mode; $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element.$mode;
$sql .= " WHERE piece_num = ".$piecenum; $sql .= " WHERE piece_num = ".((int) $piecenum);
$sql .= " AND entity IN (".getEntity('accountancy').")"; $sql .= " AND entity IN (".getEntity('accountancy').")";
dol_syslog(__METHOD__, LOG_DEBUG); dol_syslog(__METHOD__, LOG_DEBUG);
@ -1854,7 +1855,7 @@ class BookKeeping extends CommonObject
$sql .= ' SELECT doc_date, doc_type,'; $sql .= ' SELECT doc_date, doc_type,';
$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, '.$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);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if (!$resql) { if (!$resql) {
@ -2013,7 +2014,7 @@ class BookKeeping extends CommonObject
$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 IN (".getEntity('accountancy').")";
dol_syslog(get_class($this)."::select_account sql=".$sql, LOG_DEBUG); dol_syslog(get_class($this)."::select_account", LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if ($resql) { if ($resql) {
$obj = ''; $obj = '';
@ -2053,7 +2054,7 @@ class BookKeeping extends CommonObject
$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 IN (".getEntity('accountancy').")";
dol_syslog(get_class($this)."::select_account sql=".$sql, LOG_DEBUG); dol_syslog(get_class($this)."::select_account", LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if ($resql) { if ($resql) {
$obj = ''; $obj = '';
@ -2117,11 +2118,22 @@ class BookKeepingLine
*/ */
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
@ -2152,4 +2164,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

@ -6,7 +6,7 @@
* *
* 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
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
@ -279,7 +279,7 @@ class Lettering extends BookKeeping
$sql .= " WHERE rowid IN (".$this->db->sanitize(implode(',', $ids)).") AND date_validated IS NULL "; $sql .= " WHERE rowid IN (".$this->db->sanitize(implode(',', $ids)).") AND date_validated IS NULL ";
$this->db->begin(); $this->db->begin();
dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG); dol_syslog(get_class($this)."::update", LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if (!$resql) { if (!$resql) {
$error++; $error++;

View File

@ -31,7 +31,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');
@ -63,57 +64,52 @@ if (empty($conf->accounting->enabled)) {
if ($user->socid > 0) { if ($user->socid > 0) {
accessforbidden(); accessforbidden();
} }
if (!$user->rights->accounting->fiscalyear->write) { if (empty($user->rights->accounting->fiscalyear->write)) {
accessforbidden(); accessforbidden();
} }
/* /*
* 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();
if ($result < 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')); $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')); $date_end = dol_mktime(23, 59, 59, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int'));
if (is_array($object->lines)) { $error = 0;
foreach ($object->lines as $movement) {
$now = dol_now();
$db->begin();
// Specify as export : update field date_validated on selected month/year
$sql = " UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping"; $sql = " UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping";
$sql .= " SET date_validated = '".$db->idate($now)."'"; $sql .= " SET date_validated = '".$db->idate($now)."'";
$sql .= " WHERE rowid = ".((int) $movement->id); $sql .= " WHERE entity = " . ((int) $conf->entity);
$sql .= " AND doc_date >= '" . $db->idate($date_start) . "'"; $sql .= " AND doc_date >= '" . $db->idate($date_start) . "'";
$sql .= " AND doc_date <= '" . $db->idate($date_end) . "'"; $sql .= " AND doc_date <= '" . $db->idate($date_end) . "'";
$sql .= " AND date_validated IS NULL";
dol_syslog("/accountancy/closure/index.php :: Function validate_movement_confirm Specify movements as validated sql=".$sql, LOG_DEBUG); dol_syslog("/accountancy/closure/index.php action=validate_movement_confirm -> Set movements as validated", LOG_DEBUG);
$result = $db->query($sql); $result = $db->query($sql);
if (!$result) { if (!$result) {
$error++; $error++;
break;
}
}
} }
if (!$error) { if (!$error) {
$db->commit(); $db->commit();
setEventMessages($langs->trans("AllMovementsWereRecordedAsValidated"), null, 'mesgs'); 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 = '';
} }
} }
@ -189,7 +185,7 @@ for ($i = 1; $i <= 12; $i++) {
if ($j > 12) { if ($j > 12) {
$j -= 12; $j -= 12;
} }
$sql .= " SUM(".$db->ifsql('MONTH(b.doc_date)='.$j, '1', '0').") AS month".str_pad($j, 2, '0', STR_PAD_LEFT).","; $sql .= " SUM(".$db->ifsql("MONTH(b.doc_date)=".$j, "1", "0").") AS month".str_pad($j, 2, "0", STR_PAD_LEFT).",";
} }
$sql .= " COUNT(b.rowid) as total"; $sql .= " COUNT(b.rowid) as total";
$sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as b"; $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as b";
@ -198,7 +194,7 @@ $sql .= " AND b.doc_date <= '".$db->idate($search_date_end)."'";
$sql .= " AND b.entity IN (".getEntity('bookkeeping', 0).")"; // We don't share object for accountancy $sql .= " AND b.entity IN (".getEntity('bookkeeping', 0).")"; // We don't share object for accountancy
$sql .= " AND date_validated IS NULL"; $sql .= " AND date_validated IS NULL";
dol_syslog('htdocs/accountancy/closure/index.php sql='.$sql, LOG_DEBUG); dol_syslog('htdocs/accountancy/closure/index.php', LOG_DEBUG);
$resql = $db->query($sql); $resql = $db->query($sql);
if ($resql) { if ($resql) {
$num = $db->num_rows($resql); $num = $db->num_rows($resql);

View File

@ -117,7 +117,7 @@ if (!empty($id)) {
$sql .= " WHERE f.fk_statut > 0 AND l.rowid = ".((int) $id); $sql .= " WHERE f.fk_statut > 0 AND l.rowid = ".((int) $id);
$sql .= " AND f.entity IN (".getEntity('invoice', 0).")"; // We don't share object for accountancy $sql .= " AND f.entity IN (".getEntity('invoice', 0).")"; // We don't share object for accountancy
dol_syslog("/accounting/customer/card.php sql=".$sql, LOG_DEBUG); dol_syslog("/accounting/customer/card.php", LOG_DEBUG);
$result = $db->query($sql); $result = $db->query($sql);
if ($result) { if ($result) {

View File

@ -31,10 +31,14 @@ 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.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.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"));
$validatemonth = GETPOST('validatemonth', 'int');
$validateyear = GETPOST('validateyear', 'int');
// Security check // Security check
if (empty($conf->accounting->enabled)) { if (empty($conf->accounting->enabled)) {
accessforbidden(); accessforbidden();
@ -42,10 +46,11 @@ if (empty($conf->accounting->enabled)) {
if ($user->socid > 0) { if ($user->socid > 0) {
accessforbidden(); accessforbidden();
} }
if (!$user->rights->accounting->bind->write) { if (empty($user->rights->accounting->bind->write)) {
accessforbidden(); accessforbidden();
} }
$accountingAccount = new AccountingAccount($db);
$month_start = ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1); $month_start = ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1);
if (GETPOST("year", 'int')) { if (GETPOST("year", 'int')) {
@ -71,13 +76,24 @@ $action = GETPOST('action', 'aZ09');
$chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version'); $chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version');
// Security check
if (empty($conf->accounting->enabled)) {
accessforbidden();
}
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->mouvements->lire)) {
accessforbidden();
}
/* /*
* Actions * Actions
*/ */
if ($action == 'clean' || $action == 'validatehistory') { 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";
@ -85,8 +101,8 @@ if ($action == 'clean' || $action == 'validatehistory') {
$sql1 .= ' (SELECT accnt.rowid '; $sql1 .= ' (SELECT accnt.rowid ';
$sql1 .= ' FROM '.MAIN_DB_PREFIX.'accounting_account as accnt'; $sql1 .= ' FROM '.MAIN_DB_PREFIX.'accounting_account as accnt';
$sql1 .= ' INNER JOIN '.MAIN_DB_PREFIX.'accounting_system as syst'; $sql1 .= ' INNER JOIN '.MAIN_DB_PREFIX.'accounting_system as syst';
$sql1 .= ' ON accnt.fk_pcg_version = syst.pcg_version AND syst.rowid='.$conf->global->CHARTOFACCOUNTS.' AND accnt.entity = '.$conf->entity.')'; $sql1 .= ' ON accnt.fk_pcg_version = syst.pcg_version AND syst.rowid='.((int) $conf->global->CHARTOFACCOUNTS).' AND accnt.entity = '.((int) $conf->entity).')';
$sql1 .= ' AND fd.fk_facture IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'facture WHERE entity = '.$conf->entity.')'; $sql1 .= ' AND fd.fk_facture IN (SELECT rowid FROM '.MAIN_DB_PREFIX.'facture WHERE entity = '.((int) $conf->entity).')';
$sql1 .= ' AND fk_code_ventilation <> 0'; $sql1 .= ' AND fk_code_ventilation <> 0';
dol_syslog("htdocs/accountancy/customer/index.php fixaccountancycode", LOG_DEBUG); dol_syslog("htdocs/accountancy/customer/index.php fixaccountancycode", LOG_DEBUG);
@ -103,6 +119,9 @@ if ($action == 'clean' || $action == 'validatehistory') {
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
@ -110,13 +129,13 @@ if ($action == 'validatehistory') {
$sql1 = "UPDATE " . MAIN_DB_PREFIX . "facturedet"; $sql1 = "UPDATE " . MAIN_DB_PREFIX . "facturedet";
$sql1 .= " SET fk_code_ventilation = accnt.rowid"; $sql1 .= " SET fk_code_ventilation = accnt.rowid";
$sql1 .= " FROM " . MAIN_DB_PREFIX . "product as p, " . MAIN_DB_PREFIX . "accounting_account as accnt , " . MAIN_DB_PREFIX . "accounting_system as syst"; $sql1 .= " FROM " . MAIN_DB_PREFIX . "product as p, " . MAIN_DB_PREFIX . "accounting_account as accnt , " . MAIN_DB_PREFIX . "accounting_system as syst";
$sql1 .= " WHERE " . MAIN_DB_PREFIX . "facturedet.fk_product = p.rowid AND accnt.fk_pcg_version = syst.pcg_version AND syst.rowid=" . ((int) $conf->global->CHARTOFACCOUNTS).' AND accnt.entity = '.$conf->entity; $sql1 .= " WHERE " . MAIN_DB_PREFIX . "facturedet.fk_product = p.rowid 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 p.accountancy_code_sell=accnt.account_number"; $sql1 .= " AND accnt.active = 1 AND p.accountancy_code_sell=accnt.account_number";
$sql1 .= " AND " . MAIN_DB_PREFIX . "facturedet.fk_code_ventilation = 0"; $sql1 .= " AND " . MAIN_DB_PREFIX . "facturedet.fk_code_ventilation = 0";
} else { } else {
$sql1 = "UPDATE " . MAIN_DB_PREFIX . "facturedet as fd, " . MAIN_DB_PREFIX . "product as p, " . MAIN_DB_PREFIX . "accounting_account as accnt , " . MAIN_DB_PREFIX . "accounting_system as syst"; $sql1 = "UPDATE " . MAIN_DB_PREFIX . "facturedet as fd, " . MAIN_DB_PREFIX . "product as p, " . MAIN_DB_PREFIX . "accounting_account as accnt , " . MAIN_DB_PREFIX . "accounting_system as syst";
$sql1 .= " SET fk_code_ventilation = accnt.rowid"; $sql1 .= " SET fk_code_ventilation = accnt.rowid";
$sql1 .= " WHERE fd.fk_product = p.rowid AND accnt.fk_pcg_version = syst.pcg_version AND syst.rowid=" . ((int) $conf->global->CHARTOFACCOUNTS).' AND accnt.entity = '.$conf->entity; $sql1 .= " WHERE fd.fk_product = p.rowid 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 p.accountancy_code_sell=accnt.account_number"; $sql1 .= " AND accnt.active = 1 AND p.accountancy_code_sell=accnt.account_number";
$sql1 .= " AND fd.fk_code_ventilation = 0"; $sql1 .= " AND fd.fk_code_ventilation = 0";
}*/ }*/
@ -134,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);
@ -156,13 +174,16 @@ 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)."'";
} }
if ($validatemonth && $validateyear) {
$sql .= dolSqlDateFilter('f.datef', 0, $validatemonth, $validateyear);
}
dol_syslog('htdocs/accountancy/customer/index.php'); dol_syslog('htdocs/accountancy/customer/index.php');
$result = $db->query($sql); $result = $db->query($sql);
if (!$result) { if (!$result) {
$error++; $error++;
@ -174,81 +195,108 @@ if ($action == 'validatehistory') {
$isSellerInEEC = isInEEC($mysoc); $isSellerInEEC = isInEEC($mysoc);
$thirdpartystatic = new Societe($db);
$facture_static = new Facture($db);
$facture_static_det = new FactureLigne($db);
$product_static = new Product($db);
$i = 0; $i = 0;
while ($i < min($num_lines, 10000)) { // No more than 10000 at once while ($i < min($num_lines, 10000)) { // No more than 10000 at once
$objp = $db->fetch_object($result); $objp = $db->fetch_object($result);
$isBuyerInEEC = isInEEC($objp); // This make a database request but there is a cache into $conf->cache['country_code_in_EEC'] $thirdpartystatic->id = $objp->socid;
$thirdpartystatic->name = $objp->name;
$thirdpartystatic->client = $objp->client;
$thirdpartystatic->fournisseur = $objp->fournisseur;
$thirdpartystatic->code_client = $objp->code_client;
$thirdpartystatic->code_compta_client = $objp->code_compta_client;
$thirdpartystatic->code_fournisseur = $objp->code_fournisseur;
$thirdpartystatic->code_compta_fournisseur = $objp->code_compta_fournisseur;
$thirdpartystatic->email = $objp->email;
$thirdpartystatic->country_code = $objp->country_code;
$thirdpartystatic->tva_intra = $objp->tva_intra;
$thirdpartystatic->code_compta_product = $objp->company_code_sell; // The accounting account for product stored on thirdparty object (for level3 suggestion)
// Level 2: Search suggested account for product/service (similar code exists in page list.php to make manual binding) $product_static->ref = $objp->product_ref;
$suggestedaccountingaccountfor = ''; $product_static->id = $objp->product_id;
if (($objp->country_code == $mysoc->country_code) || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) $product_static->type = $objp->type;
$objp->code_sell_p = $objp->code_sell; $product_static->label = $objp->product_label;
$objp->aarowid_suggest = $objp->aarowid; $product_static->status = $objp->status;
$suggestedaccountingaccountfor = ''; $product_static->status_buy = $objp->status_buy;
$product_static->accountancy_code_sell = $objp->code_sell;
$product_static->accountancy_code_sell_intra = $objp->code_sell_intra;
$product_static->accountancy_code_sell_export = $objp->code_sell_export;
$product_static->accountancy_code_buy = $objp->code_buy;
$product_static->accountancy_code_buy_intra = $objp->code_buy_intra;
$product_static->accountancy_code_buy_export = $objp->code_buy_export;
$product_static->tva_tx = $objp->tva_tx_prod;
$facture_static->ref = $objp->ref;
$facture_static->id = $objp->facid;
$facture_static->type = $objp->ftype;
$facture_static->date = $objp->datef;
$facture_static_det->id = $objp->rowid;
$facture_static_det->total_ht = $objp->total_ht;
$facture_static_det->tva_tx = $objp->tva_tx_line;
$facture_static_det->vat_src_code = $objp->vat_src_code;
$facture_static_det->product_type = $objp->type_l;
$facture_static_det->desc = $objp->description;
$accountingAccountArray = array(
'dom'=>$objp->aarowid,
'intra'=>$objp->aarowid_intra,
'export'=>$objp->aarowid_export,
'thirdparty' =>$objp->aarowid_thirdparty);
$code_sell_p_notset = '';
$code_sell_t_notset = '';
$suggestedid = 0;
$return=$accountingAccount->getAccountingCodeToBind($thirdpartystatic, $mysoc, $product_static, $facture_static, $facture_static_det, $accountingAccountArray, 'customer');
if (!is_array($return) && $return < 0) {
setEventMessage($accountingAccount->error, 'errors');
} else { } else {
if ($isSellerInEEC && $isBuyerInEEC && $objp->tva_tx_line != 0) { // European intravat sale, but with VAT $suggestedid = $return['suggestedid'];
$objp->code_sell_p = $objp->code_sell; $suggestedaccountingaccountfor = $return['suggestedaccountingaccountfor'];
$objp->aarowid_suggest = $objp->aarowid;
$suggestedaccountingaccountfor = 'eecwithvat'; if (!empty($suggestedid) && $suggestedaccountingaccountfor != '' && $suggestedaccountingaccountfor != 'eecwithoutvatnumber') {
} elseif ($isSellerInEEC && $isBuyerInEEC && empty($objp->tva_intra)) { // European intravat sale, without VAT intra community number $suggestedid = $return['suggestedid'];
$objp->code_sell_p = $objp->code_sell; } else {
$objp->aarowid_suggest = 0; // There is a doubt, no automatic binding $suggestedid = 0;
$suggestedaccountingaccountfor = 'eecwithoutvatnumber';
} elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale
$objp->code_sell_p = $objp->code_sell_intra;
$objp->aarowid_suggest = $objp->aarowid_intra;
$suggestedaccountingaccountfor = 'eec';
} else { // Foreign sale
$objp->code_sell_p = $objp->code_sell_export;
$objp->aarowid_suggest = $objp->aarowid_export;
$suggestedaccountingaccountfor = 'export';
} }
} }
if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { if ($suggestedid > 0) {
// Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding)
if (!empty($objp->company_code_sell)) {
$objp->code_sell_t = $objp->company_code_sell;
$objp->aarowid_suggest = $objp->aarowid_thirdparty;
$suggestedaccountingaccountfor = '';
}
}
// Manage Deposit
if (!empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT)) {
if ($objp->description == "(DEPOSIT)" || $objp->ftype == $facture_static::TYPE_DEPOSIT) {
$accountdeposittoventilated = new AccountingAccount($db);
$accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1);
$objp->code_sell_l = $accountdeposittoventilated->ref;
$objp->code_sell_p = '';
$objp->code_sell_t = '';
$objp->aarowid_suggest = $accountdeposittoventilated->rowid;
}
}
if ($objp->aarowid_suggest > 0) {
$sqlupdate = "UPDATE ".MAIN_DB_PREFIX."facturedet"; $sqlupdate = "UPDATE ".MAIN_DB_PREFIX."facturedet";
$sqlupdate .= " SET fk_code_ventilation = ".((int) $objp->aarowid_suggest); $sqlupdate .= " SET fk_code_ventilation = ".((int) $suggestedid);
$sqlupdate .= " WHERE fk_code_ventilation <= 0 AND product_type <= 2 AND rowid = ".((int) $objp->rowid); $sqlupdate .= " WHERE fk_code_ventilation <= 0 AND product_type <= 2 AND rowid = ".((int) $facture_static_det->id);
$resqlupdate = $db->query($sqlupdate); $resqlupdate = $db->query($sqlupdate);
if (!$resqlupdate) { if (!$resqlupdate) {
$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');
} }
} }
@ -272,21 +320,38 @@ print '</span><br>';
$y = $year_current; $y = $year_current;
$buttonbind = '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?year='.$year_current.'&action=validatehistory">'.$langs->trans("ValidateHistory").'</a>'; $buttonbind = '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=validatehistory&token='.newToken().'">'.$langs->trans("ValidateHistory").'</a>';
print_barre_liste($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);
//print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesNotBound"), $buttonbind, ''); //print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesNotBound"), $buttonbind, '');
print '<div class="div-table-responsive-no-min">'; print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">'; print '<table class="noborder centpercent">';
print '<tr class="liste_titre"><td class="minwidth100">'.$langs->trans("Account").'</td>'; print '<tr class="liste_titre"><td class="minwidth100">'.$langs->trans("Account").'</td>';
print '<td class="left">'.$langs->trans("Label").'</td>'; print '<td>'.$langs->trans("Label").'</td>';
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;
} }
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'];
print '<a href="'.DOL_URL_ROOT.'/accountancy/customer/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>';
@ -297,7 +362,7 @@ for ($i = 1; $i <= 12; $i++) {
if ($j > 12) { if ($j > 12) {
$j -= 12; $j -= 12;
} }
$sql .= " SUM(".$db->ifsql('MONTH(f.datef)='.$j, 'fd.total_ht', '0').") AS month".str_pad($j, 2, '0', STR_PAD_LEFT).","; $sql .= " SUM(".$db->ifsql("MONTH(f.datef)=".$j, "fd.total_ht", "0").") AS month".str_pad($j, 2, "0", STR_PAD_LEFT).",";
} }
$sql .= " SUM(fd.total_ht) as total"; $sql .= " SUM(fd.total_ht) as total";
$sql .= " FROM ".MAIN_DB_PREFIX."facturedet as fd"; $sql .= " FROM ".MAIN_DB_PREFIX."facturedet as fd";
@ -320,34 +385,49 @@ if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
} }
$sql .= " GROUP BY fd.fk_code_ventilation,aa.account_number,aa.label"; $sql .= " GROUP BY fd.fk_code_ventilation,aa.account_number,aa.label";
dol_syslog('htdocs/accountancy/customer/index.php sql='.$sql, LOG_DEBUG); dol_syslog('htdocs/accountancy/customer/index.php', LOG_DEBUG);
$resql = $db->query($sql); $resql = $db->query($sql);
if ($resql) { if ($resql) {
$num = $db->num_rows($resql); $num = $db->num_rows($resql);
while ($row = $db->fetch_row($resql)) { while ($row = $db->fetch_row($resql)) {
print '<tr class="oddeven"><td>'; print '<tr class="oddeven">';
print '<td>';
if ($row[0] == 'tobind') { if ($row[0] == 'tobind') {
print '<span class="opacitymedium">'.$langs->trans("Unknown").'</span>'; print '<span class="opacitymedium">'.$langs->trans("Unknown").'</span>';
} else { } else {
print length_accountg($row[0]); print length_accountg($row[0]);
} }
print '</td>'; print '</td>';
print '<td class="left">'; print '<td>';
if ($row[0] == 'tobind') { if ($row[0] == 'tobind') {
print $langs->trans("UseMenuToSetBindindManualy", DOL_URL_ROOT.'/accountancy/customer/list.php?search_year='.$y, $langs->transnoentitiesnoconv("ToBind")); print $langs->trans("UseMenuToSetBindindManualy", DOL_URL_ROOT.'/accountancy/customer/list.php?search_year='.((int) $y), $langs->transnoentitiesnoconv("ToBind"));
} else { } else {
print $row[1]; print $row[1];
} }
print '</td>'; print '</td>';
for ($i = 2; $i <= 12; $i++) { for ($i = 2; $i <= 13; $i++) {
print '<td class="right nowraponall amount">'.price($row[$i]).'</td>'; $cursormonth = (($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) + $i - 2);
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 class="right nowraponall amount">';
print price($row[$i]);
print '</td>';
} }
print '<td class="right nowraponall amount">'.price($row[13]).'</td>';
print '<td class="right nowraponall amount"><b>'.price($row[14]).'</b></td>'; print '<td class="right nowraponall amount"><b>'.price($row[14]).'</b></td>';
print '</tr>'; print '</tr>';
} }
$db->free($resql); $db->free($resql);
if ($num == 0) {
print '<tr class="oddeven"><td colspan="16">';
print '<span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span>';
print '</td></tr>';
}
} else { } else {
print $db->lasterror(); // Show last sql error print $db->lasterror(); // Show last sql error
} }
@ -358,19 +438,36 @@ print '</div>';
print '<br>'; print '<br>';
print_barre_liste($langs->trans("OverviewOfAmountOfLinesBound"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1); print_barre_liste(img_picto('', 'link', 'class="paddingright fa-color-unset"').$langs->trans("OverviewOfAmountOfLinesBound"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1);
//print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesBound"), '', ''); //print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesBound"), '', '');
print '<div class="div-table-responsive-no-min">'; print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">'; print '<table class="noborder centpercent">';
print '<tr class="liste_titre"><td class="minwidth100">'.$langs->trans("Account").'</td>'; print '<tr class="liste_titre"><td class="minwidth100">'.$langs->trans("Account").'</td>';
print '<td class="left">'.$langs->trans("Label").'</td>'; print '<td>'.$langs->trans("Label").'</td>';
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;
} }
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'];
print '<a href="'.DOL_URL_ROOT.'/accountancy/customer/lines.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>';
@ -381,7 +478,7 @@ for ($i = 1; $i <= 12; $i++) {
if ($j > 12) { if ($j > 12) {
$j -= 12; $j -= 12;
} }
$sql .= " SUM(".$db->ifsql('MONTH(f.datef)='.$j, 'fd.total_ht', '0').") AS month".str_pad($j, 2, '0', STR_PAD_LEFT).","; $sql .= " SUM(".$db->ifsql("MONTH(f.datef)=".$j, "fd.total_ht", "0").") AS month".str_pad($j, 2, "0", STR_PAD_LEFT).",";
} }
$sql .= " SUM(fd.total_ht) as total"; $sql .= " SUM(fd.total_ht) as total";
$sql .= " FROM ".MAIN_DB_PREFIX."facturedet as fd"; $sql .= " FROM ".MAIN_DB_PREFIX."facturedet as fd";
@ -410,7 +507,8 @@ if ($resql) {
$num = $db->num_rows($resql); $num = $db->num_rows($resql);
while ($row = $db->fetch_row($resql)) { while ($row = $db->fetch_row($resql)) {
print '<tr class="oddeven"><td>'; print '<tr class="oddeven">';
print '<td>';
if ($row[0] == 'tobind') { if ($row[0] == 'tobind') {
print $langs->trans("Unknown"); print $langs->trans("Unknown");
} else { } else {
@ -418,22 +516,36 @@ if ($resql) {
} }
print '</td>'; print '</td>';
print '<td class="left">'; print '<td>';
if ($row[0] == 'tobind') { if ($row[0] == 'tobind') {
print $langs->trans("UseMenuToSetBindindManualy", DOL_URL_ROOT.'/accountancy/customer/list.php?search_year='.$y, $langs->transnoentitiesnoconv("ToBind")); print $langs->trans("UseMenuToSetBindindManualy", DOL_URL_ROOT.'/accountancy/customer/list.php?search_year='.((int) $y), $langs->transnoentitiesnoconv("ToBind"));
} else { } else {
print $row[1]; print $row[1];
} }
print '</td>'; print '</td>';
for ($i = 2; $i <= 12; $i++) { for ($i = 2; $i <= 13; $i++) {
print '<td class="right nowraponall amount">'.price($row[$i]).'</td>'; $cursormonth = (($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) + $i - 2);
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 class="right nowraponall amount">';
print price($row[$i]);
print '</td>';
} }
print '<td class="right nowraponall amount">'.price($row[13]).'</td>';
print '<td class="right nowraponall amount"><b>'.price($row[14]).'</b></td>'; print '<td class="right nowraponall amount"><b>'.price($row[14]).'</b></td>';
print '</tr>'; print '</tr>';
} }
$db->free($resql); $db->free($resql);
if ($num == 0) {
print '<tr class="oddeven"><td colspan="16">';
print '<span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span>';
print '</td></tr>';
}
} else { } else {
print $db->lasterror(); // Show last sql error print $db->lasterror(); // Show last sql error
} }
@ -466,7 +578,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) { // This part of code looks strange
if ($j > 12) { if ($j > 12) {
$j -= 12; $j -= 12;
} }
$sql .= " SUM(".$db->ifsql('MONTH(f.datef)='.$j, 'fd.total_ht', '0').") AS month".str_pad($j, 2, '0', STR_PAD_LEFT).","; $sql .= " SUM(".$db->ifsql("MONTH(f.datef)=".$j, "fd.total_ht", "0").") AS month".str_pad($j, 2, "0", STR_PAD_LEFT).",";
} }
$sql .= " SUM(fd.total_ht) as total"; $sql .= " SUM(fd.total_ht) as total";
$sql .= " FROM ".MAIN_DB_PREFIX."facturedet as fd"; $sql .= " FROM ".MAIN_DB_PREFIX."facturedet as fd";
@ -526,16 +638,15 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) { // This part of code looks strange
if ($j > 12) { if ($j > 12) {
$j -= 12; $j -= 12;
} }
$sql .= ' $sql .= " SUM(".$db->ifsql("MONTH(f.datef)=".$j,
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))))",
$db->ifsql('fd.total_ht < 0', " (fd.total_ht - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100)))").")",
' (-1 * (abs(fd.total_ht) - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100))))', 0).") AS month".str_pad($j, 2, '0', STR_PAD_LEFT).",";
' (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";

View File

@ -191,7 +191,14 @@ print '<script type="text/javascript">
*/ */
$sql = "SELECT f.rowid as facid, f.ref as ref, f.type, f.datef, f.ref_client,"; $sql = "SELECT f.rowid as facid, f.ref as ref, f.type, f.datef, f.ref_client,";
$sql .= " fd.rowid, fd.description, fd.product_type as line_type, fd.total_ht, fd.total_tva, fd.tva_tx, fd.vat_src_code, fd.total_ttc,"; $sql .= " fd.rowid, fd.description, fd.product_type as line_type, fd.total_ht, fd.total_tva, fd.tva_tx, fd.vat_src_code, fd.total_ttc,";
$sql .= " s.rowid as socid, s.nom as name, s.code_compta, s.code_client,"; $sql .= " s.rowid as socid, s.nom as name, s.code_client,";
if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) {
$sql .= " spe.accountancy_code_customer as code_compta_client,";
$sql .= " spe.accountancy_code_supplier as code_compta_fournisseur,";
} else {
$sql .= " s.code_compta as code_compta_client,";
$sql .= " s.code_compta_fournisseur,";
}
$sql .= " p.rowid as product_id, p.fk_product_type as product_type, p.ref as product_ref, p.label as product_label,"; $sql .= " p.rowid as product_id, p.fk_product_type as product_type, p.ref as product_ref, p.label as product_label,";
if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) { if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
$sql .= " ppe.accountancy_code_sell, ppe.accountancy_code_sell_intra, ppe.accountancy_code_sell_export,"; $sql .= " ppe.accountancy_code_sell, ppe.accountancy_code_sell_intra, ppe.accountancy_code_sell_export,";
@ -201,7 +208,7 @@ if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
$sql .= " aa.rowid as fk_compte, aa.account_number, aa.label as label_account, aa.labelshort as labelshort_account,"; $sql .= " aa.rowid as fk_compte, aa.account_number, aa.label as label_account, aa.labelshort as labelshort_account,";
$sql .= " fd.situation_percent,"; $sql .= " fd.situation_percent,";
$sql .= " co.code as country_code, co.label as country,"; $sql .= " co.code as country_code, co.label as country,";
$sql .= " s.rowid as socid, s.nom as name, s.tva_intra, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta as code_compta_client, s.code_compta_fournisseur"; $sql .= " s.rowid as socid, s.nom as name, s.tva_intra, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur";
$parameters = array(); $parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
$sql .= $hookmanager->resPrint; $sql .= $hookmanager->resPrint;
@ -213,6 +220,9 @@ if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON aa.rowid = fd.fk_code_ventilation"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON aa.rowid = fd.fk_code_ventilation";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."facture as f ON f.rowid = fd.fk_facture"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."facture as f ON f.rowid = fd.fk_facture";
$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)) {
$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 .= " WHERE fd.fk_code_ventilation > 0"; $sql .= " WHERE fd.fk_code_ventilation > 0";
$sql .= " AND f.entity IN (".getEntity('invoice', 0).")"; // We don't share object for accountancy $sql .= " AND f.entity IN (".getEntity('invoice', 0).")"; // We don't share object for accountancy

View File

@ -2,7 +2,7 @@
/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com> /* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2021 Alexandre Spangaro <aspangaro@open-dsi.fr> * Copyright (C) 2013-2021 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-2021 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
* *
@ -45,6 +45,7 @@ $massaction = GETPOST('massaction', 'alpha');
$show_files = GETPOST('show_files', 'int'); $show_files = GETPOST('show_files', 'int');
$confirm = GETPOST('confirm', 'alpha'); $confirm = GETPOST('confirm', 'alpha');
$toselect = GETPOST('toselect', 'array'); $toselect = GETPOST('toselect', 'array');
$optioncss = GETPOST('optioncss', 'alpha');
// Select Box // Select Box
$mesCasesCochees = GETPOST('toselect', 'array'); $mesCasesCochees = GETPOST('toselect', 'array');
@ -96,6 +97,7 @@ if (!$sortorder) {
$hookmanager->initHooks(array('accountancycustomerlist')); $hookmanager->initHooks(array('accountancycustomerlist'));
$formaccounting = new FormAccounting($db); $formaccounting = new FormAccounting($db);
$accountingAccount = new AccountingAccount($db);
$chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version'); $chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version');
@ -188,12 +190,12 @@ 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/customer/list.php sql=".$sql, LOG_DEBUG); dol_syslog("accountancy/customer/list.php", LOG_DEBUG);
if ($db->query($sql)) { if ($db->query($sql)) {
$msg .= '<div><span style="color:green">'.$langs->trans("Lineofinvoice", $monId).' - '.$langs->trans("VentilatedinAccount").' : '.length_accountg($accountventilated->account_number).'</span></div>'; $msg .= '<div><span style="color:green">'.$langs->trans("Lineofinvoice").' '.$monId.' - '.$langs->trans("VentilatedinAccount").' : '.length_accountg($accountventilated->account_number).'</span></div>';
$ok++; $ok++;
} else { } else {
$msg .= '<div><span style="color:red">'.$langs->trans("ErrorDB").' : '.$langs->trans("Lineofinvoice", $monId).' - '.$langs->trans("NotVentilatedinAccount").' : '.length_accountg($accountventilated->account_number).'<br> <pre>'.$sql.'</pre></span></div>'; $msg .= '<div><span style="color:red">'.$langs->trans("ErrorDB").' : '.$langs->trans("Lineofinvoice").' '.$monId.' - '.$langs->trans("NotVentilatedinAccount").' : '.length_accountg($accountventilated->account_number).'<br> <pre>'.$sql.'</pre></span></div>';
$ko++; $ko++;
} }
} }
@ -238,10 +240,14 @@ if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
$sql .= " p.tosell as status, p.tobuy as status_buy,"; $sql .= " p.tosell as status, p.tobuy as status_buy,";
$sql .= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export, aa4.rowid as aarowid_thirdparty,"; $sql .= " aa.rowid as aarowid, aa2.rowid as aarowid_intra, aa3.rowid as aarowid_export, aa4.rowid as aarowid_thirdparty,";
$sql .= " co.code as country_code, co.label as country_label,"; $sql .= " co.code as country_code, co.label as country_label,";
$sql .= " s.rowid as socid, s.nom as name, s.tva_intra, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta as code_compta_client, s.code_compta_fournisseur,"; $sql .= " s.rowid as socid, s.nom as name, s.tva_intra, s.email, s.town, s.zip, s.fk_pays, s.client, s.fournisseur, s.code_client, s.code_fournisseur,";
if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) {
$sql .= " spe.accountancy_code_customer as code_compta_client,";
$sql .= " spe.accountancy_code_supplier as code_compta_fournisseur,";
$sql .= " spe.accountancy_code_sell as company_code_sell"; $sql .= " spe.accountancy_code_sell as company_code_sell";
} else { } else {
$sql .= " s.code_compta as code_compta_client,";
$sql .= " s.code_compta_fournisseur,";
$sql .= " s.accountancy_code_sell as company_code_sell"; $sql .= " s.accountancy_code_sell as company_code_sell";
} }
$parameters = array(); $parameters = array();
@ -407,6 +413,9 @@ if ($result) {
if ($search_ref) { if ($search_ref) {
$param .= '&search_ref='.urlencode($search_ref); $param .= '&search_ref='.urlencode($search_ref);
} }
if ($search_label) {
$param .= '&search_label='.urlencode($search_label);
}
if ($search_desc) { if ($search_desc) {
$param .= '&search_desc='.urlencode($search_desc); $param .= '&search_desc='.urlencode($search_desc);
} }
@ -469,7 +478,6 @@ if ($result) {
print '</div>'; print '</div>';
print '</td>'; print '</td>';
print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_ref" value="'.dol_escape_htmltag($search_ref).'"></td>'; print '<td class="liste_titre"><input type="text" class="flat maxwidth50" name="search_ref" value="'.dol_escape_htmltag($search_ref).'"></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 maxwidth100" name="search_desc" value="'.dol_escape_htmltag($search_desc).'"></td>'; print '<td class="liste_titre"><input type="text" class="flat maxwidth100" name="search_desc" value="'.dol_escape_htmltag($search_desc).'"></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="flat maxwidth50 right" 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_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>';
@ -485,7 +493,7 @@ if ($result) {
$searchpicto = $form->showFilterButtons(); $searchpicto = $form->showFilterButtons();
print $searchpicto; print $searchpicto;
print '</td>'; print '</td>';
print '</tr>'; print "</tr>\n";
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);
@ -510,28 +518,35 @@ if ($result) {
$thirdpartystatic = new Societe($db); $thirdpartystatic = new Societe($db);
$facture_static = new Facture($db); $facture_static = new Facture($db);
$facture_static_det = new FactureLigne($db);
$product_static = new Product($db); $product_static = new Product($db);
$isSellerInEEC = isInEEC($mysoc);
$accountingaccount_codetotid_cache = array(); $accountingaccount_codetotid_cache = array();
while ($i < min($num_lines, $limit)) { while ($i < min($num_lines, $limit)) {
$objp = $db->fetch_object($result); $objp = $db->fetch_object($result);
$objp->code_sell_l = ''; // product_type: 0 = service, 1 = product
$objp->code_sell_p = ''; // if product does not exist we use the value of product_type provided in facturedet to define if this is a product or service
// issue : if we change product_type value in product DB it should differ from the value stored in facturedet DB !
$code_sell_l = '';
$code_sell_p = '';
$code_sell_t = '';
$thirdpartystatic->id = $objp->socid; $thirdpartystatic->id = $objp->socid;
$thirdpartystatic->name = $objp->name; $thirdpartystatic->name = $objp->name;
$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->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;
@ -545,150 +560,86 @@ if ($result) {
$product_static->accountancy_code_buy = $objp->code_buy; $product_static->accountancy_code_buy = $objp->code_buy;
$product_static->accountancy_code_buy_intra = $objp->code_buy_intra; $product_static->accountancy_code_buy_intra = $objp->code_buy_intra;
$product_static->accountancy_code_buy_export = $objp->code_buy_export; $product_static->accountancy_code_buy_export = $objp->code_buy_export;
$product_static->tva_tx = $objp->tva_tx_prod;
$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->date = $db->jdate($objp->datef);
$facture_static_det->id = $objp->rowid;
$facture_static_det->total_ht = $objp->total_ht;
$facture_static_det->tva_tx = $objp->tva_tx_line;
$facture_static_det->vat_src_code = $objp->vat_src_code;
$facture_static_det->product_type = $objp->type_l;
$facture_static_det->desc = $objp->description;
$accountingAccountArray = array(
'dom'=>$objp->aarowid,
'intra'=>$objp->aarowid_intra,
'export'=>$objp->aarowid_export,
'thirdparty' =>$objp->aarowid_thirdparty);
$code_sell_p_notset = ''; $code_sell_p_notset = '';
$code_sell_t_notset = ''; $code_sell_t_notset = '';
$objp->aarowid_suggest = ''; // Will be set later
$isBuyerInEEC = isInEEC($objp); $suggestedid = 0;
// Level 1: Search suggested default account for product/service $return=$accountingAccount->getAccountingCodeToBind($thirdpartystatic, $mysoc, $product_static, $facture_static, $facture_static_det, $accountingAccountArray, 'customer');
$suggestedaccountingaccountbydefaultfor = ''; if (!is_array($return) && $return<0) {
if ($objp->type_l == 1) { setEventMessage($accountingAccount->error, 'errors');
if ($objp->country_code == $mysoc->country_code || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country)
$objp->code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : '');
$suggestedaccountingaccountbydefaultfor = '';
} else { } else {
if ($isSellerInEEC && $isBuyerInEEC && $objp->tva_tx_line != 0) { // European intravat sale, but with a VAT $suggestedid=$return['suggestedid'];
$objp->code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : ''); $suggestedaccountingaccountfor=$return['suggestedaccountingaccountfor'];
$suggestedaccountingaccountbydefaultfor = 'eecwithvat'; $suggestedaccountingaccountbydefaultfor=$return['suggestedaccountingaccountbydefaultfor'];
} elseif ($isSellerInEEC && $isBuyerInEEC && empty($objp->tva_intra)) { // European intravat sale, without VAT intra community number $code_sell_l=$return['code_l'];
$objp->code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : ''); $code_sell_p=$return['code_p'];
$suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber'; $code_sell_t=$return['code_t'];
} elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale
$objp->code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT : '');
$suggestedaccountingaccountbydefaultfor = 'eec';
} else { // Foreign sale
$objp->code_sell_l = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT : '');
$suggestedaccountingaccountbydefaultfor = 'export';
}
}
} elseif ($objp->type_l == 0) {
if ($objp->country_code == $mysoc->country_code || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country)
$objp->code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : '');
$suggestedaccountingaccountbydefaultfor = '';
} else {
if ($isSellerInEEC && $isBuyerInEEC && $objp->tva_tx_line != 0) { // European intravat sale, but with a VAT
$objp->code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : '');
$suggestedaccountingaccountbydefaultfor = 'eecwithvat';
} elseif ($isSellerInEEC && $isBuyerInEEC && empty($objp->tva_intra)) { // European intravat sale, without VAT intra community number
$objp->code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : '');
$suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber';
} elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale
$objp->code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT : '');
$suggestedaccountingaccountbydefaultfor = 'eec';
} else {
$objp->code_sell_l = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT : '');
$suggestedaccountingaccountbydefaultfor = 'export';
}
}
}
if ($objp->code_sell_l == -1) {
$objp->code_sell_l = '';
} }
//var_dump($return);
// Level 2: Search suggested account for product/service (similar code exists in page index.php to make automatic binding) if (!empty($code_sell_p)) {
$suggestedaccountingaccountfor = '';
if (($objp->country_code == $mysoc->country_code) || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country)
$objp->code_sell_p = $objp->code_sell;
$objp->aarowid_suggest = $objp->aarowid;
$suggestedaccountingaccountfor = '';
} else {
if ($isSellerInEEC && $isBuyerInEEC && $objp->tva_tx_line != 0) { // European intravat sale, but with VAT
$objp->code_sell_p = $objp->code_sell;
$objp->aarowid_suggest = $objp->aarowid;
$suggestedaccountingaccountfor = 'eecwithvat';
} elseif ($isSellerInEEC && $isBuyerInEEC && empty($objp->tva_intra)) { // European intravat sale, without VAT intra community number
$objp->code_sell_p = $objp->code_sell;
$objp->aarowid_suggest = $objp->aarowid; // There is a doubt for this case. Is it an error on vat or we just forgot to fill vat number ?
$suggestedaccountingaccountfor = 'eecwithoutvatnumber';
} elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale
$objp->code_sell_p = $objp->code_sell_intra;
$objp->aarowid_suggest = $objp->aarowid_intra;
$suggestedaccountingaccountfor = 'eec';
} else { // Foreign sale
$objp->code_sell_p = $objp->code_sell_export;
$objp->aarowid_suggest = $objp->aarowid_export;
$suggestedaccountingaccountfor = 'export';
}
}
// Level 3: 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($objp->company_code_sell)) {
$objp->code_sell_t = $objp->company_code_sell;
$objp->aarowid_suggest = $objp->aarowid_thirdparty;
$suggestedaccountingaccountfor = '';
}
}
// Manage Deposit
if (!empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT)) {
if ($objp->description == "(DEPOSIT)" || $objp->ftype == $facture_static::TYPE_DEPOSIT) {
$accountdeposittoventilated = new AccountingAccount($db);
$accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1);
$objp->code_sell_l = $accountdeposittoventilated->ref;
$objp->code_sell_p = '';
$objp->code_sell_t = '';
$objp->aarowid_suggest = $accountdeposittoventilated->rowid;
}
}
if (!empty($objp->code_sell_p)) {
// Value was defined previously // Value was defined previously
} else { } else {
$code_sell_p_notset = 'color:orange'; $code_sell_p_notset = 'color:orange';
} }
if (empty($objp->code_sell_l) && empty($objp->code_sell_p)) { if (empty($code_sell_l) && empty($code_sell_p)) {
$code_sell_p_notset = 'color:red'; $code_sell_p_notset = 'color:red';
} }
if ($suggestedaccountingaccountfor == 'eecwithoutvatnumber' && empty($code_sell_p_notset)) { if ($suggestedaccountingaccountfor == 'eecwithoutvatnumber' && empty($code_sell_p_notset)) {
$code_sell_p_notset = 'color:orange'; $code_sell_p_notset = 'color:orange';
} }
// $objp->code_sell_l is now default code of product/service // $code_sell_l is now default code of product/service
// $objp->code_sell_p is now code of product/service // $code_sell_p is now code of product/service
// $objp->code_sell_t is now code of thirdparty // $code_sell_t is now code of thirdparty
//var_dump($code_sell_l.' - '.$code_sell_p.' - '.$code_sell_t.' -> '.$suggestedid.' ('.$suggestedaccountingaccountbydefaultfor.' '.$suggestedaccountingaccountfor.')');
print '<tr class="oddeven">'; print '<tr class="oddeven">';
// Line id // Line id
print '<td>'.$objp->rowid.'</td>'; print '<td>'.$facture_static_det->id.'</td>';
// Ref Invoice // Ref Invoice
print '<td class="nowraponall">'.$facture_static->getNomUrl(1).'</td>'; print '<td class="nowraponall">'.$facture_static->getNomUrl(1).'</td>';
print '<td class="center">'.dol_print_date($db->jdate($objp->datef), 'day').'</td>'; print '<td class="center">'.dol_print_date($facture_static->date, 'day').'</td>';
// Ref Product // Ref Product
print '<td class="tdoverflowmax150">'; print '<td class="tdoverflowmax150">';
if ($product_static->id > 0) { if ($product_static->id > 0) {
print $product_static->getNomUrl(1); print $product_static->getNomUrl(1);
} }
if ($objp->product_label) { if ($product_static->label) {
print '<br><span class="opacitymedium small">'.$objp->product_label.'</span>'; print '<br><span class="opacitymedium small">'.$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($objp->description)); $text = dolGetFirstLineOfText(dol_string_nohtmltag($facture_static_det->desc));
$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), $facture_static_det->desc);
print '</td>'; print '</td>';
print '<td class="right nowraponall amount">'; print '<td class="right nowraponall amount">';
@ -696,11 +647,12 @@ if ($result) {
print '</td>'; print '</td>';
// Vat rate // Vat rate
if ($objp->vat_tx_l != $objp->vat_tx_p) { $code_vat_differ = '';
$code_vat_differ = 'font-weight:bold; text-decoration:blink; color:red'; if ($product_static->tva_tx !== $facture_static_det->tva_tx && price2num($product_static->tva_tx) && price2num($facture_static_det->tva_tx)) { // Note: having a vat rate of 0 is often the normal case when sells is intra b2b or to export
$code_vat_differ = 'warning bold';
} }
print '<td style="'.$code_vat_differ.'" class="right">'; print '<td class="right'.($code_vat_differ?' '.$code_vat_differ:'').'">';
print vatrate($objp->tva_tx_line.($objp->vat_src_code ? ' ('.$objp->vat_src_code.')' : '')); print vatrate($facture_static_det->tva_tx.($facture_static_det->vat_src_code ? ' ('.$facture_static_det->vat_src_code.')' : ''));
print '</td>'; print '</td>';
// Thirdparty // Thirdparty
@ -717,18 +669,18 @@ if ($result) {
// Found accounts // Found accounts
print '<td class="small">'; print '<td class="small">';
$s = '1. '.(($objp->type_l == 1) ? $langs->trans("DefaultForService") : $langs->trans("DefaultForProduct")).': '; $s = '1. '.(($facture_static_det->product_type == 1) ? $langs->trans("DefaultForService") : $langs->trans("DefaultForProduct")).': ';
$shelp = ''; $shelp = '';
if ($suggestedaccountingaccountbydefaultfor == 'eec') { if ($suggestedaccountingaccountbydefaultfor == 'eec') {
$shelp .= $langs->trans("SaleEEC"); $shelp .= $langs->trans("SaleEEC");
} elseif ($suggestedaccountingaccountbydefaultfor == 'export') { } elseif ($suggestedaccountingaccountbydefaultfor == 'export') {
$shelp .= $langs->trans("SaleExport"); $shelp .= $langs->trans("SaleExport");
} }
$s .= ($objp->code_sell_l > 0 ? length_accountg($objp->code_sell_l) : '<span style="'.$code_sell_p_notset.'">'.$langs->trans("NotDefined").'</span>'); $s .= ($code_sell_l > 0 ? length_accountg($code_sell_l) : '<span style="'.$code_sell_p_notset.'">'.$langs->trans("NotDefined").'</span>');
print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
if ($objp->product_id > 0) { if ($product_static->id > 0) {
print '<br>'; print '<br>';
$s = '2. '.(($objp->type_l == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': '; $s = '2. '.(($facture_static_det->product_type == 1) ? $langs->trans("ThisService") : $langs->trans("ThisProduct")).': ';
$shelp = ''; $ttype = 'help'; $shelp = ''; $ttype = 'help';
if ($suggestedaccountingaccountfor == 'eec') { if ($suggestedaccountingaccountfor == 'eec') {
$shelp = $langs->trans("SaleEEC"); $shelp = $langs->trans("SaleEEC");
@ -740,7 +692,7 @@ if ($result) {
} elseif ($suggestedaccountingaccountfor == 'export') { } elseif ($suggestedaccountingaccountfor == 'export') {
$shelp = $langs->trans("SaleExport"); $shelp = $langs->trans("SaleExport");
} }
$s .= (empty($objp->code_sell_p) ? '<span style="'.$code_sell_p_notset.'">'.$langs->trans("NotDefined").'</span>' : length_accountg($objp->code_sell_p)); $s .= (empty($code_sell_p) ? '<span style="'.$code_sell_p_notset.'">'.$langs->trans("NotDefined").'</span>' : length_accountg($code_sell_p));
print $form->textwithpicto($s, $shelp, 1, $ttype, '', 0, 2, '', 1); print $form->textwithpicto($s, $shelp, 1, $ttype, '', 0, 2, '', 1);
} else { } else {
print '<br>'; print '<br>';
@ -751,38 +703,25 @@ if ($result) {
} }
if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) {
print '<br>'; print '<br>';
$s = '3. '.(($objp->type_l == 1) ? $langs->trans("ServiceForThisThirdparty") : $langs->trans("ProductForThisThirdparty")).': '; $s = '3. '.(($facture_static_det->product_type == 1) ? $langs->trans("ServiceForThisThirdparty") : $langs->trans("ProductForThisThirdparty")).': ';
$shelp = ''; $shelp = '';
$s .= ($objp->code_sell_t > 0 ? length_accountg($objp->code_sell_t) : '<span style="'.$code_sell_t_notset.'">'.$langs->trans("NotDefined").'</span>'); $s .= ($code_sell_t > 0 ? length_accountg($code_sell_t) : '<span style="'.$code_sell_t_notset.'">'.$langs->trans("NotDefined").'</span>');
print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1); print $form->textwithpicto($s, $shelp, 1, 'help', '', 0, 2, '', 1);
} }
print '</td>'; print '</td>';
// Suggested accounting account // Suggested accounting account
print '<td>'; print '<td>';
$suggestedid = $objp->aarowid_suggest; print $formaccounting->select_account($suggestedid, 'codeventil'.$facture_static_det->id, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone');
if (empty($suggestedid) && empty($objp->code_sell_p) && !empty($objp->code_sell_l) && empty($conf->global->ACCOUNTANCY_DO_NOT_AUTOFILL_ACCOUNT_WITH_GENERIC)) {
if (empty($accountingaccount_codetotid_cache[$objp->code_sell_l])) {
$tmpaccount = new AccountingAccount($db);
$tmpaccount->fetch(0, $objp->code_sell_l, 1);
if ($tmpaccount->id > 0) {
$suggestedid = $tmpaccount->id;
}
$accountingaccount_codetotid_cache[$objp->code_sell_l] = $tmpaccount->id;
} else {
$suggestedid = $accountingaccount_codetotid_cache[$objp->code_sell_l];
}
}
print $formaccounting->select_account($suggestedid, 'codeventil'.$objp->rowid, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone');
print '</td>'; print '</td>';
// Column with checkbox // Column with checkbox
print '<td class="center">'; print '<td class="center">';
$ischecked = $objp->aarowid_suggest;
if ($suggestedaccountingaccountfor == 'eecwithoutvatnumber') {
$ischecked = 0; $ischecked = 0;
if (!empty($suggestedid) && $suggestedaccountingaccountfor != '' && $suggestedaccountingaccountfor != 'eecwithoutvatnumber') {
$ischecked = 1;
} }
print '<input type="checkbox" class="flat checkforselect checkforselect'.$objp->rowid.'" name="toselect[]" value="'.$objp->rowid."_".$i.'"'.($ischecked ? "checked" : "").'/>'; print '<input type="checkbox" class="flat checkforselect checkforselect'.$facture_static_det->id.'" name="toselect[]" value="'.$facture_static_det->id."_".$i.'"'.($ischecked ? " checked" : "").'/>';
print '</td>'; print '</td>';
print '</tr>'; print '</tr>';
@ -800,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

@ -110,7 +110,7 @@ if (!empty($id)) {
$sql .= " WHERE er.fk_statut > 0 AND erd.rowid = ".((int) $id); $sql .= " WHERE er.fk_statut > 0 AND erd.rowid = ".((int) $id);
$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
dol_syslog("/accounting/expensereport/card.php sql=".$sql, LOG_DEBUG); dol_syslog("/accounting/expensereport/card.php", LOG_DEBUG);
$result = $db->query($sql); $result = $db->query($sql);
if ($result) { if ($result) {

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