Merge branch 'develop' of github.com:Dolibarr/dolibarr into develop_of_consumption_selectbatch

This commit is contained in:
atm-lena 2022-09-12 13:42:21 +02:00
commit 7b7e0437a0
4768 changed files with 259181 additions and 83448 deletions

6
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

View File

@ -5,11 +5,14 @@ on:
schedule:
- cron: "0 20 * * *"
permissions:
contents: read
jobs:
exakat:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Exakat
uses: docker://exakat/exakat-ga
with:

View File

@ -6,9 +6,13 @@ on:
- cron: "0 21 * * *"
issue_comment:
types: [created]
permissions: {} # none
jobs:
stale:
permissions:
issues: write
runs-on: ubuntu-latest
steps:
- uses: Dolibarr/stale@staleunstale
@ -21,4 +25,4 @@ jobs:
days-before-close: 10
operations-per-run: 100
dry-run: false

3
.gitignore vendored
View File

@ -42,6 +42,8 @@ htdocs/includes/sebastian/
htdocs/includes/squizlabs/
htdocs/includes/webmozart/
htdocs/.well-known/apple-developer-merchantid-domain-association
/factory/
/output/
# Node Modules
build/yarn-error.log
@ -55,4 +57,3 @@ yarn.lock
package-lock.json
doc/install.lock
/factory/

View File

@ -18,9 +18,10 @@ filter:
- dev/*
- doc/*
- documents/*
- htdocs/includes/*
- node_modules/*
- test/*
dependency_paths:
- htdocs/includes/*
paths:
- htdocs/*
- scripts/*

View File

@ -54,11 +54,11 @@ jobs:
env: DB=mysql
- stage: PHP Dev
if: type = push AND branch = develop
php: nightly
php: nightly
env: DB=mysql
- stage: PHP Dev
if: type = push AND branch = 15.0
php: nightly
php: nightly
env: DB=mysql
notifications:
@ -93,23 +93,26 @@ install:
echo
- |
echo "Installing Composer dependencies - PHP Unit, Parallel Lint, PHP CodeSniffer - for $TRAVIS_PHP_VERSION"
echo "Installing Composer dependencies - PHP Unit, Parallel Lint, PHP CodeSniffer, PHP Vardump check - for $TRAVIS_PHP_VERSION"
if [ "$TRAVIS_PHP_VERSION" = '5.6' ]; then
composer -n require phpunit/phpunit ^5 \
php-parallel-lint/php-parallel-lint ^1 \
php-parallel-lint/php-console-highlighter ^0 \
php-parallel-lint/php-var-dump-check ~0.4 \
squizlabs/php_codesniffer ^3
fi
if [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] || [ "$TRAVIS_PHP_VERSION" = '7.2' ]; then
composer -n require phpunit/phpunit ^6 \
php-parallel-lint/php-parallel-lint ^1 \
php-parallel-lint/php-console-highlighter ^0 \
php-parallel-lint/php-var-dump-check ~0.4 \
squizlabs/php_codesniffer ^3
fi
if [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ] || [ "$TRAVIS_PHP_VERSION" = '7.4.22' ]; then
composer -n require phpunit/phpunit ^7 \
php-parallel-lint/php-parallel-lint ^1.2 \
php-parallel-lint/php-console-highlighter ^0 \
php-parallel-lint/php-var-dump-check ~0.4 \
squizlabs/php_codesniffer ^3
fi
# phpunit 9 is required for php 8
@ -117,6 +120,7 @@ install:
composer -n require --ignore-platform-reqs phpunit/phpunit ^7 \
php-parallel-lint/php-parallel-lint ^1.2 \
php-parallel-lint/php-console-highlighter ^0 \
php-parallel-lint/php-var-dump-check ~0.4 \
squizlabs/php_codesniffer ^3
fi
echo
@ -166,6 +170,10 @@ before_script:
which phpcs
phpcs --version | head -
phpcs -i | head -
# Check PHP Vardump check version
echo "PHP Vardump check version"
which var_dump_check
var_dump_check --version
# Check PHPUnit version
echo "PHPUnit version"
which phpunit
@ -281,7 +289,7 @@ script:
--exclude htdocs/includes/sabre --exclude htdocs/includes/phpoffice/PhpSpreadsheet --exclude htdocs/includes/sebastian \
--exclude htdocs/includes/squizlabs/php_codesniffer --exclude htdocs/includes/jakub-onderka --exclude htdocs/includes/php-parallel-lint --exclude htdocs/includes/symfony \
--exclude htdocs/includes/mike42/escpos-php/example --exclude htdocs/includes/maximebf \
--exclude htdocs/includes/phpunit/ --exclude htdocs/includes/tecnickcom/tcpdf/include/barcodes --exclude htdocs/includes/webmozart --blame .
--exclude htdocs/includes/phpunit/ --exclude htdocs/includes/tecnickcom/tcpdf/include/barcodes --exclude htdocs/includes/webmozart --exclude htdocs/includes/webklex --blame .
fi
set +e
echo
@ -297,6 +305,17 @@ script:
set +e
echo
- |
echo "Checking missing debug"
# Ensure we catch errors
set -e
# Exclusions are defined in the ruleset.xml file
if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_PHP_VERSION" = "7.4.22" ]; then
var-dump-check --extensions php --tracy --exclude htdocs/includes --exclude test/ --exclude htdocs/public/test/ --exclude htdocs/core/lib/functions.lib.php .
fi
set +e
echo
- |
export INSTALL_FORCED_FILE=htdocs/install/install.forced.php
echo "Setting up Dolibarr $INSTALL_FORCED_FILE to test installation"
@ -417,6 +436,9 @@ script:
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
php upgrade.php 16.0.0 17.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade16001700.log
php upgrade2.php 16.0.0 17.0.0 > $TRAVIS_BUILD_DIR/upgrade16001700-2.log
php step5.php 16.0.0 17.0.0 > $TRAVIS_BUILD_DIR/upgrade16001700-3.log
ls -alrt $TRAVIS_BUILD_DIR/
- |

View File

@ -98,6 +98,12 @@ source_file = htdocs/langs/en_US/cron.lang
source_lang = en_US
type = MOZILLAPROPERTIES
[dolibarr.datapolicy]
file_filter = htdocs/langs/<lang>/datapolicy.lang
source_file = htdocs/langs/en_US/datapolicy.lang
source_lang = en_US
type = MOZILLAPROPERTIES
[dolibarr.deliveries]
file_filter = htdocs/langs/<lang>/deliveries.lang
source_file = htdocs/langs/en_US/deliveries.lang
@ -140,18 +146,6 @@ source_file = htdocs/langs/en_US/exports.lang
source_lang = en_US
type = MOZILLAPROPERTIES
[dolibarr.externalsite]
file_filter = htdocs/langs/<lang>/externalsite.lang
source_file = htdocs/langs/en_US/externalsite.lang
source_lang = en_US
type = MOZILLAPROPERTIES
[dolibarr.ftp]
file_filter = htdocs/langs/<lang>/ftp.lang
source_file = htdocs/langs/en_US/ftp.lang
source_lang = en_US
type = MOZILLAPROPERTIES
[dolibarr.help]
file_filter = htdocs/langs/<lang>/help.lang
source_file = htdocs/langs/en_US/help.lang

View File

@ -24,7 +24,6 @@ Component Version License GPL Compatible
-------------------------------------------------------------------------------------
PHP libraries:
ADOdb-Date 0.36 Modified BSD License Yes Date convertion (not into rpm package)
CKEditor 4.12.1 LGPL-2.1+ Yes Editor WYSIWYG
EvalMath 1.0 BSD Yes Safe math expressions evaluation
Escpos-php 2.2 MIT License Yes Thermal receipt printer library, for use with ESC/POS compatible printers
GeoIP2 0.2.0 Apache License 2.0 Yes Lib to make geoip convert
@ -34,15 +33,17 @@ PEAR Mail_MIME 1.8.9 BSD Yes
ParseDown 1.6 MIT License Yes Markdown parser
PCLZip 2.8.4 LGPL-3+ Yes Library to zip/unzip files
PHPDebugBar 1.15.1 MIT License Yes Used only by the module "debugbar" for developers
PHP-Imap 2.7.2 MIT License Yes Library to use IMAP with OAuth
PHPSpreadSheet 1.8.2 LGPL-2.1+ Yes Read/Write XLS files, read ODS files
php-iban 1.4.7 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP
php-iban 4.1 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP
PHPoAuthLib 0.8.2 MIT License Yes Library to provide oauth1 and oauth2 to different service
PHPPrintIPP 1.3 GPL-2+ Yes Library to send print IPP requests
PSR/Logs 1.0 Library for logs (used by DebugBar)
PSR/Logs 1.0 MIT License Yes Library for logs (used by DebugBar)
PSR/simple-cache ? MIT License Yes Library for cache (used by PHPSpreadSheet)
Restler 3.1.1 LGPL-3+ Yes Library to develop REST Web services (+ swagger-ui js lib into dir explorer)
Sabre 3.2.2 BSD Yes DAV support
Swift Mailer 5.4.2-DEV MIT License Yes Comprehensive mailing tools for PHP
Symfony/var-dumper ??? MIT License Yes Library to make var dump (used by DebugBar)
Stripe 7.67.0 MIT Licence Yes Library for Stripe module
TCPDF 6.3.2 LGPL-3+ Yes PDF generation
TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes FPDI replacement
@ -50,8 +51,9 @@ TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes
JS libraries:
Ace 1.4.14 BSD Yes JS library to get code syntaxique coloration in a textarea.
ChartJS 3.7.1 MIT License Yes JS library for graph
CKEditor 4.18 LGPL-2.1+ Yes Editor WYSIWYG
jQuery 3.6.0 MIT License Yes JS library
jQuery UI 1.13.1 GPL and MIT License Yes JS library plugin UI
jQuery UI 1.13.2 GPL and MIT License Yes JS library plugin UI
jQuery select2 4.0.13 GPL and Apache License Yes JS library plugin for sexier multiselect. Warning: 4.0.6+ create troubles without patching css
jQuery blockUI 2.70.0 GPL and MIT License Yes JS library plugin blockUI (to use ajax popups)
jQuery Colorpicker 1.1 MIT License Yes JS library for color picker for a defined list of colors

451
ChangeLog
View File

@ -2,6 +2,25 @@
English Dolibarr ChangeLog
--------------------------------------------------------------
***** ChangeLog for 17.0.0 compared to 16.0.0 *****
For users:
---------------
...
For developers or integrators:
------------------------------
...
WARNING:
Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
* The signature of method getNomUrl() of class ProductFournisseur has been modified to match the signature of method Product
* Trigger ORDER_SUPPLIER_DISPATCH is removed, use ORDER_SUPPLIER_RECEIVE and/or LINEORDER_SUPPLIER_DISPATCH instead.
***** ChangeLog for 16.0.0 compared to 15.0.0 *****
@ -9,31 +28,378 @@ English Dolibarr ChangeLog
For users:
---------------
NEW: PHP 8.0 compatibility
NEW: PHP 8.1 compatibility:
Warning!! Application works correctly with PHP8 and 8.1 but you will experience a lot of PHP warnings into the PHP server
log files (depending on your PHP setup). Removal of all PHP warnings on server side is planned for v17.
NEW: Support for recurring purchase invoices.
NEW: #20292 Include German public holidays
NEW: Can show ZATCA QR-Code on PDFs
NEW: Can show Swiss QR-Code on PDFs
NEW: #17123 added ExtraFields for Stock Mouvement
NEW: #20609 new massaction to assign a sale representatives on a selection of thirdparties
NEW: #20653 edit discount pourcentage for all lines in one shot
NEW: Accept 'auto' for ref of object on import of purchase order/proposal
NEW: Accountancy - Add more filters and info on page to bind accounting accounts
NEW: Accountancy - Add subledger account when generate a transaction with a deposit invoice
NEW: Accountancy - Add a massaction to preselect an account (customer and supplier list)
NEW: Accountancy - Add hidden feature for accounting reconciliation
NEW: ACE Editor is restored at same cursor position after a save.
NEW: Add "addMoreActionsButtons" hook to subscription form
NEW: Add an option in GUI to show a Quick add button into top menu bar
NEW: Add a workflow to auto link contract on a ticket
NEW: Add column date of Signature on proposal list
NEW: Add column template invoice in invoice list
NEW: Add column "Total HT" to products array on document creation card
NEW: Add configuration for text color of button action
NEW: Add entity filter in exports
NEW: Show the event block on recurring invoices #20870
NEW: Add filter "opportunity status" on statistics of projects.
NEW: Add firstname, lastname and max number of attendees for module "Event Organization"
NEW: Add margin info in proposal and order list
NEW: Add massaction "Edit Extrafield" for Product
NEW: Add more fields to detect duplicate during import of thirdparties
NEW: Add option to foce delivery on email for purchase order receipt to yes
NEW: Add param border table for md theme
NEW: Add param color button action
NEW: Add possibility to create contract from invoice
NEW: Add possibility with constant MAIN_LOGIN_BADCHARUNAUTHORIZED to define bad character unauthorized into login name
NEW: Add private and public notes on tax files.
NEW: Add substitutions "user numbers"
NEW: allow a ticket to be automatically marked as read when created from backend.
NEW: allow cut&paste as real numeric value to excel
NEW: A public form to send a message and create a lead is available
NEW: automatically set totally received status in reception
NEW: Auto set invoice paid when adding credit not and remain to pay is 0
NEW: Can change value of AWP during the inventory
NEW: Can enter price with tax for predefined products on purchase objects
NEW: Can filter on a thirdparty on product statistics
NEW: Can removed doc templates from setup page of thirdparty
NEW: Can use ! to make a search that exclude a string
NEW: Change in theme colors does not need to use the refresh button
NEW: clean values and amount in FEC import
NEW: const MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND for mailing mass action
NEW: Contact filter project list
NEW: Create contract from invoice
NEW: Database: Can store the session into database (instead of beeing managed by PHP)
NEW: Database: Some core tables are created only at module activation
NEW: Default value for MAIN_SECURITY_CSRF_WITH_TOKEN is now 2 (GET are also protected agains CSRF attacks)
NEW: deposit payment terms: add field into dictionary admin page to define default percentage of deposit.
NEW: Dictionaries - add possibility to manage countries in EEC
NEW: Dictionaries - Availibility dictionnary has a new column unit and number
NEW: Display errors in a message box after generating documents
NEW: Enhance the import. Can use 'auto' for the ref (import of orders)
NEW: Events on Proposal to Return to Draft
NEW: Page to list expense report payments
NEW: JS inventory autocalc input
NEW: language support for more emailing target selectors
NEW: leave requests: add field into type dictionary to block request if balance is negative
NEW: Mass action "Close shipments"
NEW: Module BOM - Add tabs for nets Bom
NEW: Module BOM - Add the possibility to add sub-BOMs to BOM
NEW: Module Recruitment - Add a public page with list of all open job positions.
NEW: Module Recruitment - Add a tab with list of application on the jobposition file.
NEW: More mode for THEME_TOPMENU_DISABLE_IMAGE (2, 3, ...)
NEW: Add option to move checkbox column as first column on Thirdparty list (only few screens)
NEW: payment conditions enabling semi-automatic deposit creation (Issue #18439)
NEW: possibility to consume multiple batch
NEW: Reverse movement product consumption
NEW: Send email to the supplier order contact
NEW: add permission to report time on timesheet
NEW: Knowledge Management - Add status "Obsolete" to KM articles
NEW: MRP - split consumption line on MO
NEW: MRP - Display physical and virtual stock of the products when creating OF from a BOM
NEW: MRP - Display product ref in "Object link" product tab for BOM
NEW: Proposals - option update prices on proposal cloning
NEW: SEPA XML - option to place payment Type Info at Credit transfer Transaction level
NEW: Stocks - stock filter in reassort lists
NEW: Stocks - stock limit in stock export CSV
NEW: Supplier order - Show ref supplier of reception in linked object block
NEW: support user_modif in order
NEW: Surveys - Show number of votes into the label of tab "Results" of a survey
NEW: TakePOS - barcode rule to insert product in TakePOS
NEW: TakePOS - pagination on search results
NEW: TakePOS - show product reference
NEW: TakePOS - add constant to hide categories
NEW: TakePOS - add constant to show category description
NEW: TakePOS - add constant to show only the products in stock
NEW: Third-Parties - Add rules "customer accountancy code" is mandatory to validate invoice
NEW: Third-Parties - Can set the parent company during the creation of thirdparty (action=add of societe/card.php)
NEW: Tickets - create Third-party with contact if not found on public ticket
NEW: Tickets - option to default check "notify tier at creation"
NEW: Tickets - Trigger: allow to automatically send messages on new tickets
NEW: Tickets - optional display warning icons on ticket list
NEW: Websites Module - supports now the multicompany module
NEW: Websites Module - on redirect of page in website module, GET parameters are kept.
NEW: The backup tools has an "lowmemory" option for mysqldump on large database
NEW: The 'reposition' class works on ajax constantonoff that make redirects
NEW: thumbnail field in product list
NEW: total mark rate in list
NEW: uncheck "send message" by default on a ticket when private messages has been checked
NEW: VAT Report by month - Show detail by rate and also by code
NEW: Added MMK currency (Myanmar Kyat)
NEW: On a form to send an email, we show all emails of contacts of object
Modules state
NEW: Module Partnership Management
NEW: Module Event Organization Management
Modules
NEW: Experimental module Event Organization Management
NEW: Experimental module Workstations Management
NEW: Experimental module Partnership Management
For developers or integrators:
------------------------------
NEW: dol_uncompress() supports more extensions (.gz, .bz2, .zstd). Only .zip was supported before.
NEW: Implement a generic method for Kaban views
NEW: Upgrade chartjs library to 3.7.1
NEW: stripe element with more gateways
NEW: solde() function evolution to be able to get solde until a chosen date
NEW: Suggest a way to run upgrade per entities.
NEW: Support html content for multiselect component.
NEW: ModuleBuilder - Add tabs view in module builder
NEW: ModuleBuilder - More feature that can be modifed after module generation
NEW: Identification of tr is possible with by attribute data-id on some pages
NEW: Import with select boxes V2
NEW: Can use current entity filter on 'chkbxlst'
NEW: Creation of the function select_bom() used to display bom select list
NEW: Add trigger and event on completely received status change
NEW: Add utility function send backup by mail
NEW: add WordPress OAuth to save a token (not SSO)
NEW: A module can embed a SQL script run at each Dolibarr upgrade
NEW: Add param to keep the robot=index meta tag on public pages
NEW: Add method hintindex() in database handlers.
NEW: add modifications for new function "$db->prefix()"
NEW: addMoreActionsButtonsList hook for button in list
NEW: Standardize a lot of code.
NEW: Add a protection into PHPunit to avoid to forget a var_dump
For developers:
---------------
API:
NEW: API Proposals - Add POST lines
NEW: API REST filter states by country
NEW: Add API to get a template invoice
NEW: Add datem and type parameters to API to create movements
NEW: #19294 implement detailed timespent in task of project API
NEW: #20736 Allow extrafields SQL filters on REST API product lookup
NEW: Can update rank of invoice, proposal and order lines with API update
NEW: update rank line is possible on API for customer invoices, sales orders and supplier invoice
NEW: Add option MAIN_API_DEBUG to save API logs into a file
NEW: A lot of addition of hooks.
Hooks:
NEW: Hook getNomUrl available everywhere in tooltip of ref links
NEW: Add hooks: selectContactListWhere hook, selectThirdpartyListWhere hook
NEW: Add hook before the public ticket list
NEW: Add hook for Notif
NEW: Add hook for more buttons
NEW: add hook printFieldListWhere in product ressort card
NEW: Add hook printFieldListWhere in "show_contacts" function
NEW: Add hook printFieldWhere in load_state_board function
NEW: Add hooks contact tab badge and hooks parameter for avoid conflicts
NEW: Add hook selectProductsListWhere in select_produits_list function
NEW: Add hooks in commercial index
NEW: Add hooks in customers and products boxes
NEW: Add hooks in thirdparty index page
NEW: Add hooks on project task time page
NEW: Add hooks on salaries and sociales card
NEW: Add hooks select product list and select thirdparty list function
NEW: Add hook to getSellPrice function
NEW: TakePos - add hooks complete product display
NEW: TakePos - add hooks for cart display
NEW: TakePos - add hooks to complete ajax return array
NEW: TakePOS - add hook doaction in TakePOS invoice
Config Options:
NEW: Add hidden option on contract PDF line to hide qty and price
NEW: Option MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND to send last document in mass mailing action
NEW: Option MAIN_API_DEBUG to save API logs into a file
NEW: Option MAIN_MAIL_AUTOCOPY_TO can accept several email and special keys
NEW: Option MAIN_SEARCH_CAT_OR_BY_DEFAULT const for search by category
NEW: Option INVOICEREC_SET_AUTOFILL_DATE_START/END
WARNING:
Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
* There is a new specific permission to be allowed to enter timesheets. If you use timesheet, don't forget to give the new permission (disable and
enable the module project if it is not visible).
* The default value for MAIN_SECURITY_CSRF_WITH_TOKEN has been set to 2. It means any POST and any GET request that contains the "action" or "massaction"
with a value of a sensitive action must also a valid token parameter (With previous value 1, only POST was concerned). Note: With value 3, any URL
with parameter "action" or "massaction" need the token, whatever is the value of the action.
* verifCond('stringtoevaluate') now return false when string contains a bad syntax content instead of true.
* The deprecated method thirdparty_doc_create() has been removed. You can use the generateDocument() instead.
* All triggers with a name XXX_UPDATE have been rename with name XXX_MODIFY for code consistency purpose.
* Rename build_path_from_id_categ() into buildPathFromId() and set method to private
* All triggers with a name XXX_UPDATE have been renamed with name XXX_MODIFY for code consistency purpose.
* Rename build_path_from_id_categ() into buildPathFromId() and set method to private.
* Move massaction 'confirm_createbills' from actions_massactions.inc.php to commande/list.php
* Method fetch_all_resources(), fetch_all_used(), fetch_all_available() of DolResource has been removed (they were not used by core code).
* Method fetch_all of DolResource has been renamed into fetchAll() to match naming conventions.
* The hook 'upgrade' and 'doUpgrade2" has been renamed 'doUpgradeBefore' and 'doUpgradeAfterDB'. A new trigger 'doUpgradeAfterFiles' has been introduced.
* The context hook 'suppliercard' when on the supplier tab of a thirdparty has been renamed into 'thirdpartysupplier'
***** ChangeLog for 15.0.3 compared to 15.0.2 *****
FIX: 15.0: modules cannot declare more than 1 cron job using the same method with different parameters
FIX: 15 fix graph ficheinter status
FIX: #18704
FIX: #20444
FIX: #20448 missing preg_replace for vat rate when adding a free line
FIX: #20476 migration postgresql 13.0.x to 14.0.x packaging type
FIX: #20487 missing letter D in constant THIRDPARTIES_DISABLE_RELATED_OBJECT_TAB
FIX: #20527 Accountancy - Unbalanced entry proposed when an employee are declared on a social contribution
FIX: #20621 signature online with proposal with n page.
FIX: #20696
FIX: #20828
FIX: #20886 : manage durations in list_print_total.tpl.php
FIX: #20902
FIX: #21051
FIX: #21093
FIX: #21138
FIX: #21140
FIX: #21174
FIX: #21323
FIX: #21472 On the bank transfer lists, a change of page switches to the lists of the direct debit module
FIX: #21495
FIX: #21518
FIX: Accountancy - Label of VAT account is empty
FIX: Accountancy - Model account list - Problem of CSRF
FIX: Accountancy - Partitioning of the entity on an automatic binding
FIX: add missing thead, th and id on table
FIX: backport commit 5b3fcc5e43979b1b0789bf81fb8f1b2b59c93056, chkbxlst cannot be emptied
FIX: Bank account not set when creating invoice from order
FIX: Bank transfer - Link on code supplier invoice was bad
FIX: Can convert a partially closed down payment when close for
FIX: class center linkedObjectblock order date
FIX: count elements in invoice list (Issue #21444)
FIX: Customer price non numeric warning when 0 vat.
FIX: errors in getLinesArray()
FIX: False alert of WAF when there is "set" into some URL action=update.
FIX: Intervention graph by status on ficheinter Index page
FIX: Intervention url link into Commerce index
FIX: Fix get origin from other than supplier proposal when add a new supplier proposal
FIX: Fix show errors in card
FIX: fourn/commande/card.php Added "$object" parameter to $formfile->showdocuments call
FIX: french traductions for payment methods
FIX: hook for dol_format_address
FIX: Index page for "Sales" give wrong URL link to Intervention
FIX: issue Dolibarr #21495 for v15
FIX: label and get_substitutionarray_each_var_object on ODT generation
FIX: load product stock in inventory lines
FIX: missing morecss for multiselectarray
FIX: missins time spent list menu
FIX: new member subscription: bank account and payment mode might be hidden
FIX: ODT generation of BOM document
FIX: ODT tags for subobjects {object_subobject_yyy} was not working.
FIX: qty received label in Squille PDF model
FIX: rank duplicate on mass action invoice from multiple orders
FIX: regression + add $forceentity parameter
FIX: regression PR #20713
FIX: security breach if we have same ref number in multiple entities
FIX: selection of type of invoice
FIX: Send remind to pay invoice only on validated invoices
FIX: Show sellist type of extrafield when none category selected
FIX: signature online with proposal with n page.
FIX: sql error when PRODUCT_USE_SUPPLIER_PACKAGING enabled.
FIX: sql order
FIX: trash icon on crontask list to do not work
FIX: v15 linked object block center order date
FIX: Warning on attribut
FIX: We must remove empty values of $features array in fetchByProductCombination2ValuePairs() because some products can use only several attributes in their variations and not necessarily all. In this case, fetch doesn't work without my correction
FIX: with callback function
FIX: xml file for company with special chars in name
FIX: Zatca QR code must use company name/vat
***** ChangeLog for 15.0.2 compared to 15.0.1 *****
FIX: #19777 #20281
FIX: #20140 #20301
FIX: #20279 Accountancy - PostGreSQL - Error on mass update lines already binded
FIX: #20476 migration postgresql 14.0.x to 15.0.x packaging type
FIX: #20733 Inventory: Do not use batch qty even if present if batch module is disabled.
FIX: action comm list: holiday last day not included + handle duration with halfdays
FIX: Add missing entity on salary's payment
FIX: Add 'recruitment' into check array
FIX: add tools to fix bad bank amount in accounting with multicurrency
FIX: assign member cateogry to a member
FIX: backport
FIX: bad bank amount in accounting with multicurrency
FIX: Bad condition on remx
FIX: Bad filter on date on salary list
FIX: bad link to add a customer price (token duplicated)
FIX: bad status of member on widget by type and status
FIX: better error management at product selling price update
FIX: Can't edit bank record
FIX: check mandatory thirdparty fields for mass action
FIX: check thirdparty object loaded and properties exist
FIX: comment
FIX: compatibility for ticket number sharing
FIX: compatibility with multicompany sharings
FIX: contact card: single extrafield update failed
FIX: country not visible into list of states
FIX: Delete an extrafield where type is double
FIX: deprecated module are not more viewed as external modules
FIX: Disable customer type by default if type prospect/customer is disabled
FIX: each time we create a supplier order, we need to give it a ref_supplier
FIX: Error management
FIX: fatal error for $db usage in tpl
FIX: filter into the list of product lots
FIX: Filter on Object Referent page give CRSF page
FIX: Fix default options ($hidedetails, $hidedesc, $hideref) with globales when generate PDF in mass actions
FIX: Fix search by filters
FIX: Fix the adding of lines in the create invoice functions
FIX: forgotten form confirm before various payment delete
FIX: holiday/leave requests: write status change emails in HTML
FIX: include discount price for PMP after a reception (Issue #20029)
FIX: incrementation
FIX: in salary stats and payment list, we must check right perms as well as salary list
FIX: intervention entity missing
FIX: label tax cat trad
FIX: Mass action ship orders
FIX: missing advanced perms
FIX: missing call to executeHooks()
FIX: Missing entity on adding new VAT
FIX: missing hook for row ordering
FIX: missing hook parameter ($possiblelinks)
FIX: missing parenthesis
FIX: missing picto in combo of mass actions of thirdparties.
FIX: missing signature library when ODT model is used
FIX: Missing unset fields after updateline expensereport
FIX: ModuileBuilder - Fix getLinesArray() error reporting
FIX: Move delete task time trigger position
FIX: Navigation between invoices
FIX: No empty line inserted into accounting_bookkeeping
FIX: Numbering of sepa files
FIX: object cloning: set unique extrafield values to null to prevent duplicates
FIX: on update with action reminder in future there is user key error
FIX: originproductline array td identification data-id
FIX: out of memory when more than 100 000 invoices.
FIX: permit access to medias when logged in a different entity
FIX: phpcs
FIX: project creation prevented if PROJECTLEADER contact role renamed, de-activated or deleted
FIX: project timesheet by week: cleanup unused code
FIX: project timesheet: public holidays offset by 1 day
FIX: project timesheets: assume Saturday and Sunday as default weekend days when working days conf is empty or badly formed
FIX: propal list: bad error management when setting "not signed" mass action
FIX: propal list mass action translations and error management (v14 edition)
FIX: propal list: missing not signed massaction translation keys for transifex
FIX: PR returns
FIX: ref_client doesn't exists on supplier invoice, then ref_fourn needs to have a default value when we want to bill several supplier orders
FIX: replenish and manage product stock by warhouse
FIX: sending email on payment of registration of event
FIX: SEPA ICS is not mandatory for bank transfer
FIX: Set datec when add time spent on a project task
FIX: status filter on supplierOrder stats doesn't work
FIX: stickler-ci
FIX: still prevent project creation if PROJECTLEADER role unavailable, but with a specific error message
FIX: Supplier order stats
FIX: Tabulation must be allowed for HTML content
FIX: tool to fix bank account not in main currency for vendor invoice
FIX: translations
FIX: Travis + Update dev
FIX: truncate Customer Reference too long on PDF header (PR #20718)
FIX: uniformize code
FIX: Update of sale price (log not correctly updated)
FIX: user actions rights when mulit-company transverse mode is enabled
FIX: user employee tab: offset in open days messes up holiday length calculation
FIX: We need to have a different default_ref_supplier for each new fourn invoice
FIX: "WHERE" clause missing on resource export
FIX: #yogosha9754
***** ChangeLog for 15.0.1 compared to 15.0.0 *****
@ -145,8 +511,9 @@ 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: mass action validate on supplier orders list
NEW: mass action send email to all attendees of an event
NEW: mass action to switch status on sale / on purchase of a product
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)
@ -167,7 +534,7 @@ 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
@ -175,36 +542,51 @@ NEW: Stable module Knowledge Management
NEW: Experimental module Event Organization Management
NEW: Experimental module Workstations Management
NEW: Development of module Partnership Management
OLD: module SimplePOS has been completely removed -> use TakePOS
For developers:
---------------
API:
NEW: #18319 REST API - Shipment: Add 'close' action / endpoint / POST method.
NEW: add API /approve and /makeOrder for purchase orders
NEW: API for knowledgemanagement
NEW: API get list of legal form of business
NEW: API list of staff units
NEW: Hidden option API_DISABLE_COMPRESSION is now visible in API setup page.
Hook:
NEW: add hook 'beforeBodyClose'
NEW: add hook 'hookGetEntity'
NEW: add hook 'menuLeftMenuItems' to filter the leftmenu items
NEW: add hook 'printUnderHeaderPDFline' on invoice PDF templates (can be used for example to add a barcode or more information on header of invoices).
NEW: add hookmanager on note pages
NEW: hook after rank update
NEW: 'printFieldListFrom' hook call on several lists
ModuleBuilder:
NEW: add the property "copytoclipboard" in modulebuilder
NEW: Use lang selector when using a field key 'lang' in modulebuilder
Options:
NEW: add options MAIN_IBAN_IS_NEVER_MANDATORY, MAIN_IBAN_NOT_MANDATORY, PROPAL_NOT_BILLABLE, PROPAL_REOPEN_UNSIGNED_ONLY, PROPOSAL_ARE_NOT_BILLABLE, TICKETS_MESSAGE_FORCE_MAIL
Trigger:
NEW: add action trigger for member excluded
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: add code codebar column on serial/lot structure
NEW: add date_valid and date_approve columns in the list of supplier orders
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).
WARNING:
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
@ -1061,7 +1443,6 @@ NEW: introduce constant FACTUREFOURN_REUSE_NOTES_ON_CREATE_FROM
NEW: introducing new modal boxes in TakePOS
NEW: keep TakePOS terminal when login/logout
NEW: link on balance to the ledger
NEW: MAIN_EMAILCOLLECTOR_MAIL_WITHOUT_HEADER const in email collector
NEW: manage errors on update extra fields in ticket card
NEW: mass-actions for the event list view
NEW: more filter for "View change logs"

View File

@ -32,7 +32,7 @@ Other licenses apply for some included dependencies. See [COPYRIGHT](https://git
If you have low technical skills and you're looking to install Dolibarr ERP/CRM in just a few clicks, you can use one of the packaged versions:
- [DoliWamp for Windows](https://wiki.dolibarr.org/index.php/Dolibarr_for_Windows_DoliWamp)
- [DoliWamp for Windows](https://wiki.dolibarr.org/index.php/Dolibarr_for_Windows_(DoliWamp))
- [DoliDeb for Debian](https://wiki.dolibarr.org/index.php/Dolibarr_for_Ubuntu_or_Debian)
- DoliRpm for Redhat, Fedora, OpenSuse, Mandriva or Mageia
@ -111,7 +111,7 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
- Customers/Prospects + Contacts management
- Opportunities or Leads management
- Commercial proposals management
- Commercial proposals management (online signing)
- Customer Orders management
- Contracts/Subscription management
- Interventions management
@ -129,11 +129,11 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
- Supplier Invoices/credit notes and payment management
- INCOTERMS
Finance / Accounting
Finance/Accounting
- Invoices / Payments
- Invoices/Payments
- Bank accounts management
- Direct debit orders management (European SEPA)
- Direct debit and Credit transfer management (European SEPA)
- Accounting management
- Donations management
- Loan management
@ -142,14 +142,14 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
Collaboration
- Shared calendar/agenda (with ical and vcal export for third party tools integration)
- Shared calendar/agenda (with ical and vcal import/export for third party tools integration)
- Projects & Tasks management
- Ticket System
- Surveys
HR
- Employee's leave requests management
- Employee's leaves management
- Expense reports
- Recruitment management
- Timesheets
@ -157,16 +157,14 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
### Other application/modules
- Electronic Document Management (EDM)
- Bookmarks management
- Bookmarks
- Reporting
- Data export/import
- Barcodes
- Margin calculations
- LDAP connectivity
- ClickToDial integration
- Mass emailing
- RSS integration
- Skype integration
- Social platforms linking
- Payment platforms integration (PayPal, Stripe, Paybox...)
- Email-Collector
@ -175,13 +173,12 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
### Other general features
- Localization in most major languages
- Multi-Language Support
- Multi-Language Support (Localization in most major languages)
- Multi-Users and groups with finely grained rights
- Multi-Currency
- Multi-Company (by adding of an external module)
- Very user friendly and easy to use
- customizable Dashboard
- Customizable dashboards
- Highly customizable: enable only the modules you need, add user personalized fields, choose your skin, several menu managers (can be used by internal users as a back-office with a particular menu, or by external users as a front-office with another one)
- APIs (REST, SOAP)
- Code that is easy to understand, maintain and develop (PHP with no heavy framework; trigger and hook architecture)
@ -191,8 +188,9 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog)
- Canadian double taxes (federal/province) and other countries using cumulative VAT
- Tunisian tax stamp
- Argentina invoice numbering using A,B,C...
- ZATCA e-invoicing QR-Code
- 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 data privacy rules (europe GDPR, ...)
- ...
- Flexible PDF & ODT generation for invoices, proposals, orders...
- ...
@ -244,6 +242,7 @@ Follow Dolibarr project on:
- [Facebook](https://www.facebook.com/dolibarr)
- [Twitter](https://www.twitter.com/dolibarr)
- [LinkedIn](https://www.linkedin.com/company/association-dolibarr)
- [Reddit](https://www.reddit.com/r/Dolibarr_ERP_CRM/)
- [YouTube](https://www.youtube.com/user/DolibarrERPCRM)
- [GitHub](https://github.com/Dolibarr/dolibarr)

View File

@ -6,8 +6,9 @@ This file contains some policies about the security reports on Dolibarr ERP CRM
| Version | Supported |
| ---------- | ---------------------- |
| <= 14.0.4 | :x: |
| >= 14.0.5+ | :white_check_mark: except CSRF attacks|
| <= 15.0.0 | :x: |
| >= 15.0.1+ | :white_check_mark: except CSRF attacks|
| >= 16.0.0 | :white_check_mark: |
| >= develop | :white_check_mark: |
## Reporting a Vulnerability

View File

@ -13,32 +13,12 @@ It is here only to build Dolibarr packages, and those generated packages will no
There are several tools:
--------------------------------------------------------------------------------------------------
- To build full Dolibarr packages, launch the script
> Launch command perl makepack-dolibarr.pl
--------------------------------------------------------------------------------------------------
Prerequisites to build tgz, debian and rpm packages:
> apt-get install tar dpkg dpatch p7zip-full rpm zip
--------------------------------------------------------------------------------------------------
Prerequisites to build autoexe DoliWamp package:
> apt-get install wine q4wine
> Launch "wine cmd" to check a drive Z: pointing to / exists.
> Install InnoSetup
For example by running isetup-5.5.8.exe (https://www.jrsoftware.org) https://files.jrsoftware.org/is/5/
> Install WampServer into "C:\wamp64" to have Apache, PHP and MariaDB
For example by running wampserver3.2.0_x64.exe (https://www.wampserver.com).
See file build/exe/doliwamp.iss to know the doliwamp version currently setup.
> Add path to ISCC into PATH windows var:
Launch wine cmd, then regedit and add entry int HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment\PATH
> To build manually the .exe from Windows (running from makepack-dolibarr.pl script is however recommanded),
open file build/exe/doliwamp.iss and click on button "Compile".
The .exe file will be build into directory build.
See makepack-howto.txt for prerequisites.
--------------------------------------------------------------------------------------------------

View File

@ -1,4 +1,6 @@
#!/bin/bash
# Script used by the Dockerfile.
# See README.md to know how to create a Dolibarr env with docker
usermod -u ${HOST_USER_ID} www-data
groupmod -g ${HOST_USER_ID} www-data

View File

@ -1 +1 @@
/doliwamp.tmp.iss
/doliwamp.tmp.iss*

View File

@ -1,5 +1,4 @@
<?php
/* !!! DO NOT EDIT THIS FILE, EDIT config.inc.php INSTEAD !!! */
// vim: expandtab sw=4 ts=4 sts=4:
@ -139,7 +138,7 @@ $cfg['UseDbSearch'] = TRUE; // whether to enable the "database sea
$cfg['IgnoreMultiSubmitErrors'] = FALSE; // if set to true, PMA continues computing multiple-statement queries
// even if one of the queries failed
$cfg['VerboseMultiSubmit'] = TRUE; // if set to true, PMA will show the affected rows of EACH statement on
// multiple-statement queries. See the libraries/import.php file for
// multiple-statement queries. See the libraries/import.php file for
// hardcoded defaults on how many queries a statement may contain!
$cfg['AllowArbitraryServer'] = FALSE; // allow login to any user entered server in cookie based auth
@ -195,7 +194,7 @@ $cfg['CharEditing'] = 'input';
// textarea - allows newlines in fields
$cfg['InsertRows'] = 2; // How many rows can be inserted at one time
$cfg['ForeignKeyDropdownOrder'] = // Sort order for items in a foreign-key dropdown box.
$cfg['ForeignKeyDropdownOrder'] = // Sort order for items in a foreign-key dropdown box.
array( 'content-id', 'id-content'); // 'content' is the referenced data, 'id' is the key value.
$cfg['ForeignKeyMaxLimit'] = 100; // A dropdown will be used if fewer items are present
@ -488,7 +487,7 @@ $cfg['ShowBrowseComments'] = TRUE; // shows stored relation-comments in
$cfg['ShowPropertyComments']= TRUE; // shows stored relation-comments in 'table property' mode.
$cfg['RepeatCells'] = 100; // repeat header names every X cells? (0 = deactivate)
$cfg['EditInWindow'] = TRUE; // Set to TRUE if Edit link should open the query to edit in the query window (assuming Javascript is enabled), and to FALSE if we should edit in the right panel
$cfg['EditInWindow'] = TRUE; // Set to TRUE if Edit link should open the query to edit in the query window (assuming Javascript is enabled), and to FALSE if we should edit in the right panel
$cfg['QueryWindowWidth'] = 550; // Width of Query window
$cfg['QueryWindowHeight'] = 310; // Height of Query window
$cfg['QueryHistoryDB'] = FALSE; // Set to TRUE if you want DB-based query history.
@ -561,7 +560,7 @@ $cfg['SQLQuery']['Refresh'] = TRUE; // Refresh the results page
*/
$cfg['UploadDir'] = ''; // Directory for uploaded files that can be executed by
// phpMyAdmin. For example './upload'. Leave empty for
// no upload directory support. Use %u for username
// no upload directory support. Use %u for username
// inclusion.
$cfg['SaveDir'] = ''; // Directory where phpMyAdmin can save exported data on
// server. For example './save'. Leave empty for no save
@ -645,7 +644,7 @@ $cfg['ColumnTypes'] = array(
);
// Attributes
// Note: the "ON UPDATE CURRENT_TIMESTAMP" attribute is added dynamically
// Note: the "ON UPDATE CURRENT_TIMESTAMP" attribute is added dynamically
// for MySQL >= 4.1.2, in libraries/tbl_properties.inc.php
$cfg['AttributeTypes'] = array(

View File

@ -24,15 +24,14 @@ OutputBaseFilename=__FILENAMEEXEDOLIWAMP__
;OutputManifestFile=build\doliwampbuild.log
; Define full path from which all relative path are defined
; You must modify this to put here your dolibarr root directory
;SourceDir=Z:\home\ldestailleur\git\dolibarrxxx
SourceDir=..\..\..
AppId=doliwamp
AppPublisher=NLTechno
AppPublisherURL=https://www.nltechno.com
AppPublisher=DoliCloud
AppPublisherURL=https://www.dolicloud.com
AppSupportURL=https://www.dolibarr.org
AppUpdatesURL=https://www.dolibarr.org
AppComments=DoliWamp includes Dolibarr, Apache, PHP and Mysql software.
AppCopyright=Copyright (C) 2008-2020 Laurent Destailleur (NLTechno), Fabian Rodriguez (Le Goût du Libre)
AppCopyright=Copyright (C) 2008-2022 Laurent Destailleur (DoliCloud), Fabian Rodriguez (Le Goût du Libre)
DefaultDirName=c:\dolibarr
DefaultGroupName=Dolibarr
;LicenseFile=COPYING
@ -81,7 +80,7 @@ Name: "desktopicon"; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:
Name: "{app}\logs"
Name: "{app}\tmp"
Name: "{app}\dolibarr_documents"
Name: "{app}\bin\apache\apache2.4.41\logs"
Name: "{app}\bin\apache\apache2.4.51\logs"
[Files]
; Stop/start
@ -99,19 +98,12 @@ Source: "build\exe\doliwamp\startdoliwamp_manual_donotuse.bat.install"; DestDir:
Source: "build\exe\doliwamp\builddemosslfiles.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "build\exe\doliwamp\UsedPort.exe"; DestDir: "{app}\"; Flags: ignoreversion;
; PhpMyAdmin, Apache, Php, Mysql
; Apache, Php, Mysql
; Put here path of Wampserver applications
; Value OK: apache 2.2.6, php 5.2.5 (5.2.11, 5.3.0 and 5.3.1 fails if php_exif, php_pgsql, php_zip is on), mysql 5.0.45
; Value OK: apache 2.2.11, php 5.3.0 (if no php_exif, php_pgsql, php_zip), mysql 5.0.45
; Value OK: apache 2.4.9, php 5.5.12, mysql 5.0.45 instead of 5.6.17 (wampserver2.5-Apache-2.4.9-Mysql-5.6.17-php5.5.12-32b.exe)
; Value OK: apache 2.4.41, php 7.3.12, mariadb10.4.10 (wampserver3.2.0_x64.exe)
Source: "C:\wamp64\apps\phpmyadmin4.9.2\*.*"; DestDir: "{app}\apps\phpmyadmin4.9.2"; Flags: ignoreversion recursesubdirs; Excludes: "config.inc.php,wampserver.conf,*.log,*_log,darkblue_orange"
;Source: "C:\Program Files\Wamp\bin\apache\apache2.4.9\*.*"; DestDir: "{app}\bin\apache\apache2.4.9"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,httpd.conf,wampserver.conf,*.log,*_log"
Source: "C:\wamp64\bin\apache\apache2.4.41\*.*"; DestDir: "{app}\bin\apache\apache2.4.41"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,httpd.conf,wampserver.conf,*.log,*_log"
;Source: "C:\Program Files\Wamp\bin\php\php5.5.12\*.*"; DestDir: "{app}\bin\php\php5.5.12"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,phpForApache.ini,wampserver.conf,*.log,*_log"
Source: "C:\wamp64\bin\php\php7.3.12\*.*"; DestDir: "{app}\bin\php\php7.3.12"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,phpForApache.ini,wampserver.conf,*.log,*_log"
;Source: "C:\Program Files\Wamp\bin\mysql\mysql5.0.45\*.*"; DestDir: "{app}\bin\mysql\mysql5.0.45"; Flags: ignoreversion recursesubdirs; Excludes: "my.ini,data\*,wampserver.conf,*.log,*_log,MySQLInstanceConfig.exe"
Source: "C:\wamp64\bin\mariadb\mariadb10.4.10\*.*"; DestDir: "{app}\bin\mariadb\mariadb10.4.10"; Flags: ignoreversion recursesubdirs; Excludes: "my.ini,data\*,wampserver.conf,*.log,*_log,MySQLInstanceConfig.exe"
; Value OK: apache 2.4.51, php 7.3.33, mariadb10.6.5 (wampserver3.2.6_x64.exe)
Source: "C:\wamp64\bin\apache\apache2.4.51\*.*"; DestDir: "{app}\bin\apache\apache2.4.51"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,httpd.conf,wampserver.conf,*.log,*_log"
Source: "C:\wamp64\bin\php\php7.3.33\*.*"; DestDir: "{app}\bin\php\php7.3.33"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,phpForApache.ini,wampserver.conf,*.log,*_log"
Source: "C:\wamp64\bin\mariadb\mariadb10.6.5\*.*"; DestDir: "{app}\bin\mariadb\mariadb10.6.5"; Flags: ignoreversion recursesubdirs; Excludes: "my.ini,data\*,wampserver.conf,*.log,*_log,MySQLInstanceConfig.exe"
; Mysql data files (does not overwrite if exists)
; We must copy them because the tool mysql_install_db.exe to generate them at first install does not return to prompt so make install hang
@ -125,15 +117,11 @@ Source: "scripts\*.*"; DestDir: "{app}\www\dolibarr\scripts"; Flags: ignoreversi
Source: "*.*"; DestDir: "{app}\www\dolibarr"; Flags: ignoreversion; Excludes: ".gitignore,.project,CVS\*,Thumbs.db,default.properties,install.lock"
; Config files
Source: "build\exe\doliwamp\phpmyadmin.conf.install"; DestDir: "{app}\alias"; Flags: ignoreversion;
Source: "build\exe\doliwamp\dolibarr.conf.install"; DestDir: "{app}\alias"; Flags: ignoreversion;
Source: "build\exe\doliwamp\config.inc.php.install"; DestDir: "{app}\apps\phpmyadmin4.1.14"; Flags: ignoreversion;
;Source: "build\exe\doliwamp\httpd.conf.install"; DestDir: "{app}\bin\apache\apache2.4.9\conf"; Flags: ignoreversion;
Source: "build\exe\doliwamp\httpd.conf.install"; DestDir: "{app}\bin\apache\apache2.4.41\conf"; Flags: ignoreversion;
Source: "build\exe\doliwamp\httpd.conf.install"; DestDir: "{app}\bin\apache\apache2.4.51\conf"; Flags: ignoreversion;
Source: "build\exe\doliwamp\my.ini.install"; DestDir: "{app}\bin\mysql\mysql5.0.45"; Flags: ignoreversion;
Source: "build\exe\doliwamp\my.ini.install"; DestDir: "{app}\bin\mariadb\mariadb10.4.10"; Flags: ignoreversion;
;Source: "build\exe\doliwamp\php.ini.install"; DestDir: "{app}\bin\php\php5.5.12"; Flags: ignoreversion;
Source: "build\exe\doliwamp\php.ini.install"; DestDir: "{app}\bin\php\php7.3.12"; Flags: ignoreversion;
Source: "build\exe\doliwamp\my.ini.install"; DestDir: "{app}\bin\mariadb\mariadb10.6.5"; Flags: ignoreversion;
Source: "build\exe\doliwamp\php.ini.install"; DestDir: "{app}\bin\php\php7.3.33"; Flags: ignoreversion;
Source: "build\exe\doliwamp\index.php.install"; DestDir: "{app}\www"; Flags: ignoreversion;
Source: "build\exe\doliwamp\install.forced.php.install"; DestDir: "{app}\www\dolibarr\htdocs\install"; Flags: ignoreversion;
Source: "build\exe\doliwamp\openssl.conf"; DestDir: "{app}"; Flags: ignoreversion;
@ -196,7 +184,6 @@ var destFileA: String;
var srcContents: String;
var browser: String;
var mysqlVersion: String;
var phpmyadminVersion: String;
var phpDllCopy: String;
var batFile: String;
@ -240,13 +227,9 @@ procedure InitializeWizard();
begin
//version des applis, a modifier pour chaque version de WampServer 2
//apacheVersion := '2.4.9';
//phpVersion := '5.5.12' ;
apacheVersion := '2.4.41';
phpVersion := '7.3.12' ;
//mysqlVersion := '5.0.45';
mysqlVersion := '10.4.10';
phpmyadminVersion := '4.1.14';
apacheVersion := '2.4.51';
phpVersion := '7.3.33' ;
mysqlVersion := '10.6.5';
smtpServer := 'localhost';
apachePort := '80';
@ -380,9 +363,9 @@ begin
// Migration of database
// datadir := pathWithSlashes+'/bin/mariadb/marradb10.4.10/data';
// exedirold := pathWithSlashes+'/bin/mariadb/marradb10.4.10/';
// exedirnew := pathWithSlashes+'/bin/mariadb/marradb10.4.10/';
// datadir := pathWithSlashes+'/bin/mariadb/mariadb10.6.5/data';
// exedirold := pathWithSlashes+'/bin/mariadb/mariadb10.6.5/';
// exedirnew := pathWithSlashes+'/bin/mariadb/mariadb10.6.5/';
// If we have a new database version, we should only copy old my.ini file into new directory
// and change only all basedir= strings to use new version. Like this, data dir is still correct.
@ -635,27 +618,6 @@ begin
begin
//----------------------------------------------
// Create file alias phpmyadmin (always)
//----------------------------------------------
destFile := pathWithSlashes+'/alias/phpmyadmin.conf';
srcFile := pathWithSlashes+'/alias/phpmyadmin.conf.install';
if FileExists(srcFile) then
begin
LoadStringFromFile (srcFile, srcContents);
//installDir et version de phpmyadmin
StringChangeEx (srcContents, 'WAMPROOT', pathWithSlashes, True);
StringChangeEx (srcContents, 'WAMPPHPMYADMINVERSION', phpmyadminVersion, True);
SaveStringToFile(destFile,srcContents, False);
end;
DeleteFile(srcFile);
//----------------------------------------------
// Create file alias dolibarr (if not exists)
//----------------------------------------------
@ -691,35 +653,6 @@ begin
//----------------------------------------------
// Create file configuration for phpmyadmin (if not exists)
//----------------------------------------------
destFile := pathWithSlashes+'/apps/phpmyadmin'+phpmyadminVersion+'/config.inc.php';
srcFile := pathWithSlashes+'/apps/phpmyadmin'+phpmyadminVersion+'/config.inc.php.install';
if FileExists(srcFile) then
begin
if not FileExists (destFile) then
begin
LoadStringFromFile (srcFile, srcContents);
StringChangeEx (srcContents, 'WAMPMYSQLNEWPASSWORD', mypass, True);
StringChangeEx (srcContents, 'WAMPMYSQLPORT', myport, True);
SaveStringToFile(destFile,srcContents, False);
end
else
begin
// We must replace to use format 2.4 of apache
DeleteFile(destFile);
LoadStringFromFile (srcFile, srcContents);
StringChangeEx (srcContents, 'WAMPMYSQLNEWPASSWORD', mypass, True);
StringChangeEx (srcContents, 'WAMPMYSQLPORT', myport, True);
SaveStringToFile(destFile,srcContents, False);
end;
end;
//----------------------------------------------
// Create file httpd.conf (if not exists)
//----------------------------------------------
@ -1082,7 +1015,7 @@ Filename: "{app}\rundoliwamp.bat"; Description: {cm:LaunchNow}; Flags: shellexec
[UninstallDelete]
Type: files; Name: "{app}\*.*"
Type: files; Name: "{app}\bin\mariadb\mariadb10.4.10\*.*"
Type: files; Name: "{app}\bin\mariadb\mariadb10.6.5\*.*"
Type: filesandordirs; Name: "{app}\alias"
Type: filesandordirs; Name: "{app}\apps"
Type: filesandordirs; Name: "{app}\bin\apache"

View File

@ -56,7 +56,7 @@ if (empty($argv[1])) {
$i=0;
while ($i < $argc) {
if (! empty($argv[$i])) {
if (!empty($argv[$i])) {
parse_str($argv[$i]); // set all params $release, $includecustom, $includeconstant, $buildzip ...
}
if (preg_match('/includeconstant=/', $argv[$i])) {

View File

@ -65,7 +65,7 @@ $DIR||='.'; $DIR =~ s/([^\/\\])[\\\/]+$/$1/;
$SOURCE="$DIR/..";
$DESTI="$SOURCE/build";
if ($SOURCE !~ /^\//)
if ($SOURCE !~ /^\// && $SOURCE !~ /^[a-z]:/i)
{
print "Error: Launch the script $PROG.$Extension with its full path from /.\n";
print "$PROG.$Extension aborted.\n";
@ -76,15 +76,23 @@ if (! $ENV{"DESTIBETARC"} || ! $ENV{"DESTISTABLE"})
{
print "Error: Missing environment variables.\n";
print "You must define the environment variable DESTIBETARC and DESTISTABLE to point to the\ndirectories where you want to save the generated packages.\n";
print "$PROG.$Extension aborted.\n";
print "\n";
print "You can set them with\n";
print "On Linux:\n";
print "export DESTIBETARC='/tmp'; export DESTISTABLE='/tmp';\n";
print "On Windows:\n";
print "set DESTIBETARC=c:/tmp\n";
print "set DESTISTABLE=c:/tmp\n";
print "\n";
print "Example: DESTIBETARC='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/lastbuild'\n";
print "Example: DESTISTABLE='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/stable'\n";
print "$PROG.$Extension aborted.\n";
sleep 2;
exit 1;
}
if (! -d $ENV{"DESTIBETARC"} || ! -d $ENV{"DESTISTABLE"})
{
print "Error: Directory of environment variable DESTIBETARC or DESTISTABLE does not exist.\n";
print "Error: Directory of environment variable DESTIBETARC ($ENV{'DESTIBETARC'}) or DESTISTABLE ($ENV{'DESTISTABLE'}) does not exist.\n";
print "$PROG.$Extension aborted.\n";
sleep 2;
exit 1;
@ -94,7 +102,7 @@ if (! -d $ENV{"DESTIBETARC"} || ! -d $ENV{"DESTISTABLE"})
# --------------
if ("$^O" =~ /linux/i || (-d "/etc" && -d "/var" && "$^O" !~ /cygwin/i)) { $OS='linux'; $CR=''; }
elsif (-d "/etc" && -d "/Users") { $OS='macosx'; $CR=''; }
elsif ("$^O" =~ /cygwin/i || "$^O" =~ /win32/i) { $OS='windows'; $CR="\r"; }
elsif ("$^O" =~ /cygwin/i || "$^O" =~ /win32/i || "$^O" =~ /msys/i) { $OS='windows'; $CR="\r"; }
if (! $OS) {
print "Error: Can't detect your OS.\n";
print "Can't continue.\n";
@ -390,7 +398,7 @@ if ($nboftargetok) {
$olddir=getcwd();
chdir("$SOURCE");
print "Clean $SOURCE/htdocs\n";
print "Clean $SOURCE/htdocs/includes/autoload.php\n";
$ret=`rm -f $SOURCE/htdocs/includes/autoload.php`;
$ret=`git ls-files . --exclude-standard --others`;
@ -499,8 +507,9 @@ if ($nboftargetok) {
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/cache.manifest`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/conf/conf.php`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/conf/conf.php.mysql`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/conf/conf.php.nova*`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/conf/conf.php.old`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/conf/conf.php.postgres`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/conf/conf.php.pgsql`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/conf/conf*sav*`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/install/mssql/README`;
@ -582,9 +591,7 @@ if ($nboftargetok) {
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/teclib*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/timesheet*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/webmail*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/themes/oblyon*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/themes/allscreen*`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/theme/common/octicons/LICENSE`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/theme/common/fontawesome-5/svgs`;
# Removed other test files
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/public/test`;
@ -625,7 +632,7 @@ if ($nboftargetok) {
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/tecnickcom/tcpdf/fonts/freefont-*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/tecnickcom/tcpdf/fonts/ae_fonts_*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/tecnickcom/tcpdf/fonts/utils`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/tecnickcom/tcpdf/tools`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/tecnickcom/tcpdf/tools`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/vendor`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/webmozart`;
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/autoload.php`;
@ -1075,28 +1082,52 @@ if ($nboftargetok) {
print "Remove target $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe...\n";
unlink "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe";
print "Check that in your Wine setup, you have created a Z: drive that point to your / directory.\n";
if ($OS eq 'windows') {
print "Check that ISCC.exe is in your PATH.\n";
} else {
print "Check that in your Wine setup, you have created a Z: drive that point to your / directory.\n";
}
$SOURCEBACK=$SOURCE;
$SOURCEBACK =~ s/\//\\/g;
print "Prepare file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss from \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.iss\"\n";
$ret=`cat "$SOURCE/build/exe/doliwamp/doliwamp.iss" | sed -e 's/__FILENAMEEXEDOLIWAMP__/$FILENAMEEXEDOLIWAMP/g' > "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`;
print "Prepare file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\" from \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.iss\"\n";
#$ret=`cat "$SOURCE/build/exe/doliwamp/doliwamp.iss" | sed -e 's/__FILENAMEEXEDOLIWAMP__/$FILENAMEEXEDOLIWAMP/g' > "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`;
open(IN, '<' . $SOURCE."/build/exe/doliwamp/doliwamp.iss") or die $!;
open(OUT, '>' . "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss") or die $!;
while(<IN>)
{
$_ =~ s/__FILENAMEEXEDOLIWAMP__/$FILENAMEEXEDOLIWAMP/g;
print OUT $_;
}
close(IN);
close(OUT);
print "Compil exe $FILENAMEEXEDOLIWAMP.exe file from iss file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\"\n";
$cmd= "wine ISCC.exe \"Z:$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\"";
print "Compil exe $FILENAMEEXEDOLIWAMP.exe file from iss file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\" on OS $OS\n";
if ($OS eq 'windows') {
$cmd= "ISCC.exe \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\"";
} else {
#$cmd= "wine ISCC.exe \"Z:$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\"";
}
print "$cmd\n";
$ret= `$cmd`;
#print "$ret\n";
print "ret=$ret\n";
# Move to final dir
print "Move \"$SOURCE\\build\\$FILENAMEEXEDOLIWAMP.exe\" to $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe\n";
rename("$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe","$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe");
print "Move $SOURCE/build/$FILENAMEEXEDOLIWAMP.exe to $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe\n";
$ret=`mv "$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe" "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"`;
use File::Copy;
#$ret=`mv "$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe" "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"`;
$ret=move("$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe", "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe");
print "Remove tmp file $SOURCE/build/exe/doliwamp/doliwamp.tmp.iss\n";
$ret=`rm "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`;
#$ret=`rm "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`;
$ret=unlink("$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss");
next;
}
@ -1243,7 +1274,7 @@ if ($nboftargetok) {
print "\n----- Summary -----\n";
foreach my $target (sort keys %CHOOSEDTARGET) {
if ($target eq '-CHKSUM') { print "Checksum was generated"; next; }
if ($target eq '-CHKSUM') { print "Checksum was generated\n"; next; }
if ($CHOOSEDTARGET{$target} < 0) {
print "Package $target not built (bad requirement).\n";
} else {

View File

@ -1,19 +1,47 @@
----- Dolibarr Makepack How To -----
This documentation describe steps to build a BETA or RELEASE versions
of Dolibarr. There is a chapter for BETA version and a chapter for
RELEASE version.
of Dolibarr. There is a chapter for BETA version and a chapter for RELEASE version.
***** Prerequisites For Linux *****
Prerequisites to build tgz, debian and rpm packages:
> apt-get install perl tar dpkg dpatch p7zip-full rpm zip php-cli
Prerequisites to build autoexe DoliWamp package:
> apt-get install wine q4wine
> Launch "wine cmd" to check a drive Z: pointing to / exists.
> Install InnoSetup
For example by running isetup-5.5.8.exe (https://www.jrsoftware.org) https://files.jrsoftware.org/is/5/
> Install WampServer into "C:\wamp64" to have Apache, PHP and MariaDB
For example by running wampserver3.2.0_x64.exe (https://www.wampserver.com).
See file build/exe/doliwamp.iss to know the doliwamp version currently setup.
> Add path to ISCC into PATH windows var:
Launch wine cmd, then regedit and add entry int HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment\PATH
> To build manually the .exe from Windows (running from makepack-dolibarr.pl script is however recommanded),
open file build/exe/doliwamp.iss and click on button "Compile".
The .exe file will be build into directory build.
***** Prerequisites For Windows *****
Install Perl
Install WampServer-3.2.*-64.exe
isetup-5.5.8.exe
***** Actions to do a BETA *****
This files describe steps made by Dolibarr packaging team to make a
beta version of Dolibarr, step by step.
- Check all files are commited.
- Update version/info in ChangeLog.
To generate a changelog of a major new version x.y.0 (from develop repo), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
To generate a changelog of a major new version x.y.0 (from x.y repo), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
- Update version/info in ChangeLog, for this you can:
To generate a changelog of a major new version x.y.0 (from a repo on branch develop), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
To generate a changelog of a major new version x.y.0 (from a repo on branch x.y repo), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log x.y.z-1.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
- To know number of lines changes: git diff --shortstat A B
- Update version number with x.y.z-w in htdocs/filefunc.inc.php
Recopy the content of the output file into the file ChangeLog.
- Note: To know number of lines changes: git diff --shortstat A B
- Update version number with x.y.z-w in file htdocs/filefunc.inc.php
- Commit all changes.
- Run makepack-dolibarr.pl to generate all packages.
@ -24,7 +52,6 @@ To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dol
(/home/dolibarr/wwwroot/files/lastbuild).
- Post a news on dolibarr.org/dolibarr.fr + social networks
- Send mail on mailings-list
***** Actions to do a RELEASE *****
@ -32,12 +59,13 @@ This files describe steps made by Dolibarr packaging team to make a
complete release of Dolibarr, step by step.
- Check all files are commited.
- Update version/info in ChangeLog.
To generate a changelog of a major new version x.y.0 (from develop repo), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
To generate a changelog of a major new version x.y.0 (from x.y repo), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
- Update version/info in ChangeLog, for this you can:
To generate a changelog of a major new version x.y.0 (from a repo on branch develop), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
To generate a changelog of a major new version x.y.0 (from a repo pn branch x.y), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log x.y.z-1.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
- To know number of lines changes: git diff --shortstat A B
- Update version number with x.y.z in htdocs/filefunc.inc.php
Recopy the content of the output file into the file ChangeLog.
- Note: To know the number of lines changes: git diff --shortstat A B
- Update version number with x.y.z in file htdocs/filefunc.inc.php
- Commit all changes.
- Run makepack-dolibarr.pl to generate all packages.
@ -52,4 +80,3 @@ To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dol
on server to point to new files (used by some web sites).
- Post a news on dolibarr.org/dolibarr.fr + social networks
- Send mail on mailings-list

View File

@ -227,6 +227,7 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/ticket
%_datadir/dolibarr/htdocs/user
%_datadir/dolibarr/htdocs/variants
%_datadir/dolibarr/htdocs/webhook
%_datadir/dolibarr/htdocs/webservices
%_datadir/dolibarr/htdocs/website
%_datadir/dolibarr/htdocs/workstation

View File

@ -54,7 +54,7 @@ BuildRequires: desktop-file-utils
Group: Applications/Productivity
Requires: apache-base, apache-mod_php, php-cgi, php-cli, php-bz2, php-gd, php-ldap, php-imap, php-mysqli, php-openssl, fonts-ttf-dejavu
Requires: mysql, mysql-client
%else%_datadir/dolibarr/htdocs/datapolicy
%else
%if 0%{?suse_version}
# Voir http://en.opensuse.org/openSUSE:Packaging_Conventions_RPM_Macros
Group: Productivity/Office/Management
@ -67,7 +67,7 @@ Requires: httpd, php >= 5.3.0, php-cli, php-gd, php-ldap, php-imap, php-mbstring
Requires: mysql-server, mysql
Requires: php-mysqli >= 4.1.0
%endif
%endif%_datadir/dolibarr/htdocs/eventorganization
%endif
%endif
@ -125,7 +125,7 @@ cui hai bisogno ed essere facile da usare.
%if 0%{?sles_version}
%{__rm} -rf $RPM_BUILD_ROOT
%{__mkdir} $RPM_BUILD_ROOT%_datadir/dolibarr/htdocs/datapolicy
%{__mkdir} $RPM_BUILD_ROOT%
%{__mkdir} $RPM_BUILD_ROOT%{_sysconfdir}
%{__mkdir} $RPM_BUILD_ROOT%{_sysconfdir}/%{name}
%else
@ -308,6 +308,7 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/ticket
%_datadir/dolibarr/htdocs/user
%_datadir/dolibarr/htdocs/variants
%_datadir/dolibarr/htdocs/webhook
%_datadir/dolibarr/htdocs/webservices
%_datadir/dolibarr/htdocs/website
%_datadir/dolibarr/htdocs/workstation

View File

@ -224,6 +224,7 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/ticket
%_datadir/dolibarr/htdocs/user
%_datadir/dolibarr/htdocs/variants
%_datadir/dolibarr/htdocs/webhook
%_datadir/dolibarr/htdocs/webservices
%_datadir/dolibarr/htdocs/website
%_datadir/dolibarr/htdocs/workstation

View File

@ -66,7 +66,7 @@ ed essere facile da usare.
Programmo web, progettato per poter fornire solo ciò di
cui hai bisogno ed essere facile da usare.
%_datadir/dolibarr/htdocs/webhook
#---- prep
%prep
@ -235,6 +235,7 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/ticket
%_datadir/dolibarr/htdocs/user
%_datadir/dolibarr/htdocs/variants
%_datadir/dolibarr/htdocs/webhook
%_datadir/dolibarr/htdocs/webservices
%_datadir/dolibarr/htdocs/website
%_datadir/dolibarr/htdocs/workstation

View File

@ -275,6 +275,13 @@ RESTLER:
with
$loaders = array_unique(static::$rogueLoaders, SORT_REGULAR);
* Replace CommentParser.php line 423
elseif (count($value) && is_numeric($value[0]))
with
elseif (count($value) && isset($value[0]) && is_numeric($value[0]))
+With swagger 2 provided into /explorer:

View File

@ -152,7 +152,7 @@ $user->rights->propal->creer=1;
$user->rights->propal->propal_advance->validate=1;
if (! empty($conf->global->PROPALE_ADDON) && is_readable(DOL_DOCUMENT_ROOT ."/core/modules/propale/".$conf->global->PROPALE_ADDON.".php")) {
if (!empty($conf->global->PROPALE_ADDON) && is_readable(DOL_DOCUMENT_ROOT ."/core/modules/propale/".$conf->global->PROPALE_ADDON.".php")) {
require_once DOL_DOCUMENT_ROOT ."/core/modules/propale/".$conf->global->PROPALE_ADDON.".php";
}

View File

@ -218,7 +218,7 @@ if ($date == 'all') {
}
// Replace database handler
if (! empty($argv[4])) {
if (!empty($argv[4])) {
$db->close();
unset($db);
$db=getDoliDBInstance($argv[4], $argv[5], $argv[6], $argv[7], $argv[8], $argv[9]);

View File

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

File diff suppressed because one or more lines are too long

View File

@ -2,13 +2,13 @@
Gestion escompte:
Sur une facture de 120 € TTC :
707xxx 100 € HT
44571x 20 € TVA
411xxx 120 € TTC
707xxx 100 € HT
44571x 20 € TVA
411xxx 120 € TTC
Le client règle rapidement et on lui accorde un escompte de 3% (120 € * 3% = 3.6 € TTC), on aura donc :
665000 3,00 € HT
44571x 0,60 € TVA
411xxx 3.60 € TVA
665000 3,00 € HT
44571x 0,60 € TVA
411xxx 3,60 € TTC
Et ça marche à linverse avec un fournisseur sauf que lon est en 775000 au lieu de 665000 pour escompte obtenus.

Binary file not shown.

View File

@ -1,3 +1,8 @@
QR-Code = Quick Response Code - is a two-dimensional / 2D- / Matrix-Barcode
ISO/IEC 18004
List of QR Code format we found on some invoices
------------------------------------------------
@ -15,3 +20,10 @@ https://www.pwc.com/m1/en/services/tax/me-tax-legal-news/2021/saudi-arabia-guide
https://www.tecklenborgh.com/post/ksa-zatca-publishes-guide-on-how-to-develop-a-fatoora-compliant-qr-code
Method to encode/decode ZATCA string is available in test/phpunit/BarcodeTest.php
* FOR QR-Bill in switzerland
----------------------------
Syntax of QR Code https://www.swiss-qr-invoice.org/fr/
Syntax of complentary field named "structured information of invoice S1": https://www.swiss-qr-invoice.org/downloads/qr-bill-s1-syntax-fr.pdf
To test/validate: https://www.swiss-qr-invoice.org/validator/

View File

@ -31,60 +31,60 @@ Here is the list of country codes or system:
List
====
00 - 13 UCC (U.S.A / États-Unis & Canada)
00 - 13 UCC (U.S.A / États-Unis & Canada)
20 - 29 Flag for internal numbering / Codification interne en magasin
30 - 37 GENCOD-EAN France
380 BCCI (Bulgaria)
383 SANA (Slovenia)
385 CRO-EAN (Croatia)
387 EAN-BIH (Bosnia-Herzegovina)
400-440 CCG (Allemagne/Germany)
400-440 CCG (DE/Germany/Allemagne)
45 + 49 Distribution Code Center - DCC (Japan)
460-469 UNISCAN - EAN Russia (Federation de Russie)
471 CAN Taiwan
474 EAN Estonia
475 EAN Latvia
476 EAN Azerbaijan
477 EAN Lithuania
478 EAN Uzbekistan
479 EAN Sri Lanka
474 EAN Estonia
475 EAN Latvia
476 EAN Azerbaijan
477 EAN Lithuania
478 EAN Uzbekistan
479 EAN Sri Lanka
480 PANC Philippines
481 EAN Belarus
482 EAN Ukraine
484 EAN Moldova
485 EAN Armenia
486 EAN Georgia
487 EAN Kazakhstan
481 EAN Belarus
482 EAN Ukraine
484 EAN Moldova
485 EAN Armenia
486 EAN Georgia
487 EAN Kazakhstan
489 HKANA Hong Kong
50 E Centre UK - United Kingdom
520 HELLCAN-EAN HELLAS (Grece)
528 EAN Liban
529 EAN Chypre
531 EAN-MAC (FYR Macedonie)
535 EAN Malte
539 EAN Irlande
54 ICODIF/EAN Belgique. Luxembourg
560 CODIPOR (Portugal)
569 EAN Islande
57 EAN Danemark
590 EAN Pologne
594 EAN Roumanie
599 H.A.P.M.H. (Hongrie)
600 - 601 EAN Afrique du Sud
609 EAN Ile Maurice
611 EAN Maroc
613 EAN Algerie
619 Tunicode (Tunisie)
621 EAN Syrie
622 EAN Egypte
625 EAN Jordanie
626 EAN Iran
628 EAN Arabie Saoudite
64 EAN Finlande
690 - 693 Article Numbering Centre of China - ANCC (Chine)
70 EAN Norge (Norvege)
729 Israeli Bar Code Association <EFBFBD> EAN Israel
73 EAN Suede
520 HELLCAN-EAN HELLAS - Greece
528 EAN Lebanon
529 EAN Cyprus
531 EAN-MAC (FYR Macedonia)
535 EAN Malta
539 EAN Ireland
54 ICODIF/EAN Belgium & Luxembourg
560 CODIPOR (Portugal)
569 EAN Iceland/Islande
57 EAN Denmark
590 EAN Poland
594 EAN Romania
599 H.A.P.M.H. (Hungary)
600-601 EAN South Africa
609 EAN Mauritius Island
611 EAN Morocco
613 EAN Algeria
619 Tunicode (Tunisia)
621 EAN Syria
622 EAN Egypt
625 EAN Jordan/Jordanie
626 EAN Iran
628 EAN Saudi Arabia
64 EAN Finland
690-693 ANCC - Article Numbering Centre of China
70 EAN Norge (Norvege)
729 Israeli Bar Code Association - EAN Israel
73 EAN Suede
740 EAN Guatemala
741 EAN El Salvador
742 ICCC (Honduras)
@ -93,7 +93,7 @@ List
746 746 EAN Republique Dominicaine
750 AMECE (Mexique)
759 EAN Venezuela
76 EAN (Schweiz, Suisse, Svizzera)
76 EAN (Schweiz, Suisse, Svizzera)
770 IAC (Colombie)
773 EAN Uruguay
775 APC - EAN Peru (Perou)
@ -103,15 +103,15 @@ List
784 EAN Paraguay
786 ECOP (Equateur)
789 EAN Bresil
80 <EFBFBD> 83 INDICOD (Italie)
84 AECOC (Espagne)
80 - 83 INDICOD (Italy)
84 AECOC (Espagne)
850 Camera de Comercio de la Republica de Cuba (Cuba)
858 EAN Slovaquie
859 EAN Republique Tcheque
860 EAN YU (Yougoslavie)
867 EAN DPR Korea (Coree du Nord)
869 Union of Chambers of Commerce of Turkey (Turquie)
87 EAN Nederland (Hollande)
87 EAN Nederland (Hollande)
880 EAN Korea (Coree du Sud)
885 EAN Thailande
888 SANC (Singapour)
@ -119,11 +119,11 @@ List
893 EAN Vietnam
899 EAN Indonesie
90 - 91 EAN Autriche
93 EAN Australie
94 EAN Nouvelle Zelande
93 EAN Australie
94 EAN Nouvelle Zelande
955 Malaysian Article Numbering Council (MANC) - Malaisie
977 Publications sirielles (ISSN)
978 - 979 Livres (ISBN)
980 Refus de remboursement
981 - 982 Coupons (monnaie courante)
99 Coupons
99 Coupons

View File

@ -4,4 +4,5 @@ terms
(en) VAT = Value Added Tax
(fr) TVA = Taxe sur la Valeur Ajouté
(es) NIF / CIF
(de) USt / MwSt
(de) USt / MwSt = UmsatzSteuer / Mehrwertsteuer
(it) IVA

View File

@ -0,0 +1,10 @@
VAT Rates
---------
https://www.taxrates.cc/index.html
https://en.wikipedia.org/wiki/List_of_countries_by_tax_rates
For India: VAT=IGST / CGST=Localtax1 / SGST=Localtax2
see:
https://cleartax.in/s/what-is-sgst-cgst-igst
https://www.mastersindia.co/blog/what-is-cgst-sgst-igst-and-ugst/

View File

@ -1,8 +0,0 @@
VAT Rates
---------
http://www.taxrates.cc/index.html
https://en.wikipedia.org/wiki/List_of_countries_by_tax_rates
For India: VAT=IGST/CGST=Localtax1/SGST=Localtax2: https://cleartax.in/s/what-is-sgst-cgst-igst

View File

@ -135,7 +135,7 @@
<rule ref="Generic.Metrics.CyclomaticComplexity">
<properties>
<property name="complexity" value="250" />
<property name="absoluteComplexity" value="300" />
<property name="absoluteComplexity" value="400" />
</properties>
</rule>
<rule ref="Generic.Metrics.NestingLevel">

View File

@ -7,7 +7,7 @@
# To run the fix manually: cd ~/git/dolibarr; phpcbf -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true "fileordir"
PROJECT=`php -r "echo dirname(dirname(dirname(realpath('$0'))));"`
STAGED_FILES_CMD=`git diff --cached --name-only --diff-filter=ACMR HEAD | grep \\\\.php`
STAGED_FILES_CMD=`git diff --cached --name-only --diff-filter=ACMR HEAD | grep -v '/includes/'| grep \\\\.php`
DIRPHPCS=""
AUTOFIX=1

View File

@ -10,6 +10,7 @@
# Syntax
if [ "x$1" != "xlist" -a "x$1" != "xfix" ]
then
echo "Detect .sh and .spec files that does not contains any tab inside"
echo "Usage: fixnotabfiles.sh [list|fix]"
fi

View File

@ -487,7 +487,7 @@ function pg2mysql(&$input, &$arrayofprimaryalreadyintabledef, $header = true)
$pkey = $line;
$linenumber ++;
if (! empty($lines[$linenumber])) {
if (!empty($lines[$linenumber])) {
$line = $lines[$linenumber];
} else {
$line = '';
@ -517,7 +517,7 @@ function pg2mysql(&$input, &$arrayofprimaryalreadyintabledef, $header = true)
if (substr($line, 0, 12) == "CREATE INDEX") {
$matches = array();
preg_match('/CREATE INDEX "?([a-zA-Z0-9_]*)"? ON "?([a-zA-Z0-9_\.]*)"? USING btree \((.*)\);/', $line, $matches);
if (! empty($matches[3])) {
if (!empty($matches[3])) {
$indexname = $matches[1];
$tablename = str_replace('public.', '', $matches[2]);
$columns = $matches[3];
@ -529,7 +529,7 @@ function pg2mysql(&$input, &$arrayofprimaryalreadyintabledef, $header = true)
if (substr($line, 0, 19) == "CREATE UNIQUE INDEX") {
$matches = array();
preg_match('/CREATE UNIQUE INDEX "?([a-zA-Z0-9_]*)"? ON "?([a-zA-Z0-9_\.]*)"? USING btree \((.*)\);/', $line, $matches);
if (! empty($matches[3])) {
if (!empty($matches[3])) {
$indexname = $matches[1];
$tablename = str_replace('public.', '', $matches[2]);
$columns = str_replace('"', '', $matches[3]);

View File

@ -17,14 +17,14 @@ fi
# To detec
if [ "x$1" = "xlist" ]
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 '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 'custom\/' | grep -v 'documents\/website' | grep -v 'documents\/medias' | grep -v 'documents\/sellyoursaas' | grep -v 'htdocs\/includes' | 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 "CRLF" | 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 "CRLF" | grep -v 'custom\/' | grep -v 'documents\/website' | grep -v 'documents\/medias' | grep -v 'documents\/sellyoursaas' | grep -v 'htdocs\/includes' | grep CRLF
fi
# To convert
if [ "x$1" = "xfix" ]
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 'custom\/' | grep -v 'documents\/website' | grep -v 'documents\/medias' | grep -v 'documents\/sellyoursaas' | 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 "CRLF" | grep -v 'custom\/' | grep -v 'documents\/website' | grep -v 'documents\/medias' | grep -v 'documents\/sellyoursaas' | grep CRLF | awk -F':' '{ print $1 }' `
do
echo "Fix file $fic"
dos2unix "$fic"

View File

@ -24,6 +24,7 @@ fi
if [ "x$1" = "xfix" ]
then
find ./htdocs -type f -iname "*.php" -exec chmod a-x {} \;
find ./htdocs/install/ -type d -exec chmod ug+rw {} \;
chmod a+x ./scripts/*/*.php
chmod a+x ./scripts/*/*.sh
chmod g-w ./scripts/*/*.php

View File

@ -39,13 +39,14 @@ optimize_image()
max_input_size=$(expr $max_input_size + $input_file_size)
if [ "${1##*.}" = "png" ]; then
#optipng -o1 -clobber -quiet $1 -out $2.firstpass
optipng -o1 -quiet $1 -out $2.firstpass
pngcrush -q -rem alla -reduce $2.firstpass $2 >/dev/null
rm -fr $2.firstpass
#optipng -o1 -clobber -quiet "$1" -out "$2.firstpass"
echo optipng -o1 -quiet "$1" -out "$2.firstpass"
optipng -o1 -quiet "$1" -out "$2.firstpass"
pngcrush -q -rem alla -reduce "$2.firstpass" "$2" >/dev/null
rm -fr "$2.firstpass"
fi
if [ "${1##*.}" = "jpg" -o "${1##*.}" = "jpeg" ]; then
jpegtran -copy none -progressive $1 > $2
jpegtran -copy none -progressive "$1" > $2
fi
output_file_size=$(stat -c%s "$2")
@ -120,8 +121,8 @@ main()
# Search of all jpg/jpeg/png in $INPUT
# We remove images from $OUTPUT if $OUTPUT is a subdirectory of $INPUT
echo "Scan $INPUT to find images"
IMAGES=$(find $INPUT -regextype posix-extended -regex '.*\.(jpg|jpeg|png)' | grep -v $OUTPUT)
echo "Scan $INPUT to find images with find $INPUT -regextype posix-extended -regex '.*\.(jpg|jpeg|png)' | grep -v '/gource/' | grep -v '/includes/' | grep -v '/custom/' | grep -v $OUTPUT"
IMAGES=$(find $INPUT -regextype posix-extended -regex '.*\.(jpg|jpeg|png)' | grep -v '/gource/' | grep -v '/includes/' | grep -v '/custom/' | grep -v '/documents/' | grep -v $OUTPUT)
if [ "$QUIET" == "0" ]; then
echo --- Optimizing $INPUT ---
@ -135,11 +136,11 @@ main()
printf '%*.*s' 0 $((linelength - ${#filename} - ${#sDone} )) "$pad"
fi
optimize_image $CURRENT_IMAGE $OUTPUT/$filename
optimize_image "$CURRENT_IMAGE" "$OUTPUT/$filename"
# Replace file
if [[ "$INPLACE" == "1" ]]; then
mv $OUTPUT/$filename $CURRENT_IMAGE
mv "$OUTPUT/$filename" "$CURRENT_IMAGE"
fi
if [ "$QUIET" == "0" ]; then

View File

@ -1,7 +1,6 @@
<?php
/*spl_autoload_register(function ($class_name) {
var_dump('class='.$class_name);
//var_dump('class='.$class_name);
require $class_name;
});
*/

View File

@ -309,11 +309,11 @@ class autoTranslator
{
// We want to be sure that src_lang and dest_lang are using 2 chars only
$tmp=explode('_', $src_lang);
if (! empty($tmp[1]) && $tmp[0] == $tmp[1]) {
if (!empty($tmp[1]) && $tmp[0] == $tmp[1]) {
$src_lang=$tmp[0];
}
$tmp=explode('_', $dest_lang);
if (! empty($tmp[1]) && $tmp[0] == $tmp[1]) {
if (!empty($tmp[1]) && $tmp[0] == $tmp[1]) {
$dest_lang=$tmp[0];
}
@ -349,7 +349,7 @@ class autoTranslator
// now, process the JSON string
$json = json_decode($body, true);
if ((! empty($json['responseStatus']) && $json['responseStatus'] != 200)
if ((!empty($json['responseStatus']) && $json['responseStatus'] != 200)
|| count($json['data']['translations']) == 0) {
print "Error: ".$json['responseStatus']." ".$url."\n";
return false;

View File

@ -221,7 +221,7 @@ foreach ($dups as $string => $pages) {
// Loop on each line keword was found into file.
$listoffilesforthisentry=array();
foreach ($lines as $line => $translatedvalue) {
if (! empty($listoffilesforthisentry[$file])) {
if (!empty($listoffilesforthisentry[$file])) {
$duplicateinsamefile=1;
}
$listoffilesforthisentry[$file]=1;
@ -300,7 +300,7 @@ if ($web) {
// STEP 2 - Search key not used
if ((! empty($_REQUEST['unused']) && $_REQUEST['unused'] == 'true') || (isset($argv[1]) && $argv[1]=='unused=true')) {
if ((!empty($_REQUEST['unused']) && $_REQUEST['unused'] == 'true') || (isset($argv[1]) && $argv[1]=='unused=true')) {
print "***** Strings in en_US that are never used:\n";
$unused=array();

View File

@ -303,8 +303,8 @@ foreach ($filesToProcess as $fileToProcess) {
// 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]
&& ! empty($aEnglish[$key]) && $aSecondary[$key] != $aEnglish[$key])
if ((!empty($aSecondary[$key]) && $aSecondary[$key] != $aPrimary[$key]
&& !empty($aEnglish[$key]) && $aSecondary[$key] != $aEnglish[$key])
|| in_array($key, $arrayofkeytoalwayskeep) || preg_match('/^FormatDate/', $key) || preg_match('/^FormatHour/', $key)
) {
//print "Key $key differs (aSecondary=".$aSecondary[$key].", aPrimary=".$aPrimary[$key].", aEnglish=".$aEnglish[$key].") so we add it into new secondary language (line: $cnt).\n";

View File

@ -23,6 +23,7 @@
* \brief List accounting account
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
@ -30,7 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
// Load translation files required by the page
$langs->loadLangs(array("compta", "bills", "admin", "accountancy", "salaries"));
$langs->loadLangs(array('accountancy', 'admin', 'bills', 'compta', 'salaries'));
$mesg = '';
$action = GETPOST('action', 'aZ09');
@ -52,14 +53,14 @@ $confirm = GETPOST('confirm', 'alpha');
$chartofaccounts = GETPOST('chartofaccounts', 'int');
$permissiontoadd = !empty($user->rights->accounting->chartofaccount);
$permissiontodelete = !empty($user->rights->accounting->chartofaccount);
$permissiontoadd = $user->hasRight('accounting', 'chartofaccount');
$permissiontodelete = $user->hasRight('accounting', 'chartofaccount');
// Security check
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->chartofaccount)) {
if (!$user->hasRight('accounting', 'chartofaccount')) {
accessforbidden();
}
@ -97,6 +98,9 @@ if ($conf->global->MAIN_FEATURES_LEVEL < 2) {
$accounting = new AccountingAccount($db);
// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array
$hookmanager->initHooks(array('accountancyadminaccount'));
/*
* Actions
@ -109,8 +113,8 @@ if (!GETPOST('confirmmassaction', 'alpha')) {
$massaction = '';
}
$parameters = array();
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been monowraponalldified by some hooks
$parameters = array('chartofaccounts' => $chartofaccounts, 'permissiontoadd' => $permissiontoadd, 'permissiontodelete' => $permissiontodelete);
$reshook = $hookmanager->executeHooks('doActions', $parameters, $accounting, $action); // Note that $action and $object may have been monowraponalldified by some hooks
if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
}
@ -294,7 +298,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
}
// List of mass actions available
if ($user->rights->accounting->chartofaccount) {
if ($user->hasRight('accounting', 'chartofaccount')) {
$arrayofmassactions['predelete'] = '<span class="fa fa-trash paddingrightonly"></span>'.$langs->trans("Delete");
}
if (in_array($massaction, array('presend', 'predelete', 'closed'))) {
@ -350,6 +354,8 @@ if ($resql) {
</script>';
}
$newcardbutton = '';
print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
@ -396,6 +402,11 @@ if ($resql) {
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>';
$parameters = array('chartofaccounts' => $chartofaccounts, 'permissiontoadd' => $permissiontoadd, 'permissiontodelete' => $permissiontodelete);
$reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $accounting, $action); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
print '<br>';
$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
@ -588,7 +599,7 @@ if ($resql) {
// Action
print '<td class="center nowraponall">';
if ($user->rights->accounting->chartofaccount) {
if ($user->hasRight('accounting', 'chartofaccount')) {
print '<a class="editfielda" href="./card.php?action=update&token='.newToken().'&id='.$obj->rowid.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?'.$param).'">';
print img_edit();
print '</a>';

View File

@ -32,6 +32,7 @@
* \brief Page to administer model of chart of accounts
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
@ -39,12 +40,12 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
if (!empty($conf->accounting->enabled)) {
if (isModEnabled('accounting')) {
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
}
// Load translation files required by the page
$langs->loadLangs(array("errors", "admin", "companies", "resource", "holiday", "compta", "accountancy", "hrm"));
$langs->loadLangs(array('accountancy', 'admin', 'companies', 'compta', 'errors', 'holiday', 'hrm', 'resource'));
$action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view';
$confirm = GETPOST('confirm', 'alpha');
@ -78,7 +79,7 @@ $search_country_id = GETPOST('search_country_id', 'int');
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->chartofaccount)) {
if (!$user->hasRight('accounting', 'chartofaccount')) {
accessforbidden();
}
@ -126,7 +127,7 @@ $tabrowid[31] = "";
// Condition to show dictionary in setup page
$tabcond = array();
$tabcond[31] = !empty($conf->accounting->enabled);
$tabcond[31] = isModEnabled('accounting');
// List of help for fields
$tabhelp = array();
@ -674,7 +675,7 @@ if ($id) {
// Can an entry be erased or disabled ?
$iserasable = 1; $canbedisabled = 1; $canbemodified = 1; // true by default
$url = $_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')).'&code='.(!empty($obj->code) ?urlencode($obj->code) : '');
$url = $_SERVER["PHP_SELF"].'?token='.newToken().($page ? '&page='.$page : '').'&sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')).'&code='.(!empty($obj->code) ?urlencode($obj->code) : '');
if ($param) {
$url .= '&'.$param;
}

View File

@ -23,6 +23,7 @@
* \brief Card of accounting account
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
@ -32,7 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
$error = 0;
// Load translation files required by the page
$langs->loadLangs(array("bills", "accountancy", "compta"));
$langs->loadLangs(array('accountancy', 'bills', 'compta'));
$action = GETPOST('action', 'aZ09');
$backtopage = GETPOST('backtopage', 'alpha');
@ -48,7 +49,7 @@ $label = GETPOST('label', 'alpha');
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->chartofaccount)) {
if (!$user->hasRight('accounting', 'chartofaccount')) {
accessforbidden();
}
@ -66,7 +67,7 @@ if (GETPOST('cancel', 'alpha')) {
exit;
}
if ($action == 'add' && $user->rights->accounting->chartofaccount) {
if ($action == 'add' && $user->hasRight('accounting', 'chartofaccount')) {
if (!$cancel) {
if (!$account_number) {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AccountNumber")), null, 'errors');
@ -127,7 +128,7 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) {
}
}
}
} elseif ($action == 'edit' && $user->rights->accounting->chartofaccount) {
} elseif ($action == 'edit' && $user->hasRight('accounting', 'chartofaccount')) {
if (!$cancel) {
if (!$account_number) {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AccountNumber")), null, 'errors');
@ -168,10 +169,13 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) {
$object->labelshort = GETPOST('labelshort', 'alpha');
$result = $object->update($user);
if ($result > 0) {
$urltogo = $backtopage ? $backtopage : ($_SERVER["PHP_SELF"] . "?id=" . $id);
header("Location: " . $urltogo);
exit();
} elseif ($result == -2) {
setEventMessages($langs->trans("ErrorAccountNumberAlreadyExists", $object->account_number), null, 'errors');
} else {
setEventMessages($object->error, null, 'errors');
}
@ -181,7 +185,7 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) {
header("Location: ".$urltogo);
exit();
}
} elseif ($action == 'delete' && $user->rights->accounting->chartofaccount) {
} elseif ($action == 'delete' && $user->hasRight('accounting', 'chartofaccount')) {
$result = $object->fetch($id);
if (!empty($object->id)) {
@ -300,7 +304,7 @@ if ($action == 'create') {
// Edit mode
if ($action == 'update') {
print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), 0, 'billr');
print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), 0, 'accounting_account');
print '<form name="update" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n";
print '<input type="hidden" name="token" value="'.newToken().'">';
@ -368,7 +372,7 @@ if ($action == 'create') {
// View mode
$linkback = '<a href="'.DOL_URL_ROOT.'/accountancy/admin/account.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), -1, 'billr');
print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), -1, 'accounting_account');
dol_banner_tab($object, 'ref', $linkback, 1, 'account_number', 'ref');
@ -416,13 +420,13 @@ if ($action == 'create') {
*/
print '<div class="tabsAction">';
if (!empty($user->rights->accounting->chartofaccount)) {
if ($user->hasRight('accounting', 'chartofaccount')) {
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=update&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Modify').'</a>';
} else {
print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans('Modify').'</a>';
}
if (!empty($user->rights->accounting->chartofaccount)) {
if ($user->hasRight('accounting', 'chartofaccount')) {
print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id.'">'.$langs->trans('Delete').'</a>';
} else {
print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotAllowed")).'">'.$langs->trans('Delete').'</a>';

View File

@ -1,6 +1,6 @@
<?php
/* Copyright (C) 2016 Jamal Elbaz <jamelbaz@gmail.pro>
* Copyright (C) 2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
/* Copyright (C) 2016 Jamal Elbaz <jamelbaz@gmail.pro>
* Copyright (C) 2017-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,6 +22,7 @@
* \brief Page to assign mass categories to accounts
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancycategory.class.php';
@ -44,7 +45,7 @@ if ($cat_id == 0) {
}
// Security check
if (empty($user->rights->accounting->chartofaccount)) {
if (!$user->hasRight('accounting', 'chartofaccount')) {
accessforbidden();
}
@ -124,7 +125,8 @@ if (!empty($cat_id)) {
$arraykeyvalue = array();
foreach ($accountingcategory->lines_cptbk as $key => $val) {
$arraykeyvalue[length_accountg($val->numero_compte)] = length_accountg($val->numero_compte).' ('.$val->label_compte.($val->doc_ref ? ' '.$val->doc_ref : '').')';
$doc_ref = !empty($val->doc_ref) ? $val->doc_ref : '';
$arraykeyvalue[length_accountg($val->numero_compte)] = length_accountg($val->numero_compte) . ' - ' . $val->label_compte . ($doc_ref ? ' '.$doc_ref : '');
}
if (is_array($accountingcategory->lines_cptbk) && count($accountingcategory->lines_cptbk) > 0) {

View File

@ -22,6 +22,7 @@
* \brief Page to administer data tables
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
@ -42,7 +43,7 @@ $rowid = GETPOST('rowid', 'alpha');
$code = GETPOST('code', 'alpha');
// Security access
if (empty($user->rights->accounting->chartofaccount)) {
if (!$user->hasRight('accounting', 'chartofaccount')) {
accessforbidden();
}
@ -111,7 +112,7 @@ $tabrowid[32] = "";
// Condition to show dictionary in setup page
$tabcond = array();
$tabcond[32] = !empty($conf->accounting->enabled);
$tabcond[32] = isModEnabled('accounting');
// List of help for fields
$tabhelp = array();
@ -875,7 +876,7 @@ function fieldListAccountingCategories($fieldlist, $obj = '', $tabname = '', $co
$formadmin = new FormAdmin($db);
$formcompany = new FormCompany($db);
if (!empty($conf->accounting->enabled)) {
if (isModEnabled('accounting')) {
$formaccounting = new FormAccounting($db);
}
@ -885,9 +886,11 @@ function fieldListAccountingCategories($fieldlist, $obj = '', $tabname = '', $co
$fieldname = 'country';
if ($context == 'add') {
$fieldname = 'country_id';
print $form->select_country(GETPOST('country_id', 'int'), $fieldname, '', 28, 'maxwidth200 maxwidthonsmartphone');
$preselectcountrycode = GETPOSTISSET('country_id') ? GETPOST('country_id', 'int') : $mysoc->country_code;
print $form->select_country($preselectcountrycode, $fieldname, '', 28, 'maxwidth200 maxwidthonsmartphone');
} else {
print $form->select_country((!empty($obj->country_code) ? $obj->country_code : (!empty($obj->country) ? $obj->country : $mysoc->country_code)), $fieldname, '', 28, 'maxwidth200 maxwidthonsmartphone');
$preselectcountrycode = (empty($obj->country_code) ? (empty($obj->country) ? $mysoc->country_code : $obj->country) : $obj->country_code);
print $form->select_country($preselectcountrycode, $fieldname, '', 28, 'maxwidth200 maxwidthonsmartphone');
}
print '</td>';
} elseif ($fieldlist[$field] == 'country_id') {

View File

@ -22,6 +22,7 @@
* \brief Setup page to configure accounting expert module
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
@ -31,7 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
$langs->loadLangs(array("compta", "admin", "accountancy"));
// Security check
if (empty($user->rights->accounting->chartofaccount)) {
if (!$user->hasRight('accounting', 'chartofaccount')) {
accessforbidden();
}

View File

@ -38,7 +38,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
$langs->loadLangs(array("compta", "bills", "admin", "accountancy", "salaries", "loan"));
// Security check
if (empty($user->rights->accounting->chartofaccount)) {
if (!$user->hasRight('accounting', 'chartofaccount')) {
accessforbidden();
}
@ -81,31 +81,31 @@ $list_account[] = '---Others---';
$list_account[] = 'ACCOUNTING_VAT_BUY_ACCOUNT';
$list_account[] = 'ACCOUNTING_VAT_SOLD_ACCOUNT';
$list_account[] = 'ACCOUNTING_VAT_PAY_ACCOUNT';
if ($conf->banque->enabled) {
if (isModEnabled('banque')) {
$list_account[] = 'ACCOUNTING_ACCOUNT_TRANSFER_CASH';
}
if ($conf->don->enabled) {
if (isModEnabled('don')) {
$list_account[] = 'DONATION_ACCOUNTINGACCOUNT';
}
if ($conf->adherent->enabled) {
if (isModEnabled('adherent')) {
$list_account[] = 'ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT';
}
if ($conf->loan->enabled) {
if (isModEnabled('loan')) {
$list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_CAPITAL';
$list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INTEREST';
$list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INSURANCE';
}
if ($conf->societe->enabled) {
$list_account[] = 'ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT';
}
$list_account[] = 'ACCOUNTING_ACCOUNT_SUSPENSE';
if (isModEnabled('societe')) {
$list_account[] = '---Deposits---';
}
/*
* Actions
*/
if ($action == 'update') {
$error = 0;
// Process $list_account_main
foreach ($list_account_main as $constname) {
$constvalue = GETPOST($constname, 'alpha');
@ -113,7 +113,7 @@ if ($action == 'update') {
$error++;
}
}
// Process $list_account
foreach ($list_account as $constname) {
$reg = array();
if (preg_match('/---(.*)---/', $constname, $reg)) { // This is a separator
@ -127,6 +127,19 @@ if ($action == 'update') {
}
}
$constname = 'ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT';
$constvalue = GETPOST($constname, 'int');
if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
$error++;
}
$constname = 'ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT';
$constvalue = GETPOST($constname, 'int');
if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
$error++;
}
if (!$error) {
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
} else {
@ -134,6 +147,34 @@ if ($action == 'update') {
}
}
if ($action == 'setACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT') {
$setDisableAuxiliaryAccountOnCustomerDeposit = GETPOST('value', 'int');
$res = dolibarr_set_const($db, "ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT", $setDisableAuxiliaryAccountOnCustomerDeposit, 'yesno', 0, '', $conf->entity);
if (!($res > 0)) {
$error++;
}
if (!$error) {
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
} else {
setEventMessages($langs->trans("Error"), null, 'mesgs');
}
}
if ($action == 'setACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT') {
$setDisableAuxiliaryAccountOnSupplierDeposit = GETPOST('value', 'int');
$res = dolibarr_set_const($db, "ACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT", $setDisableAuxiliaryAccountOnSupplierDeposit, 'yesno', 0, '', $conf->entity);
if (!($res > 0)) {
$error++;
}
if (!$error) {
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
} else {
setEventMessages($langs->trans("Error"), null, 'mesgs');
}
}
/*
* View
@ -180,7 +221,8 @@ foreach ($list_account_main as $key) {
print '</td>';
// Value
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');
$key_value = getDolGlobalString($key);
print $formaccounting->select_account($key_value, $key, 1, '', 1, 1, 'minwidth100 maxwidth300 maxwidthonsmartphone', 'accountsmain');
print '</td>';
print '</tr>';
}
@ -232,10 +274,64 @@ foreach ($list_account as $key) {
}
// Customer deposit account
print '<tr class="oddeven value">';
// Param
print '<td>';
print img_picto('', 'bill', 'class="pictofixedwidth"') . $langs->trans('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT');
print '</td>';
// Value
print '<td class="right">'; // Do not force class=right, or it align also the content of the select box
print $formaccounting->select_account(getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT'), 'ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT', 1, '', 1, 1, 'minwidth100 maxwidth300 maxwidthonsmartphone', 'accounts');
print '</td>';
print '</tr>';
if (isModEnabled('societe') && getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT') && getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT') != '-1') {
print '<tr class="oddeven">';
print '<td>' . img_picto('', 'bill', 'class="pictofixedwidth"') . $langs->trans("UseAuxiliaryAccountOnCustomerDeposit") . '</td>';
if (getDolGlobalInt('ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT')) {
print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT&value=0">';
print img_picto($langs->trans("Activated"), 'switch_on', '', false, 0, 0, '', 'warning');
print '</a></td>';
} else {
print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT&value=1">';
print img_picto($langs->trans("Disabled"), 'switch_off');
print '</a></td>';
}
print '</tr>';
}
// Supplier deposit account
print '<tr class="oddeven value">';
// Param
print '<td>';
print img_picto('', 'supplier_invoice', 'class="pictofixedwidth"') . $langs->trans('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT');
print '</td>';
// Value
print '<td class="right">'; // Do not force class=right, or it align also the content of the select box
print $formaccounting->select_account(getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT'), 'ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT', 1, '', 1, 1, 'minwidth100 maxwidth300 maxwidthonsmartphone', 'accounts');
print '</td>';
print '</tr>';
if (isModEnabled('societe') && getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT') && getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT') != '-1') {
print '<tr class="oddeven">';
print '<td>' . img_picto('', 'supplier_invoice', 'class="pictofixedwidth"') . $langs->trans("UseAuxiliaryAccountOnSupplierDeposit") . '</td>';
if (getDolGlobalInt('ACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT')) {
print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT&value=0">';
print img_picto($langs->trans("Activated"), 'switch_on', '', false, 0, 0, '', 'warning');
print '</a></td>';
} else {
print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT&value=1">';
print img_picto($langs->trans("Disabled"), 'switch_off');
print '</a></td>';
}
print '</tr>';
}
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 button-edit" name="button" value="'.$langs->trans('Save').'"></div>';
print '</form>';

View File

@ -1,11 +1,11 @@
<?php
/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2017-2018 Frédéric France <frederic.france@netlogic.fr>
/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2017-2018 Frédéric France <frederic.france@netlogic.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -36,7 +36,7 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancyexport.class.php';
$langs->loadLangs(array("compta", "bills", "admin", "accountancy"));
// Security access
if (empty($user->rights->accounting->chartofaccount)) {
if (!$user->hasRight('accounting', 'chartofaccount')) {
accessforbidden();
}
@ -47,7 +47,8 @@ $main_option = array(
'ACCOUNTING_EXPORT_PREFIX_SPEC',
);
$configuration = AccountancyExport::getTypeConfig();
$accountancyexport = new AccountancyExport($db);
$configuration = $accountancyexport->getTypeConfig();
$listparam = $configuration['param'];
@ -117,7 +118,7 @@ if ($action == 'update') {
if (!$error) {
// reload
$configuration = AccountancyExport::getTypeConfig();
$configuration = $accountancyexport->getTypeConfig();
$listparam = $configuration['param'];
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
} else {
@ -210,7 +211,7 @@ if ($num) {
// Value
print '<td>';
print '<input type="text" size="20" id="'.$key.'" name="'.$key.'" value="'.$conf->global->$key.'">';
print '<input type="text" size="20" id="'.$key.'" name="'.$key.'" value="'.getDolGlobalString($key).'">';
print '</td></tr>';
}
}
@ -237,8 +238,8 @@ if (!$conf->use_javascript_ajax) {
print "</td>";
} else {
print '<td>';
$listmodelcsv = AccountancyExport::getType();
print $form->selectarray("ACCOUNTING_EXPORT_MODELCSV", $listmodelcsv, $conf->global->ACCOUNTING_EXPORT_MODELCSV, 0, 0, 0, '', 0, 0, 0, '', '', 1);
$listmodelcsv = $accountancyexport->getType();
print $form->selectarray("ACCOUNTING_EXPORT_MODELCSV", $listmodelcsv, getDolGlobalString('ACCOUNTING_EXPORT_MODELCSV'), 0, 0, 0, '', 0, 0, 0, '', '', 1);
print '</td>';
}

View File

@ -21,6 +21,7 @@
* \brief Setup page to configure fiscal year
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/fiscalyear.class.php';
@ -121,7 +122,7 @@ if ($result) {
$i = 0;
$addbutton .= dolGetButtonTitle($langs->trans('NewFiscalYear'), '', 'fa fa-plus-circle', 'fiscalyear_card.php?action=create', '', $user->rights->accounting->fiscalyear->write);
$addbutton .= dolGetButtonTitle($langs->trans('NewFiscalYear'), '', 'fa fa-plus-circle', 'fiscalyear_card.php?action=create', '', $user->hasRight('accounting', 'fiscalyear', 'write'));
$title = $langs->trans('AccountingPeriods');

View File

@ -22,6 +22,7 @@
* \brief Page to show a fiscal year
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/fiscalyear.lib.php';
@ -299,7 +300,7 @@ if ($action == 'create') {
/*
* Action bar
*/
if (!empty($user->rights->accounting->fiscalyear->write)) {
if ($user->hasRight('accounting', 'fiscalyear', 'write')) {
print '<div class="tabsAction">';
print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=edit&token='.newToken().'&id='.$id.'">'.$langs->trans('Modify').'</a>';

View File

@ -21,6 +21,7 @@
* \brief Page to show info of a fiscal year
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/fiscalyear.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';

View File

@ -29,6 +29,7 @@
* \brief Setup page to configure accounting expert module
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
@ -38,7 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
$langs->loadLangs(array("compta", "bills", "admin", "accountancy", "other"));
// Security access
if (empty($user->rights->accounting->chartofaccount)) {
if (!$user->hasRight('accounting', 'chartofaccount')) {
accessforbidden();
}
@ -358,7 +359,7 @@ foreach ($list as $key) {
print '<td>'.$label.'</td>';
// Value
print '<td class="right">';
print '<input type="text" class="maxwidth100" id="'.$key.'" name="'.$key.'" value="'.$conf->global->$key.'">';
print '<input type="text" class="maxwidth50 right" id="'.$key.'" name="'.$key.'" value="'.getDolGlobalString($key).'">';
print '</td>';
print '</tr>';
@ -409,12 +410,12 @@ foreach ($list_binding as $key) {
// Value
print '<td class="right">';
if ($key == 'ACCOUNTING_DATE_START_BINDING') {
print $form->selectDate(($conf->global->$key ? $db->idate($conf->global->$key) : -1), $key, 0, 0, 1);
print $form->selectDate((!empty($conf->global->$key) ? $db->idate($conf->global->$key) : -1), $key, 0, 0, 1);
} elseif ($key == 'ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER') {
$array = array(0=>$langs->trans("PreviousMonth"), 1=>$langs->trans("CurrentMonth"), 2=>$langs->trans("Fiscalyear"));
print $form->selectarray($key, $array, (isset($conf->global->ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER) ? $conf->global->ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER : 0));
} else {
print '<input type="text" class="maxwidth100" id="'.$key.'" name="'.$key.'" value="'.$conf->global->$key.'">';
print '<input type="text" class="maxwidth100" id="'.$key.'" name="'.$key.'" value="'.getDolGlobalString($key).'">';
}
print '</td>';

View File

@ -1,5 +1,5 @@
<?php
/* Copyright (C) 2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
/* Copyright (C) 2017-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,6 +26,7 @@ if (!defined('CSRFCHECK_WITH_TOKEN')) {
define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET
}
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
@ -45,7 +46,7 @@ $rowid = GETPOST('rowid', 'alpha');
$code = GETPOST('code', 'alpha');
// Security access
if (empty($user->rights->accounting->chartofaccount)) {
if (!$user->hasRight('accounting', 'chartofaccount')) {
accessforbidden();
}
@ -76,6 +77,8 @@ if (empty($sortorder)) {
$error = 0;
$search_country_id = GETPOST('search_country_id', 'int');
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('admin'));
@ -121,7 +124,7 @@ $tabrowid[35] = "";
// Condition to show dictionary in setup page
$tabcond = array();
$tabcond[35] = !empty($conf->accounting->enabled);
$tabcond[35] = isModEnabled('accounting');
// List of help for fields
$tabhelp = array();

View File

@ -1,10 +1,10 @@
<?php
/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015 Ari Elbaz (elarifr) <github@accedinfo.com>
* Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
* Copyright (C) 2013-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
* 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
* it under the terms of the GNU General Public License as published by
@ -34,12 +34,15 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
if (isModEnabled('categorie')) {
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
}
// Load translation files required by the page
$langs->loadLangs(array("companies", "compta", "accountancy", "products"));
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if (empty($user->rights->accounting->bind->write)) {
@ -59,6 +62,8 @@ $account_number_sell = GETPOST('account_number_sell');
$changeaccount = GETPOST('changeaccount', 'array');
$changeaccount_buy = GETPOST('changeaccount_buy', 'array');
$changeaccount_sell = GETPOST('changeaccount_sell', 'array');
$searchCategoryProductOperator = (GETPOST('search_category_product_operator', 'int') ? GETPOST('search_category_product_operator', 'int') : 0);
$searchCategoryProductList = GETPOST('search_category_product_list', 'array');
$search_ref = GETPOST('search_ref', 'alpha');
$search_label = GETPOST('search_label', 'alpha');
$search_desc = GETPOST('search_desc', 'alpha');
@ -144,6 +149,8 @@ if ($reshook < 0) {
// Purge search criteria
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All test are required to be compatible with all browsers
$searchCategoryProductOperator = 0;
$searchCategoryProductList = array();
$search_ref = '';
$search_label = '';
$search_desc = '';
@ -283,7 +290,16 @@ $aacompta_prodsell = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_ACCOUN
$aacompta_prodsell_intra = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT', $langs->trans("CodeNotDef"));
$aacompta_prodsell_export = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT', $langs->trans("CodeNotDef"));
llxHeader('', $langs->trans("ProductsBinding"));
$title = $langs->trans("ProductsBinding");
$helpurl = '';
$paramsCat = '';
foreach ($searchCategoryProductList as $searchCategoryProduct) {
$paramsCat .= "&search_category_product_list[]=".urlencode($searchCategoryProduct);
}
llxHeader('', $title, $helpurl, '', 0, 0, array(), array(), $paramsCat, '');
$pcgverid = getDolGlobalString('CHARTOFACCOUNTS');
$pcgvercode = dol_getIdFromCode($db, $pcgverid, 'accounting_system', 'rowid', 'pcg_version');
@ -308,6 +324,9 @@ if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
} else {
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.account_number = p." . $accountancy_field_name . " AND aa.fk_pcg_version = '" . $db->escape($pcgvercode) . "'";
}
if (!empty($searchCategoryProductList)) {
$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product"; // We'll need this table joined to the select in order to filter by categ
}
$sql .= ' WHERE p.entity IN ('.getEntity('product').')';
if (strlen(trim($search_current_account))) {
$sql .= natural_search((empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED) ? "p." : "ppe.") . $accountancy_field_name, $search_current_account);
@ -318,6 +337,30 @@ if ($search_current_account_valid == 'withoutvalidaccount') {
if ($search_current_account_valid == 'withvalidaccount') {
$sql .= " AND aa.account_number IS NOT NULL";
}
$searchCategoryProductSqlList = array();
if ($searchCategoryProductOperator == 1) {
foreach ($searchCategoryProductList as $searchCategoryProduct) {
if (intval($searchCategoryProduct) == -2) {
$searchCategoryProductSqlList[] = "cp.fk_categorie IS NULL";
} elseif (intval($searchCategoryProduct) > 0) {
$searchCategoryProductSqlList[] = "cp.fk_categorie = ".$db->escape($searchCategoryProduct);
}
}
if (!empty($searchCategoryProductSqlList)) {
$sql .= " AND (".implode(' OR ', $searchCategoryProductSqlList).")";
}
} else {
foreach ($searchCategoryProductList as $searchCategoryProduct) {
if (intval($searchCategoryProduct) == -2) {
$searchCategoryProductSqlList[] = "cp.fk_categorie IS NULL";
} elseif (intval($searchCategoryProduct) > 0) {
$searchCategoryProductSqlList[] = "p.rowid IN (SELECT fk_product FROM ".MAIN_DB_PREFIX."categorie_product WHERE fk_categorie = ".((int) $searchCategoryProduct).")";
}
}
if (!empty($searchCategoryProductSqlList)) {
$sql .= " AND (".implode(' AND ', $searchCategoryProductSqlList).")";
}
}
// Add search filter like
if (strlen(trim($search_ref))) {
$sql .= natural_search("p.ref", $search_ref);
@ -338,12 +381,22 @@ if ($search_onpurchase != '' && $search_onpurchase != '-1') {
$sql .= natural_search('p.tobuy', $search_onpurchase, 1);
}
$sql .= " GROUP BY p.rowid, p.ref, p.label, p.description, p.tosell, p.tobuy, p.tva_tx,";
$sql .= " p.fk_product_type,";
$sql .= ' p.tms,';
$sql .= ' aa.rowid,';
if (empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
$sql .= " p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export, p.accountancy_code_buy, p.accountancy_code_buy_intra, p.accountancy_code_buy_export";
} else {
$sql .= " ppe.accountancy_code_sell, ppe.accountancy_code_sell_intra, ppe.accountancy_code_sell_export, ppe.accountancy_code_buy, ppe.accountancy_code_buy_intra, ppe.accountancy_code_buy_export";
}
$sql .= $db->order($sortfield, $sortorder);
$nbtotalofrecords = '';
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
$result = $db->query($sql);
$nbtotalofrecords = $db->num_rows($result);
$resql = $db->query($sql);
$nbtotalofrecords = $db->num_rows($resql);
if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
$page = 0;
$offset = 0;
@ -353,9 +406,9 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
$sql .= $db->plimit($limit + 1, $offset);
dol_syslog("/accountancy/admin/productaccount.php", LOG_DEBUG);
$result = $db->query($sql);
if ($result) {
$num = $db->num_rows($result);
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
$i = 0;
$param = '';
@ -365,11 +418,17 @@ if ($result) {
if ($limit > 0 && $limit != $conf->liste_limit) {
$param .= '&limit='.urlencode($limit);
}
if ($searchCategoryProductOperator == 1) {
$param .= "&search_category_product_operator=".urlencode($searchCategoryProductOperator);
}
foreach ($searchCategoryProductList as $searchCategoryProduct) {
$param .= "&search_category_product_list[]=".urlencode($searchCategoryProduct);
}
if ($search_ref > 0) {
$param .= "&search_desc=".urlencode($search_ref);
$param .= "&search_ref=".urlencode($search_ref);
}
if ($search_label > 0) {
$param .= "&search_desc=".urlencode($search_label);
$param .= "&search_label=".urlencode($search_label);
}
if ($search_desc > 0) {
$param .= "&search_desc=".urlencode($search_desc);
@ -461,6 +520,40 @@ if ($result) {
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);
}
// Filter on categories
$moreforfilter = '';
if (isModEnabled('categorie') && $user->hasRight('categorie', 'lire')) {
$moreforfilter .= '<div class="divsearchfield">';
$moreforfilter .= img_picto($langs->trans('Categories'), 'category', 'class="pictofixedwidth"');
$categoriesProductArr = $form->select_all_categories(Categorie::TYPE_PRODUCT, '', '', 64, 0, 1);
$categoriesProductArr[-2] = '- '.$langs->trans('NotCategorized').' -';
$moreforfilter .= Form::multiselectarray('search_category_product_list', $categoriesProductArr, $searchCategoryProductList, 0, 0, 'minwidth300');
$moreforfilter .= ' <input type="checkbox" class="valignmiddle" name="search_category_product_operator" value="1"'.($searchCategoryProductOperator == 1 ? ' checked="checked"' : '').'/> <span class="none">'.$langs->trans('UseOrOperatorForCategories').'</span>';
$moreforfilter .= '</div>';
}
//Show/hide child products. Hidden by default
if (isModEnabled('variants') && !empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
$moreforfilter .= '<div class="divsearchfield">';
$moreforfilter .= '<input type="checkbox" id="search_show_childproducts" name="search_show_childproducts"'.($show_childproducts ? 'checked="checked"' : '').'>';
$moreforfilter .= ' <label for="search_show_childproducts">'.$langs->trans('ShowChildProducts').'</label>';
$moreforfilter .= '</div>';
}
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
if (empty($reshook)) {
$moreforfilter .= $hookmanager->resPrint;
} else {
$moreforfilter = $hookmanager->resPrint;
}
if ($moreforfilter) {
print '<div class="liste_titre liste_titre_bydiv centpercent">';
print $moreforfilter;
print '</div>';
}
print '<div class="div-table-responsive">';
print '<table class="liste '.($moreforfilter ? "listwithfilterbefore" : "").'">';
@ -515,7 +608,7 @@ if ($result) {
$i = 0;
while ($i < min($num, $limit)) {
$obj = $db->fetch_object($result);
$obj = $db->fetch_object($resql);
// Ref produit as link
$product_static->ref = $obj->ref;
@ -798,7 +891,7 @@ if ($result) {
print '</form>';
$db->free($result);
$db->free($resql);
} else {
dol_print_error($db);
}

View File

@ -23,6 +23,7 @@
* \brief List of accounting sub-account (auxiliary accounts)
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
@ -47,7 +48,7 @@ $search_type = GETPOST('search_type', 'int');
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->chartofaccount)) {
if (!$user->hasRight('accounting', 'chartofaccount')) {
accessforbidden();
}

View File

@ -1,7 +1,7 @@
<?php
/* Copyright (C) 2016 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2016 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2016-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2016-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
*
* This program is free software; you can redistribute it and/or modify
@ -24,6 +24,7 @@
* \brief Balance of book keeping
*/
// Load Dolibarr environment
require '../../main.inc.php';
// Class
@ -40,6 +41,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
$langs->loadLangs(array("accountancy", "compta"));
$action = GETPOST('action', 'aZ09');
$optioncss = GETPOST('optioncss', 'alpha');
$contextpage = GETPOST('contextpage', 'aZ09');
// Load variable for pagination
@ -142,7 +144,7 @@ if (!empty($search_ledger_code)) {
}
}
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -158,7 +160,8 @@ if (empty($user->rights->accounting->mouvements->lire)) {
* Action
*/
$parameters = array('socid'=>$socid);
$parameters = array();
$arrayfields = array();
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
@ -349,7 +352,7 @@ if ($action != 'export_csv') {
$sql .= " GROUP BY t.numero_compte";
$resql = $db->query($sql);
$nrows = $resql->num_rows;
$nrows = $db->num_rows($resql);
$opening_balances = array();
for ($i = 0; $i < $nrows; $i++) {
$arr = $resql->fetch_array();

View File

@ -1,7 +1,7 @@
<?php
/* Copyright (C) 2013-2017 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2017 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2013-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2018-2020 Frédéric France <frederic.france@netlogic.fr>
*
@ -25,6 +25,7 @@
* \brief Page to show book-entry
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
@ -79,7 +80,7 @@ if (!empty($update)) {
$object = new BookKeeping($db);
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -267,7 +268,7 @@ if ($action == "confirm_update") {
if ($mode != '_tmp') {
setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
}
$action = 'update';
$action = '';
$id = $object->id;
$piece_num = $object->piece_num;
}
@ -332,7 +333,9 @@ if ($action == 'valid') {
$html = new Form($db);
$formaccounting = new FormAccounting($db);
llxHeader('', $langs->trans("CreateMvts"));
$title = $langs->trans("CreateMvts");
llxHeader('', $title);
// Confirmation to delete the command
if ($action == 'delete') {
@ -341,7 +344,7 @@ if ($action == 'delete') {
}
if ($action == 'create') {
print load_fiche_titre($langs->trans("CreateMvts"));
print load_fiche_titre($title);
$object = new BookKeeping($db);
$next_num_mvt = $object->getNextNumMvt('_tmp');
@ -431,12 +434,12 @@ if ($action == 'create') {
// Account movement
print '<tr>';
print '<td class="titlefield">'.$langs->trans("NumMvts").'</td>';
print '<td>'.$object->piece_num.'</td>';
print '<td>'.($mode == '_tmp' ? '<span class="opacitymedium" title="Id tmp '.$object->piece_num.'">'.$langs->trans("Draft").'</span>' : $object->piece_num).'</td>';
print '</tr>';
// Date
print '<tr><td>';
print '<table class="nobordernopadding" width="100%"><tr><td>';
print '<table class="nobordernopadding centpercent"><tr><td>';
print $langs->trans('Docdate');
print '</td>';
if ($action != 'editdate') {
@ -540,21 +543,24 @@ if ($action == 'create') {
print '</td>';
print '</tr>';
// Date document creation
print '<tr>';
print '<td class="titlefield">'.$langs->trans("DateExport").'</td>';
print '<td>';
print $object->date_export ? dol_print_date($object->date_export, 'dayhour') : '&nbsp;';
print '</td>';
print '</tr>';
// Don't show in tmp mode, inevitably empty
if ($mode != "_tmp") {
// Date document export
print '<tr>';
print '<td class="titlefield">' . $langs->trans("DateExport") . '</td>';
print '<td>';
print $object->date_export ? dol_print_date($object->date_export, 'dayhour') : '&nbsp;';
print '</td>';
print '</tr>';
// Date document creation
print '<tr>';
print '<td class="titlefield">'.$langs->trans("DateValidation").'</td>';
print '<td>';
print $object->date_validation ? dol_print_date($object->date_validation, 'dayhour') : '&nbsp;';
print '</td>';
print '</tr>';
// Date document validation
print '<tr>';
print '<td class="titlefield">' . $langs->trans("DateValidation") . '</td>';
print '<td>';
print $object->date_validation ? dol_print_date($object->date_validation, 'dayhour') : '&nbsp;';
print '</td>';
print '</tr>';
}
// Validate
/*
@ -607,6 +613,7 @@ if ($action == 'create') {
print '<br>';
$result = $object->fetchAllPerMvt($piece_num, $mode); // This load $object->linesmvt
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
} else {
@ -640,13 +647,22 @@ if ($action == 'create') {
print_liste_field_titre("Debit", "", "", "", "", 'class="right"');
print_liste_field_titre("Credit", "", "", "", "", 'class="right"');
if (empty($object->date_validation)) {
print_liste_field_titre("Action", "", "", "", "", 'width="60" class="center"');
print_liste_field_titre("Action", "", "", "", "", 'width="60"', "", "", 'center ');
} else {
print_liste_field_titre("");
}
print "</tr>\n";
// Add an empty line if there is not yet
if (!empty($object->linesmvt[0])) {
$tmpline = $object->linesmvt[0];
if (!empty($tmpline->numero_compte)) {
$line = new BookKeepingLine();
$object->linesmvt[] = $line;
}
}
foreach ($object->linesmvt as $line) {
print '<tr class="oddeven">';
$total_debit += $line->debit;
@ -677,7 +693,31 @@ if ($action == 'create') {
print '<input type="hidden" name="id" value="'.$line->id.'">'."\n";
print '<input type="submit" class="button" name="update" value="'.$langs->trans("Update").'">';
print '</td>';
} elseif (empty($line->numero_compte) || (empty($line->debit) && empty($line->credit))) {
if ($action == "" || $action == 'add') {
print '<!-- td columns in add mode -->';
print '<td>';
print $formaccounting->select_account('', 'accountingaccount_number', 1, array(), 1, 1, '');
print '</td>';
print '<td>';
// TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because:
// It does not use the setup of "key pressed" to select a thirdparty and this hang browser on large databases.
// Also, it is not possible to use a value that is not in the list.
// Also, the label is not automatically filled when a value is selected.
if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) {
print $formaccounting->select_auxaccount('', 'subledger_account', 1, 'maxwidth250', '', 'subledger_label');
} else {
print '<input type="text" class="maxwidth150" name="subledger_account" value="" placeholder="' . dol_escape_htmltag($langs->trans("SubledgerAccount")) . '">';
}
print '<br><input type="text" class="maxwidth150" name="subledger_label" value="" placeholder="' . dol_escape_htmltag($langs->trans("SubledgerAccountLabel")) . '">';
print '</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="credit" value=""/></td>';
print '<td class="center"><input type="submit" class="button" name="save" value="' . $langs->trans("Add") . '"></td>';
}
} else {
print '<!-- td columns in display mode -->';
$resultfetch = $accountingaccount->fetch(null, $line->numero_compte, true);
print '<td>';
if ($resultfetch > 0) {
@ -733,35 +773,6 @@ if ($action == 'create') {
setEventMessages(null, array($langs->trans('MvtNotCorrectlyBalanced', $total_debit, $total_credit)), 'warnings');
}
if (empty($object->date_export) && empty($object->date_validation)) {
if ($action == "" || $action == 'add') {
print '<tr class="oddeven">';
print '<!-- td columns in add mode -->';
print '<td>';
print $formaccounting->select_account('', 'accountingaccount_number', 1, array(), 1, 1, '');
print '</td>';
print '<td>';
// TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because:
// It does not use the setup of "key pressed" to select a thirdparty and this hang browser on large databases.
// Also, it is not possible to use a value that is not in the list.
// Also, the label is not automatically filled when a value is selected.
if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) {
print $formaccounting->select_auxaccount('', 'subledger_account', 1, 'maxwidth250', '', 'subledger_label');
} else {
print '<input type="text" class="maxwidth150" name="subledger_account" value="" placeholder="' . dol_escape_htmltag($langs->trans("SubledgerAccount")) . '">';
}
print '<br><input type="text" class="maxwidth150" name="subledger_label" value="" placeholder="' . dol_escape_htmltag($langs->trans("SubledgerAccountLabel")) . '">';
print '</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="credit" value=""/></td>';
print '<td>';
print '<input type="submit" class="button" name="save" value="' . $langs->trans("Add") . '">';
print '</td>';
print '</tr>';
}
}
print '</table>';
print '</div>';

View File

@ -1,7 +1,7 @@
<?php
/* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2013-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2016-2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2018-2021 Frédéric France <frederic.france@netlogic.fr>
*
@ -25,9 +25,11 @@
* \brief List operation of book keeping
*/
// Load Dolibarr environment
require '../../main.inc.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.'/accountancy/class/lettering.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
@ -42,6 +44,10 @@ $langs->loadLangs(array("accountancy", "compta"));
$socid = GETPOST('socid', 'int');
$action = GETPOST('action', 'aZ09');
$massaction = GETPOST('massaction', 'alpha');
$confirm = GETPOST('confirm', 'alpha');
$toselect = GETPOST('toselect', 'array');
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'bookkeepinglist';
$search_mvt_num = GETPOST('search_mvt_num', 'int');
$search_doc_type = GETPOST("search_doc_type", 'alpha');
$search_doc_ref = GETPOST("search_doc_ref", 'alpha');
@ -86,6 +92,7 @@ $search_date_validation_endmonth = GETPOST('search_date_validation_endmonth', '
$search_date_validation_endday = GETPOST('search_date_validation_endday', 'int');
$search_date_validation_start = dol_mktime(0, 0, 0, $search_date_validation_startmonth, $search_date_validation_startday, $search_date_validation_startyear);
$search_date_validation_end = dol_mktime(23, 59, 59, $search_date_validation_endmonth, $search_date_validation_endday, $search_date_validation_endyear);
$search_import_key = GETPOST("search_import_key", 'alpha');
//var_dump($search_date_start);exit;
if (GETPOST("button_delmvt_x") || GETPOST("button_delmvt.x") || GETPOST("button_delmvt")) {
@ -126,6 +133,7 @@ $search_not_reconciled = GETPOST('search_not_reconciled', 'alpha');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION);
$sortfield = GETPOST('sortfield', 'aZ09comma');
$sortorder = GETPOST('sortorder', 'aZ09comma');
$optioncss = GETPOST('optioncss', 'alpha');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page < 0) {
$page = 0;
@ -190,22 +198,24 @@ $arrayfields = array(
't.date_creation'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0),
't.tms'=>array('label'=>$langs->trans("DateModification"), 'checked'=>0),
't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1),
't.date_validated'=>array('label'=>$langs->trans("DateValidationAndLock"), 'checked'=>1),
't.date_validated'=>array('label'=>$langs->trans("DateValidationAndLock"), 'checked'=>1, 'enabled'=>!getDolGlobalString("ACCOUNTANCY_DISABLE_CLOSURE_LINE_BY_LINE")),
't.import_key'=>array('label'=>$langs->trans("ImportId"), 'checked'=>0, 'position'=>1100),
);
if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) {
unset($arrayfields['t.lettering_code']);
}
$listofformat = AccountancyExport::getType();
$formatexportset = $conf->global->ACCOUNTING_EXPORT_MODELCSV;
$accountancyexport = new AccountancyExport($db);
$listofformat = $accountancyexport->getType();
$formatexportset = getDolGlobalString('ACCOUNTING_EXPORT_MODELCSV');
if (empty($listofformat[$formatexportset])) {
$formatexportset = 1;
}
$error = 0;
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -220,10 +230,12 @@ if (empty($user->rights->accounting->mouvements->lire)) {
* Actions
*/
$param = '';
if (GETPOST('cancel', 'alpha')) {
$action = 'list'; $massaction = '';
}
if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'preunlettering' && $massaction != 'predeletebookkeepingwriting') {
$massaction = '';
}
@ -294,10 +306,11 @@ if (empty($reshook)) {
$search_credit = '';
$search_lettering_code = '';
$search_not_reconciled = '';
$search_import_key = '';
$toselect = array();
}
// Must be after the remove filter action, before the export.
$param = '';
$filter = array();
if (!empty($search_date_start)) {
$filter['t.doc_date>='] = $search_date_start;
@ -416,77 +429,143 @@ if (empty($reshook)) {
$filter['t.reconciled_option'] = $search_not_reconciled;
$param .= '&search_not_reconciled='.urlencode($search_not_reconciled);
}
}
if (!empty($search_import_key)) {
$filter['t.import_key'] = $search_import_key;
$param .= '&search_import_key='.urlencode($search_import_key);
}
if ($action == 'delbookkeeping' && $user->rights->accounting->mouvements->supprimer) {
$import_key = GETPOST('importkey', 'alpha');
if (!empty($import_key)) {
$result = $object->deleteByImportkey($import_key);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
//if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouvements->supprimer_tous) {
// $delmonth = GETPOST('delmonth', 'int');
// $delyear = GETPOST('delyear', 'int');
// if ($delyear == -1) {
// $delyear = 0;
// }
// $deljournal = GETPOST('deljournal', 'alpha');
// if ($deljournal == -1) {
// $deljournal = 0;
// }
//
// if (!empty($delmonth) || !empty($delyear) || !empty($deljournal)) {
// $result = $object->deleteByYearAndJournal($delyear, $deljournal, '', ($delmonth > 0 ? $delmonth : 0));
// if ($result < 0) {
// setEventMessages($object->error, $object->errors, 'errors');
// } else {
// setEventMessages("RecordDeleted", null, 'mesgs');
// }
//
// // Make a redirect to avoid to launch the delete later after a back button
// header("Location: list.php".($param ? '?'.$param : ''));
// exit;
// } else {
// setEventMessages("NoRecordDeleted", null, 'warnings');
// }
//}
if ($action == 'setreexport') {
$setreexport = GETPOST('value', 'int');
if (!dolibarr_set_const($db, "ACCOUNTING_REEXPORT", $setreexport, 'yesno', 0, '', $conf->entity)) {
$error++;
}
// Make a redirect to avoid to launch the delete later after a back button
header("Location: list.php".($param ? '?'.$param : ''));
exit;
}
}
if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouvements->supprimer_tous) {
$delmonth = GETPOST('delmonth', 'int');
$delyear = GETPOST('delyear', 'int');
if ($delyear == -1) {
$delyear = 0;
}
$deljournal = GETPOST('deljournal', 'alpha');
if ($deljournal == -1) {
$deljournal = 0;
}
if (!empty($delmonth) || !empty($delyear) || !empty($deljournal)) {
$result = $object->deleteByYearAndJournal($delyear, $deljournal, '', ($delmonth > 0 ? $delmonth : 0));
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
if (!$error) {
if ($conf->global->ACCOUNTING_REEXPORT == 1) {
setEventMessages($langs->trans("ExportOfPiecesAlreadyExportedIsEnable"), null, 'mesgs');
} else {
setEventMessages($langs->trans("ExportOfPiecesAlreadyExportedIsDisable"), null, 'mesgs');
}
} else {
setEventMessages("RecordDeleted", null, 'mesgs');
setEventMessages($langs->trans("Error"), null, 'errors');
}
// Make a redirect to avoid to launch the delete later after a back button
header("Location: list.php".($param ? '?'.$param : ''));
exit;
} else {
setEventMessages("NoRecordDeleted", null, 'warnings');
}
}
if ($action == 'delmouvconfirm' && $user->rights->accounting->mouvements->supprimer) {
$mvt_num = GETPOST('mvt_num', 'int');
if (!empty($mvt_num)) {
$result = $object->deleteMvtNum($mvt_num);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
} else {
setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs');
}
header("Location: list.php?noreset=1".($param ? '&'.$param : ''));
exit;
}
}
if ($action == 'setreexport') {
$setreexport = GETPOST('value', 'int');
if (!dolibarr_set_const($db, "ACCOUNTING_REEXPORT", $setreexport, 'yesno', 0, '', $conf->entity)) {
$error++;
}
if (!$error) {
if ($conf->global->ACCOUNTING_REEXPORT == 1) {
setEventMessages($langs->trans("ExportOfPiecesAlreadyExportedIsEnable"), null, 'mesgs');
} else {
setEventMessages($langs->trans("ExportOfPiecesAlreadyExportedIsDisable"), null, 'mesgs');
// Mass actions
$objectclass = 'Bookkeeping';
$objectlabel = 'Bookkeeping';
$permissiontoread = $user->rights->societe->lire;
$permissiontodelete = $user->rights->societe->supprimer;
$permissiontoadd = $user->rights->societe->creer;
$uploaddir = $conf->societe->dir_output;
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
if (!$error && $action == 'deletebookkeepingwriting' && $confirm == "yes" && $user->rights->accounting->mouvements->supprimer) {
$nbok = 0;
foreach ($toselect as $toselectid) {
$result = $object->fetch($toselectid);
if ($result > 0 && (!isset($object->date_validation) || $object->date_validation === '')) {
$result = $object->deleteMvtNum($object->piece_num);
if ($result > 0) {
$nbok++;
} else {
setEventMessages($object->error, $object->errors, 'errors');
$error++;
break;
}
} elseif ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
$error++;
break;
}
}
// Message for elements well deleted
if ($nbok > 1) {
setEventMessages($langs->trans("RecordsDeleted", $nbok), null, 'mesgs');
} elseif ($nbok > 0) {
setEventMessages($langs->trans("RecordDeleted", $nbok), null, 'mesgs');
} elseif (!$error) {
setEventMessages($langs->trans("NoRecordDeleted"), null, 'mesgs');
}
if (!$error) {
header("Location: ".$_SERVER["PHP_SELF"]."?noreset=1".($param ? '&'.$param : ''));
exit;
}
}
// others mass actions
if (!$error && getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && $user->rights->accounting->mouvements->creer) {
if ($massaction == 'lettering') {
$lettering = new Lettering($db);
$nb_lettering = $lettering->bookkeepingLetteringAll($toselect);
if ($nb_lettering < 0) {
setEventMessages('', $lettering->errors, 'errors');
$error++;
$nb_lettering = max(0, abs($nb_lettering) - 2);
} elseif ($nb_lettering == 0) {
$nb_lettering = 0;
setEventMessages($langs->trans('AccountancyNoLetteringModified'), array(), 'mesgs');
}
if ($nb_lettering == 1) {
setEventMessages($langs->trans('AccountancyOneLetteringModifiedSuccessfully'), array(), 'mesgs');
} elseif ($nb_lettering > 1) {
setEventMessages($langs->trans('AccountancyLetteringModifiedSuccessfully', $nb_lettering), array(), 'mesgs');
}
if (!$error) {
header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param);
exit();
}
} elseif ($action == 'unlettering' && $confirm == "yes") {
$lettering = new Lettering($db);
$nb_lettering = $lettering->bookkeepingLetteringAll($toselect, true);
if ($nb_lettering < 0) {
setEventMessages('', $lettering->errors, 'errors');
$error++;
$nb_lettering = max(0, abs($nb_lettering) - 2);
} elseif ($nb_lettering == 0) {
$nb_lettering = 0;
setEventMessages($langs->trans('AccountancyNoUnletteringModified'), array(), 'mesgs');
}
if ($nb_lettering == 1) {
setEventMessages($langs->trans('AccountancyOneUnletteringModifiedSuccessfully'), array(), 'mesgs');
} elseif ($nb_lettering > 1) {
setEventMessages($langs->trans('AccountancyUnletteringModifiedSuccessfully', $nb_lettering), array(), 'mesgs');
}
if (!$error) {
header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param);
exit();
}
}
} else {
setEventMessages($langs->trans("Error"), null, 'errors');
}
}
@ -520,7 +599,8 @@ $sql .= " t.piece_num,";
$sql .= " t.date_creation,";
$sql .= " t.tms as date_modification,";
$sql .= " t.date_export,";
$sql .= " t.date_validated as date_validation";
$sql .= " t.date_validated as date_validation,";
$sql .= " t.import_key";
$sql .= ' FROM '.MAIN_DB_PREFIX.$object->table_element.' as t';
// Manage filter
$sqlwhere = array();
@ -667,6 +747,7 @@ if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) {
$num = $db->num_rows($resql);
}
$arrayofselected = is_array($toselect) ? $toselect : array();
// Output page
// --------------------------------------------------------------------
@ -684,69 +765,67 @@ if ($action == 'export_file') {
'name' => 'notifiedexportdate',
'type' => 'checkbox',
'label' => $langs->trans('NotifiedExportDate'),
'value' => $checked,
'value' => (!empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) ? 'false' : 'true'),
);
$form_question['separator'] = array('name'=>'separator', 'type'=>'separator');
// If 0 or not set, we NOT check by default.
$checked = (isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE));
$form_question['notifiedvalidationdate'] = array(
'name' => 'notifiedvalidationdate',
'type' => 'checkbox',
'label' => $langs->trans('NotifiedValidationDate'),
'value' => $checked,
);
if (!getDolGlobalString("ACCOUNTANCY_DISABLE_CLOSURE_LINE_BY_LINE")) {
// If 0 or not set, we NOT check by default.
$checked = (isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE));
$form_question['notifiedvalidationdate'] = array(
'name' => 'notifiedvalidationdate',
'type' => 'checkbox',
'label' => $langs->trans('NotifiedValidationDate', $langs->transnoentitiesnoconv("MenuAccountancyClosure")),
'value' => $checked,
);
$form_question['separator2'] = array('name'=>'separator2', 'type'=>'separator');
$form_question['separator2'] = array('name'=>'separator2', 'type'=>'separator');
}
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', $langs->trans('ConfirmExportFile'), 'export_fileconfirm', $form_question, '', 1, 300, 600);
}
if ($action == 'delmouv') {
$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') {
$form_question = array();
$delyear = GETPOST('delyear', 'int');
$deljournal = GETPOST('deljournal', 'alpha');
if (empty($delyear)) {
$delyear = dol_print_date(dol_now(), '%Y');
}
$month_array = array();
for ($i = 1; $i <= 12; $i++) {
$month_array[$i] = $langs->trans("Month".sprintf("%02d", $i));
}
$year_array = $formaccounting->selectyear_accountancy_bookkepping($delyear, 'delyear', 0, 'array');
$journal_array = $formaccounting->select_journal($deljournal, 'deljournal', '', 1, 1, 1, '', 0, 1);
$form_question['delmonth'] = array(
'name' => 'delmonth',
'type' => 'select',
'label' => $langs->trans('DelMonth'),
'values' => $month_array,
'morecss' => 'minwidth150',
'default' => ''
);
$form_question['delyear'] = array(
'name' => 'delyear',
'type' => 'select',
'label' => $langs->trans('DelYear'),
'values' => $year_array,
'default' => $delyear
);
$form_question['deljournal'] = array(
'name' => 'deljournal',
'type' => 'other', // We don't use select here, the journal_array is already a select html component
'label' => $langs->trans('DelJournal'),
'value' => $journal_array,
'default' => $deljournal
);
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'delbookkeepingyearconfirm', $form_question, '', 1, 320);
}
//if ($action == 'delbookkeepingyear') {
// $form_question = array();
// $delyear = GETPOST('delyear', 'int');
// $deljournal = GETPOST('deljournal', 'alpha');
//
// if (empty($delyear)) {
// $delyear = dol_print_date(dol_now(), '%Y');
// }
// $month_array = array();
// for ($i = 1; $i <= 12; $i++) {
// $month_array[$i] = $langs->trans("Month".sprintf("%02d", $i));
// }
// $year_array = $formaccounting->selectyear_accountancy_bookkepping($delyear, 'delyear', 0, 'array');
// $journal_array = $formaccounting->select_journal($deljournal, 'deljournal', '', 1, 1, 1, '', 0, 1);
//
// $form_question['delmonth'] = array(
// 'name' => 'delmonth',
// 'type' => 'select',
// 'label' => $langs->trans('DelMonth'),
// 'values' => $month_array,
// 'morecss' => 'minwidth150',
// 'default' => ''
// );
// $form_question['delyear'] = array(
// 'name' => 'delyear',
// 'type' => 'select',
// 'label' => $langs->trans('DelYear'),
// 'values' => $year_array,
// 'default' => $delyear
// );
// $form_question['deljournal'] = array(
// 'name' => 'deljournal',
// 'type' => 'other', // We don't use select here, the journal_array is already a select html component
// 'label' => $langs->trans('DelJournal'),
// 'value' => $journal_array,
// 'default' => $deljournal
// );
//
// $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 $formconfirm;
@ -759,6 +838,22 @@ if ($limit > 0 && $limit != $conf->liste_limit) {
$param .= '&limit='.urlencode($limit);
}
// List of mass actions available
$arrayofmassactions = array();
/*
if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && $user->rights->accounting->mouvements->creer) {
$arrayofmassactions['lettering'] = img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans('Lettering');
$arrayofmassactions['preunlettering'] = img_picto('', 'uncheck', 'class="pictofixedwidth"') . $langs->trans('Unlettering');
}
*/
if ($user->rights->accounting->mouvements->supprimer) {
$arrayofmassactions['predeletebookkeepingwriting'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
}
if (GETPOST('nomassaction', 'int') || in_array($massaction, array('preunlettering', 'predeletebookkeepingwriting'))) {
$arrayofmassactions = array();
}
$massactionbutton = $form->selectMassAction($massaction, $arrayofmassactions);
print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="list">';
@ -768,8 +863,7 @@ if ($optioncss != '') {
print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
print '<input type="hidden" name="sortfield" value="'.urlencode($sortfield).'">';
print '<input type="hidden" name="sortorder" value="'.urlencode($sortorder).'">';
$massactionbutton = '';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
if (count($filter)) {
$buttonLabel = $langs->trans("ExportFilteredList");
@ -794,7 +888,7 @@ if (empty($reshook)) {
$newcardbutton .= dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.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'));
$newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly'));
$newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?type=sub'.$param, '', 1, array('morecss' => 'marginleftonly'));
$url = './card.php?action=create';
if (!empty($socid)) {
@ -805,12 +899,26 @@ if (empty($reshook)) {
print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1);
if ($massaction == 'preunlettering') {
print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassUnlettering"), $langs->trans("ConfirmMassUnletteringQuestion", count($toselect)), "unlettering", null, '', 0, 200, 500, 1);
} elseif ($massaction == 'predeletebookkeepingwriting') {
print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassDeleteBookkeepingWriting"), $langs->trans("ConfirmMassDeleteBookkeepingWritingQuestion", count($toselect)), "deletebookkeepingwriting", null, '', 0, 200, 500, 1);
}
//$topicmail = "Information";
//$modelmail = "accountingbookkeeping";
//$objecttmp = new BookKeeping($db);
//$trackid = 'bk'.$object->id;
include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
if ($massactionbutton) {
if ($massactionbutton && $contextpage != 'poslist') {
$selectedfields .= $form->showCheckAddButtons('checkforselect', 1);
}
$moreforfilter = '';
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
if (empty($reshook)) {
@ -954,6 +1062,11 @@ if (!empty($arrayfields['t.date_validated']['checked'])) {
print '</div>';
print '</td>';
}
if (!empty($arrayfields['t.import_key']['checked'])) {
print '<td class="liste_titre center">';
print '<input class="flat searchstring maxwidth50" type="text" name="search_import_key" value="'.dol_escape_htmltag($search_import_key).'">';
print '</td>';
}
// Action column
print '<td class="liste_titre center">';
$searchpicto = $form->showFilterButtons();
@ -1008,6 +1121,9 @@ if (!empty($arrayfields['t.date_export']['checked'])) {
if (!empty($arrayfields['t.date_validated']['checked'])) {
print_liste_field_titre($arrayfields['t.date_validated']['label'], $_SERVER['PHP_SELF'], "t.date_validated", "", $param, '', $sortfield, $sortorder, 'center ');
}
if (!empty($arrayfields['t.import_key']['checked'])) {
print_liste_field_titre($arrayfields['t.import_key']['label'], $_SERVER["PHP_SELF"], "t.import_key", "", $param, '', $sortfield, $sortorder, 'center ');
}
print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
print "</tr>\n";
@ -1018,6 +1134,13 @@ $line = new BookKeepingLine();
// --------------------------------------------------------------------
$i = 0;
$totalarray = array();
$totalarray['nbfield'] = 0;
$total_debit = 0;
$total_credit = 0;
$totalarray['val'] = array ();
$totalarray['val']['totaldebit'] = 0;
$totalarray['val']['totalcredit'] = 0;
while ($i < min($num, $limit)) {
$obj = $db->fetch_object($resql);
if (empty($obj)) {
@ -1252,17 +1375,21 @@ while ($i < min($num, $limit)) {
}
}
// Action column
print '<td class="nowraponall center">';
if (empty($line->date_export) && empty($line->date_validation)) {
if ($user->rights->accounting->mouvements->creer) {
print '<a class="editfielda paddingleft marginrightonly" href="' . DOL_URL_ROOT . '/accountancy/bookkeeping/card.php?piece_num=' . $line->piece_num . $param . '&page=' . $page . ($sortfield ? '&sortfield=' . $sortfield : '') . ($sortorder ? '&sortorder=' . $sortorder : '') . '">' . img_edit() . '</a>';
if (!empty($arrayfields['t.import_key']['checked'])) {
print '<td class="tdoverflowmax100">'.$obj->import_key."</td>\n";
if (!$i) {
$totalarray['nbfield']++;
}
}
if (empty($line->date_validation)) {
if ($user->rights->accounting->mouvements->supprimer) {
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>';
// Action column
print '<td class="nowraponall center">';
if (($massactionbutton || $massaction) && $contextpage != 'poslist') { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
$selected = 0;
if (in_array($line->id, $arrayofselected)) {
$selected = 1;
}
print '<input id="cb'.$line->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$line->id.'"'.($selected ? ' checked="checked"' : '').' />';
}
print '</td>';
@ -1283,11 +1410,11 @@ print "</table>";
print '</div>';
// TODO Replace this with mass delete action
if ($user->rights->accounting->mouvements->supprimer_tous) {
print '<div class="tabsAction tabsActionNoBottom">'."\n";
print '<a class="butActionDelete" name="button_delmvt" href="'.$_SERVER["PHP_SELF"].'?action=delbookkeepingyear&token='.newToken().($param ? '&'.$param : '').'">'.$langs->trans("DeleteMvt").'</a>';
print '</div>';
}
//if ($user->rights->accounting->mouvements->supprimer_tous) {
// print '<div class="tabsAction tabsActionNoBottom">'."\n";
// print '<a class="butActionDelete" name="button_delmvt" href="'.$_SERVER["PHP_SELF"].'?action=delbookkeepingyear&token='.newToken().($param ? '&'.$param : '').'">'.$langs->trans("DeleteMvt").'</a>';
// print '</div>';
//}
print '</form>';

View File

@ -2,7 +2,7 @@
/* Copyright (C) 2016 Neil Orley <neil.orley@oeris.fr>
* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2020 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2013-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
*
* This program is free software; you can redistribute it and/or modify
@ -25,9 +25,11 @@
* \brief List operation of ledger ordered by account number
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/lettering.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
@ -39,6 +41,17 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
$langs->loadLangs(array("accountancy", "compta"));
$action = GETPOST('action', 'aZ09');
$socid = GETPOST('socid', 'int');
$massaction = GETPOST('massaction', 'alpha');
$confirm = GETPOST('confirm', 'alpha');
$toselect = GETPOST('toselect', 'array');
$type = GETPOST('type', 'alpha');
if ($type == 'sub') {
$context_default = 'bookkeepingbysubaccountlist';
} else {
$context_default = 'bookkeepingbyaccountlist';
}
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : $context_default;
$search_date_startyear = GETPOST('search_date_startyear', 'int');
$search_date_startmonth = GETPOST('search_date_startmonth', 'int');
$search_date_startday = GETPOST('search_date_startday', 'int');
@ -64,6 +77,7 @@ $search_date_validation_endmonth = GETPOST('search_date_validation_endmonth', '
$search_date_validation_endday = GETPOST('search_date_validation_endday', 'int');
$search_date_validation_start = dol_mktime(0, 0, 0, $search_date_validation_startmonth, $search_date_validation_startday, $search_date_validation_startyear);
$search_date_validation_end = dol_mktime(23, 59, 59, $search_date_validation_endmonth, $search_date_validation_endday, $search_date_validation_endyear);
$search_import_key = GETPOST("search_import_key", 'alpha');
$search_accountancy_code = GETPOST("search_accountancy_code");
$search_accountancy_code_start = GETPOST('search_accountancy_code_start', 'alpha');
@ -92,6 +106,7 @@ if (GETPOST("button_delmvt_x") || GETPOST("button_delmvt.x") || GETPOST("button_
$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION);
$sortfield = GETPOST('sortfield', 'aZ09comma');
$sortorder = GETPOST('sortorder', 'aZ09comma');
$optioncss = GETPOST('optioncss', 'alpha');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page < 0) {
$page = 0;
@ -109,7 +124,7 @@ if ($sortfield == "") {
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$object = new BookKeeping($db);
$formfile = new FormFile($db);
$hookmanager->initHooks(array('bookkeepingbyaccountlist'));
$hookmanager->initHooks(array($context_default));
$formaccounting = new FormAccounting($db);
$form = new Form($db);
@ -152,7 +167,8 @@ $arrayfields = array(
't.credit'=>array('label'=>$langs->trans("Credit"), 'checked'=>1),
't.lettering_code'=>array('label'=>$langs->trans("LetteringCode"), 'checked'=>1),
't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1),
't.date_validated'=>array('label'=>$langs->trans("DateValidation"), 'checked'=>1),
't.date_validated'=>array('label'=>$langs->trans("DateValidation"), 'checked'=>1, 'enabled'=>!getDolGlobalString("ACCOUNTANCY_DISABLE_CLOSURE_LINE_BY_LINE")),
't.import_key'=>array('label'=>$langs->trans("ImportId"), 'checked'=>0, 'position'=>1100),
);
if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) {
@ -172,7 +188,7 @@ if ($search_date_end && empty($search_date_endyear)) {
$search_date_endday = $tmparray['mday'];
}
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -187,10 +203,13 @@ if (empty($user->rights->accounting->mouvements->lire)) {
* Action
*/
$param = '';
if (GETPOST('cancel', 'alpha')) {
$action = 'list'; $massaction = '';
$action = 'list';
$massaction = '';
}
if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'preunlettering' && $massaction != 'predeletebookkeepingwriting') {
$massaction = '';
}
@ -242,10 +261,11 @@ if (empty($reshook)) {
$search_credit = '';
$search_lettering_code = '';
$search_not_reconciled = '';
$search_import_key = '';
$toselect = array();
}
// Must be after the remove filter action, before the export.
$param = '';
$filter = array();
if (!empty($search_date_start)) {
@ -261,12 +281,20 @@ if (empty($reshook)) {
$param .= '&doc_datemonth='.GETPOST('doc_datemonth', 'int').'&doc_dateday='.GETPOST('doc_dateday', 'int').'&doc_dateyear='.GETPOST('doc_dateyear', 'int');
}
if (!empty($search_accountancy_code_start)) {
$filter['t.numero_compte>='] = $search_accountancy_code_start;
$param .= '&search_accountancy_code_start='.urlencode($search_accountancy_code_start);
if ($type == 'sub') {
$filter['t.subledger_account>='] = $search_accountancy_code_start;
} else {
$filter['t.numero_compte>='] = $search_accountancy_code_start;
}
$param .= '&search_accountancy_code_start=' . urlencode($search_accountancy_code_start);
}
if (!empty($search_accountancy_code_end)) {
$filter['t.numero_compte<='] = $search_accountancy_code_end;
$param .= '&search_accountancy_code_end='.urlencode($search_accountancy_code_end);
if ($type == 'sub') {
$filter['t.subledger_account<='] = $search_accountancy_code_end;
} else {
$filter['t.numero_compte<='] = $search_accountancy_code_end;
}
$param .= '&search_accountancy_code_end=' . urlencode($search_accountancy_code_end);
}
if (!empty($search_label_account)) {
$filter['t.label_compte'] = $search_label_account;
@ -326,61 +354,133 @@ if (empty($reshook)) {
$filter['t.date_validated<='] = $search_date_validation_end;
$param .= '&search_date_validation_endmonth='.$search_date_validation_endmonth.'&search_date_validation_endday='.$search_date_validation_endday.'&search_date_validation_endyear='.$search_date_validation_endyear;
}
}
if (!empty($search_import_key)) {
$filter['t.import_key'] = $search_import_key;
$param .= '&search_import_key='.urlencode($search_import_key);
}
if ($action == 'delbookkeeping' && $user->rights->accounting->mouvements->supprimer) {
$import_key = GETPOST('importkey', 'alpha');
// param with type of list
$url_param = substr($param, 1); // remove first "&"
if (!empty($type)) {
$param = '&type='.$type.$param;
}
if (!empty($import_key)) {
$result = $object->deleteByImportkey($import_key);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
//if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouvements->supprimer_tous) {
// $delmonth = GETPOST('delmonth', 'int');
// $delyear = GETPOST('delyear', 'int');
// if ($delyear == -1) {
// $delyear = 0;
// }
// $deljournal = GETPOST('deljournal', 'alpha');
// if ($deljournal == -1) {
// $deljournal = 0;
// }
//
// if (!empty($delmonth) || !empty($delyear) || !empty($deljournal)) {
// $result = $object->deleteByYearAndJournal($delyear, $deljournal, '', ($delmonth > 0 ? $delmonth : 0));
// if ($result < 0) {
// setEventMessages($object->error, $object->errors, 'errors');
// } else {
// setEventMessages("RecordDeleted", null, 'mesgs');
// }
//
// // Make a redirect to avoid to launch the delete later after a back button
// header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : ''));
// exit;
// } else {
// setEventMessages("NoRecordDeleted", null, 'warnings');
// }
//}
// Mass actions
$objectclass = 'Bookkeeping';
$objectlabel = 'Bookkeeping';
$permissiontoread = $user->rights->societe->lire;
$permissiontodelete = $user->rights->societe->supprimer;
$permissiontoadd = $user->rights->societe->creer;
$uploaddir = $conf->societe->dir_output;
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
if (!$error && $action == 'deletebookkeepingwriting' && $confirm == "yes" && $user->rights->accounting->mouvements->supprimer) {
$nbok = 0;
foreach ($toselect as $toselectid) {
$result = $object->fetch($toselectid);
if ($result > 0 && (!isset($object->date_validation) || $object->date_validation === '')) {
$result = $object->deleteMvtNum($object->piece_num);
if ($result > 0) {
$nbok++;
} else {
setEventMessages($object->error, $object->errors, 'errors');
$error++;
break;
}
} elseif ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
$error++;
break;
}
}
// Make a redirect to avoid to launch the delete later after a back button
header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : ''));
exit;
}
}
if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouvements->supprimer_tous) {
$delmonth = GETPOST('delmonth', 'int');
$delyear = GETPOST('delyear', 'int');
if ($delyear == -1) {
$delyear = 0;
}
$deljournal = GETPOST('deljournal', 'alpha');
if ($deljournal == -1) {
$deljournal = 0;
}
if (!empty($delmonth) || !empty($delyear) || !empty($deljournal)) {
$result = $object->deleteByYearAndJournal($delyear, $deljournal, '', ($delmonth > 0 ? $delmonth : 0));
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
} else {
setEventMessages("RecordDeleted", null, 'mesgs');
// Message for elements well deleted
if ($nbok > 1) {
setEventMessages($langs->trans("RecordsDeleted", $nbok), null, 'mesgs');
} elseif ($nbok > 0) {
setEventMessages($langs->trans("RecordDeleted", $nbok), null, 'mesgs');
} elseif (!$error) {
setEventMessages($langs->trans("NoRecordDeleted"), null, 'mesgs');
}
// Make a redirect to avoid to launch the delete later after a back button
header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : ''));
exit;
} else {
setEventMessages("NoRecordDeleted", null, 'warnings');
}
}
if ($action == 'delmouvconfirm' && $user->rights->accounting->mouvements->supprimer) {
$mvt_num = GETPOST('mvt_num', 'int');
if (!empty($mvt_num)) {
$result = $object->deleteMvtNum($mvt_num);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
} else {
setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs');
if (!$error) {
header("Location: ".$_SERVER["PHP_SELF"]."?noreset=1".($param ? '&'.$param : ''));
exit;
}
}
header("Location: ".$_SERVER["PHP_SELF"]."?noreset=1".($param ? '&'.$param : ''));
exit;
// others mass actions
if (!$error && getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && $user->rights->accounting->mouvements->creer) {
if ($massaction == 'lettering') {
$lettering = new Lettering($db);
$nb_lettering = $lettering->bookkeepingLetteringAll($toselect);
if ($nb_lettering < 0) {
setEventMessages('', $lettering->errors, 'errors');
$error++;
$nb_lettering = max(0, abs($nb_lettering) - 2);
} elseif ($nb_lettering == 0) {
$nb_lettering = 0;
setEventMessages($langs->trans('AccountancyNoLetteringModified'), array(), 'mesgs');
}
if ($nb_lettering == 1) {
setEventMessages($langs->trans('AccountancyOneLetteringModifiedSuccessfully'), array(), 'mesgs');
} elseif ($nb_lettering > 1) {
setEventMessages($langs->trans('AccountancyLetteringModifiedSuccessfully', $nb_lettering), array(), 'mesgs');
}
if (!$error) {
header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param);
exit();
}
} elseif ($action == 'unlettering' && $confirm == "yes") {
$lettering = new Lettering($db);
$nb_lettering = $lettering->bookkeepingLetteringAll($toselect, true);
if ($nb_lettering < 0) {
setEventMessages('', $lettering->errors, 'errors');
$error++;
$nb_lettering = max(0, abs($nb_lettering) - 2);
} elseif ($nb_lettering == 0) {
$nb_lettering = 0;
setEventMessages($langs->trans('AccountancyNoUnletteringModified'), array(), 'mesgs');
}
if ($nb_lettering == 1) {
setEventMessages($langs->trans('AccountancyOneUnletteringModifiedSuccessfully'), array(), 'mesgs');
} elseif ($nb_lettering > 1) {
setEventMessages($langs->trans('AccountancyUnletteringModifiedSuccessfully', $nb_lettering), array(), 'mesgs');
}
if (!$error) {
header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param);
exit();
}
}
}
}
@ -394,73 +494,102 @@ $formfile = new FormFile($db);
$formother = new FormOther($db);
$form = new Form($db);
$title_page = $langs->trans("Operations").' - '.$langs->trans("VueByAccountAccounting").' ('.$langs->trans("Bookkeeping").')';
$title_page = $langs->trans("Operations").' - '.$langs->trans("VueByAccountAccounting").' (';
if ($type == 'sub') {
$title_page .= $langs->trans("BookkeepingSubAccount");
} else {
$title_page .= $langs->trans("Bookkeeping");
}
$title_page .= ')';
llxHeader('', $title_page);
// List
$nbtotalofrecords = '';
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
$nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter);
if ($type == 'sub') {
$nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter, 'AND', 1);
} else {
$nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter);
}
if ($nbtotalofrecords < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
}
$result = $object->fetchAllByAccount($sortorder, $sortfield, $limit, $offset, $filter);
if ($type == 'sub') {
$result = $object->fetchAllByAccount($sortorder, $sortfield, $limit, $offset, $filter, 'AND', 1);
} else {
$result = $object->fetchAllByAccount($sortorder, $sortfield, $limit, $offset, $filter);
}
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
$arrayofselected = is_array($toselect) ? $toselect : array();
$num = count($object->lines);
if ($action == 'delmouv') {
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?mvt_num='.GETPOST('mvt_num'), $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvtPartial'), 'delmouvconfirm', '', 0, 1);
print $formconfirm;
///if ($action == 'delbookkeepingyear') {
// $form_question = array();
// $delyear = GETPOST('delyear', 'int');
// $deljournal = GETPOST('deljournal', 'alpha');
//
// if (empty($delyear)) {
// $delyear = dol_print_date(dol_now(), '%Y');
// }
// $month_array = array();
// for ($i = 1; $i <= 12; $i++) {
// $month_array[$i] = $langs->trans("Month".sprintf("%02d", $i));
// }
// $year_array = $formaccounting->selectyear_accountancy_bookkepping($delyear, 'delyear', 0, 'array');
// $journal_array = $formaccounting->select_journal($deljournal, 'deljournal', '', 1, 1, 1, '', 0, 1);
//
// $form_question['delmonth'] = array(
// 'name' => 'delmonth',
// 'type' => 'select',
// 'label' => $langs->trans('DelMonth'),
// 'values' => $month_array,
// 'default' => ''
// );
// $form_question['delyear'] = array(
// 'name' => 'delyear',
// 'type' => 'select',
// 'label' => $langs->trans('DelYear'),
// 'values' => $year_array,
// 'default' => $delyear
// );
// $form_question['deljournal'] = array(
// 'name' => 'deljournal',
// 'type' => 'other', // We don't use select here, the journal_array is already a select html component
// 'label' => $langs->trans('DelJournal'),
// 'value' => $journal_array,
// 'default' => $deljournal
// );
//
// $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'delbookkeepingyearconfirm', $form_question, '', 1, 300);
//}
// Print form confirm
$formconfirm = '';
print $formconfirm;
// List of mass actions available
$arrayofmassactions = array();
if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && $user->rights->accounting->mouvements->creer) {
$arrayofmassactions['lettering'] = img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans('Lettering');
$arrayofmassactions['preunlettering'] = img_picto('', 'uncheck', 'class="pictofixedwidth"') . $langs->trans('Unlettering');
}
if ($action == 'delbookkeepingyear') {
$form_question = array();
$delyear = GETPOST('delyear', 'int');
$deljournal = GETPOST('deljournal', 'alpha');
if (empty($delyear)) {
$delyear = dol_print_date(dol_now(), '%Y');
}
$month_array = array();
for ($i = 1; $i <= 12; $i++) {
$month_array[$i] = $langs->trans("Month".sprintf("%02d", $i));
}
$year_array = $formaccounting->selectyear_accountancy_bookkepping($delyear, 'delyear', 0, 'array');
$journal_array = $formaccounting->select_journal($deljournal, 'deljournal', '', 1, 1, 1, '', 0, 1);
$form_question['delmonth'] = array(
'name' => 'delmonth',
'type' => 'select',
'label' => $langs->trans('DelMonth'),
'values' => $month_array,
'default' => ''
);
$form_question['delyear'] = array(
'name' => 'delyear',
'type' => 'select',
'label' => $langs->trans('DelYear'),
'values' => $year_array,
'default' => $delyear
);
$form_question['deljournal'] = array(
'name' => 'deljournal',
'type' => 'other', // We don't use select here, the journal_array is already a select html component
'label' => $langs->trans('DelJournal'),
'value' => $journal_array,
'default' => $deljournal
);
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'delbookkeepingyearconfirm', $form_question, '', 1, 300);
print $formconfirm;
if ($user->rights->accounting->mouvements->supprimer) {
$arrayofmassactions['predeletebookkeepingwriting'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
}
if (GETPOST('nomassaction', 'int') || in_array($massaction, array('preunlettering', 'predeletebookkeepingwriting'))) {
$arrayofmassactions = array();
}
$massactionbutton = $form->selectMassAction($massaction, $arrayofmassactions);
print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
@ -469,15 +598,22 @@ if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
}
print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
print '<input type="hidden" name="type" value="'.$type.'">';
print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
$parameters = array();
$reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
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('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected'));
$newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly'));
if ($type == 'sub') {
$newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?' . $url_param, '', 1, array('morecss' => 'marginleftonly'));
$newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?type=sub&' . $url_param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected'));
} else {
$newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?' . $url_param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected'));
$newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?type=sub&' . $url_param, '', 1, array('morecss' => 'marginleftonly'));
}
$newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create');
}
@ -488,11 +624,29 @@ if ($limit > 0 && $limit != $conf->liste_limit) {
$param .= '&limit='.urlencode($limit);
}
print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1);
print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1);
if ($massaction == 'preunlettering') {
print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassUnlettering"), $langs->trans("ConfirmMassUnletteringQuestion", count($toselect)), "unlettering", null, '', 0, 200, 500, 1);
} elseif ($massaction == 'predeletebookkeepingwriting') {
print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassDeleteBookkeepingWriting"), $langs->trans("ConfirmMassDeleteBookkeepingWritingQuestion", count($toselect)), "deletebookkeepingwriting", null, '', 0, 200, 500, 1);
}
//DeleteMvt=Supprimer des lignes d'opérations de la comptabilité
//DelMonth=Mois à effacer
//DelYear=Année à supprimer
//DelJournal=Journal à supprimer
//ConfirmDeleteMvt=Cette action supprime les lignes des opérations pour l'année/mois et/ou pour le journal sélectionné (au moins un critère est requis). Vous devrez utiliser de nouveau la fonctionnalité '%s' pour retrouver vos écritures dans la comptabilité.
//ConfirmDeleteMvtPartial=Cette action supprime l'écriture de la comptabilité (toutes les lignes opérations liées à une même écriture seront effacées).
//$topicmail = "Information";
//$modelmail = "accountingbookkeeping";
//$objecttmp = new BookKeeping($db);
//$trackid = 'bk'.$object->id;
include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
if ($massactionbutton) {
if ($massactionbutton && $contextpage != 'poslist') {
$selectedfields .= $form->showCheckAddButtons('checkforselect', 1);
}
@ -503,15 +657,28 @@ if (preg_match('/^asc/i', $sortorder)) {
$sortorder = "desc";
}
// Warning to explain why list of record is not consistent with the other list view (missing a lot of lines)
if ($type == 'sub') {
print info_admin($langs->trans("WarningRecordWithoutSubledgerAreExcluded"));
}
$moreforfilter = '';
// Accountancy account
$moreforfilter .= '<div class="divsearchfield">';
$moreforfilter .= $langs->trans('AccountAccounting').': ';
$moreforfilter .= '<div class="nowrap inline-block">';
$moreforfilter .= $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth200');
if ($type == 'sub') {
$moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), 'maxwidth200');
} else {
$moreforfilter .= $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth200');
}
$moreforfilter .= ' ';
$moreforfilter .= $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth200');
if ($type == 'sub') {
$moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), 'maxwidth200');
} else {
$moreforfilter .= $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth200');
}
$moreforfilter .= '</div>';
$moreforfilter .= '</div>';
@ -599,6 +766,11 @@ if (!empty($arrayfields['t.date_validated']['checked'])) {
print '</div>';
print '</td>';
}
if (!empty($arrayfields['t.import_key']['checked'])) {
print '<td class="liste_titre center">';
print '<input class="flat searchstring maxwidth50" type="text" name="search_import_key" value="'.dol_escape_htmltag($search_import_key).'">';
print '</td>';
}
// Fields from hook
$parameters = array('arrayfields'=>$arrayfields);
@ -643,6 +815,9 @@ if (!empty($arrayfields['t.date_export']['checked'])) {
if (!empty($arrayfields['t.date_validated']['checked'])) {
print_liste_field_titre($arrayfields['t.date_validated']['label'], $_SERVER['PHP_SELF'], "t.date_validated", "", $param, '', $sortfield, $sortorder, 'center ');
}
if (!empty($arrayfields['t.import_key']['checked'])) {
print_liste_field_titre($arrayfields['t.import_key']['label'], $_SERVER["PHP_SELF"], "t.import_key", "", $param, '', $sortfield, $sortorder, 'center ');
}
// Hook fields
$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder);
$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook
@ -650,24 +825,33 @@ print $hookmanager->resPrint;
print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
print "</tr>\n";
$total_debit = 0;
$total_credit = 0;
$sous_total_debit = 0;
$sous_total_credit = 0;
$displayed_account_number = null; // Start with undefined to be able to distinguish with empty
// Loop on record
// --------------------------------------------------------------------
$i = 0;
$totalarray = array();
$totalarray['val'] = array ();
$totalarray['nbfield'] = 0;
$total_debit = 0;
$total_credit = 0;
$sous_total_debit = 0;
$sous_total_credit = 0;
$totalarray['val']['totaldebit'] = 0;
$totalarray['val']['totalcredit'] = 0;
while ($i < min($num, $limit)) {
$line = $object->lines[$i];
$total_debit += $line->debit;
$total_credit += $line->credit;
$accountg = length_accountg($line->numero_compte);
if ($type == 'sub') {
$accountg = length_accounta($line->subledger_account);
} else {
$accountg = length_accountg($line->numero_compte);
}
//if (empty($accountg)) $accountg = '-';
$colspan = 0; // colspan before field 'label of operation'
@ -686,7 +870,11 @@ while ($i < min($num, $limit)) {
// Show a subtotal by accounting account
if (isset($displayed_account_number)) {
print '<tr class="liste_total">';
print '<td class="right" colspan="'.$colspan.'">'.$langs->trans("TotalForAccount").' '.length_accountg($displayed_account_number).':</td>';
if ($type == 'sub') {
print '<td class="right" colspan="' . $colspan . '">' . $langs->trans("TotalForAccount") . ' ' . length_accounta($displayed_account_number) . ':</td>';
} else {
print '<td class="right" colspan="' . $colspan . '">' . $langs->trans("TotalForAccount") . ' ' . length_accountg($displayed_account_number) . ':</td>';
}
print '<td class="nowrap right">'.price($sous_total_debit).'</td>';
print '<td class="nowrap right">'.price($sous_total_credit).'</td>';
print '<td colspan="'.$colspanend.'"></td>';
@ -712,11 +900,28 @@ while ($i < min($num, $limit)) {
// Show the break account
print '<tr class="trforbreak">';
print '<td colspan="'.($totalarray['nbfield'] ? $totalarray['nbfield'] : 10).'" class="tdforbreak">';
if ($line->numero_compte != "" && $line->numero_compte != '-1') {
print length_accountg($line->numero_compte).' : '.$object->get_compte_desc($line->numero_compte);
print '<td colspan="'.($totalarray['nbfield'] ? $totalarray['nbfield'] : count($arrayfields)+1).'" class="tdforbreak">';
if ($type == 'sub') {
if ($line->subledger_account != "" && $line->subledger_account != '-1') {
print $line->subledger_label . ' : ' . length_accounta($line->subledger_account);
} else {
// Should not happen: subledger account must be null or a non empty value
print '<span class="error">' . $langs->trans("Unknown");
if ($line->subledger_label) {
print ' (' . $line->subledger_label . ')';
$htmltext = 'EmptyStringForSubledgerAccountButSubledgerLabelDefined';
} else {
$htmltext = 'EmptyStringForSubledgerAccountAndSubledgerLabel';
}
print $form->textwithpicto('', $htmltext);
print '</span>';
}
} else {
print '<span class="error">'.$langs->trans("Unknown").'</span>';
if ($line->numero_compte != "" && $line->numero_compte != '-1') {
print length_accountg($line->numero_compte) . ' : ' . $object->get_compte_desc($line->numero_compte);
} else {
print '<span class="error">' . $langs->trans("Unknown") . '</span>';
}
}
print '</td>';
print '</tr>';
@ -890,22 +1095,26 @@ while ($i < min($num, $limit)) {
}
}
if (!empty($arrayfields['t.import_key']['checked'])) {
print '<td class="tdoverflowmax100">'.$line->import_key."</td>\n";
if (!$i) {
$totalarray['nbfield']++;
}
}
// Fields from hook
$parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj);
$parameters = array('arrayfields'=>$arrayfields, 'obj'=>$line);
$reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
// Action column
print '<td class="nowraponall center">';
if (empty($line->date_export) && empty($line->date_validation)) {
if ($user->rights->accounting->mouvements->creer) {
print '<a class="editfielda paddingleft marginrightonly" href="' . DOL_URL_ROOT . '/accountancy/bookkeeping/card.php?piece_num=' . $line->piece_num . $param . '&page=' . $page . ($sortfield ? '&sortfield=' . $sortfield : '') . ($sortorder ? '&sortorder=' . $sortorder : '') . '">' . img_edit() . '</a>';
}
}
if (empty($line->date_validation)) {
if ($user->rights->accounting->mouvements->supprimer) {
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>';
if (($massactionbutton || $massaction) && $contextpage != 'poslist') { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
$selected = 0;
if (in_array($line->id, $arrayofselected)) {
$selected = 1;
}
print '<input id="cb' . $line->id . '" class="flat checkforselect" type="checkbox" name="toselect[]" value="' . $line->id . '"' . ($selected ? ' checked="checked"' : '') . ' />';
}
print '</td>';
if (!$i) {
@ -955,11 +1164,11 @@ print "</table>";
print '</div>';
// TODO Replace this with mass delete action
if ($user->rights->accounting->mouvements->supprimer_tous) {
print '<div class="tabsAction tabsActionNoBottom">'."\n";
print '<a class="butActionDelete" name="button_delmvt" href="'.$_SERVER["PHP_SELF"].'?action=delbookkeepingyear&token='.newToken().($param ? '&'.$param : '').'">'.$langs->trans("DeleteMvt").'</a>';
print '</div>';
}
//if ($user->rights->accounting->mouvements->supprimer_tous) {
// print '<div class="tabsAction tabsActionNoBottom">'."\n";
// print '<a class="butActionDelete" name="button_delmvt" href="'.$_SERVER["PHP_SELF"].'?action=delbookkeepingyear&token='.newToken().($param ? '&'.$param : '').'">'.$langs->trans("DeleteMvt").'</a>';
// print '</div>';
//}
print '</form>';

View File

@ -1,979 +0,0 @@
<?php
/* Copyright (C) 2016 Neil Orley <neil.orley@oeris.fr>
* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2020 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2018-2020 Frédéric France <frederic.france@netlogic.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/accountancy/bookkeeping/listbysubaccount.php
* \ingroup Accountancy (Double entries)
* \brief List operation of ledger ordered by subaccount number
*/
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
// Load translation files required by the page
$langs->loadLangs(array("accountancy", "compta"));
$action = GETPOST('action', 'aZ09');
$search_date_startyear = GETPOST('search_date_startyear', 'int');
$search_date_startmonth = GETPOST('search_date_startmonth', 'int');
$search_date_startday = GETPOST('search_date_startday', 'int');
$search_date_endyear = GETPOST('search_date_endyear', 'int');
$search_date_endmonth = GETPOST('search_date_endmonth', 'int');
$search_date_endday = GETPOST('search_date_endday', 'int');
$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear);
$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear);
$search_doc_date = dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int'));
$search_date_export_startyear = GETPOST('search_date_export_startyear', 'int');
$search_date_export_startmonth = GETPOST('search_date_export_startmonth', 'int');
$search_date_export_startday = GETPOST('search_date_export_startday', 'int');
$search_date_export_endyear = GETPOST('search_date_export_endyear', 'int');
$search_date_export_endmonth = GETPOST('search_date_export_endmonth', 'int');
$search_date_export_endday = GETPOST('search_date_export_endday', 'int');
$search_date_export_start = dol_mktime(0, 0, 0, $search_date_export_startmonth, $search_date_export_startday, $search_date_export_startyear);
$search_date_export_end = dol_mktime(23, 59, 59, $search_date_export_endmonth, $search_date_export_endday, $search_date_export_endyear);
$search_date_validation_startyear = GETPOST('search_date_validation_startyear', 'int');
$search_date_validation_startmonth = GETPOST('search_date_validation_startmonth', 'int');
$search_date_validation_startday = GETPOST('search_date_validation_startday', 'int');
$search_date_validation_endyear = GETPOST('search_date_validation_endyear', 'int');
$search_date_validation_endmonth = GETPOST('search_date_validation_endmonth', 'int');
$search_date_validation_endday = GETPOST('search_date_validation_endday', 'int');
$search_date_validation_start = dol_mktime(0, 0, 0, $search_date_validation_startmonth, $search_date_validation_startday, $search_date_validation_startyear);
$search_date_validation_end = dol_mktime(23, 59, 59, $search_date_validation_endmonth, $search_date_validation_endday, $search_date_validation_endyear);
$search_accountancy_code = GETPOST("search_accountancy_code");
$search_accountancy_code_start = GETPOST('search_accountancy_code_start', 'alpha');
if ($search_accountancy_code_start == - 1) {
$search_accountancy_code_start = '';
}
$search_accountancy_code_end = GETPOST('search_accountancy_code_end', 'alpha');
if ($search_accountancy_code_end == - 1) {
$search_accountancy_code_end = '';
}
$search_doc_ref = GETPOST('search_doc_ref', 'alpha');
$search_label_operation = GETPOST('search_label_operation', 'alpha');
$search_mvt_num = GETPOST('search_mvt_num', 'int');
$search_direction = GETPOST('search_direction', 'alpha');
$search_ledger_code = GETPOST('search_ledger_code', 'array');
$search_debit = GETPOST('search_debit', 'alpha');
$search_credit = GETPOST('search_credit', 'alpha');
$search_lettering_code = GETPOST('search_lettering_code', 'alpha');
$search_not_reconciled = GETPOST('search_not_reconciled', 'alpha');
if (GETPOST("button_delmvt_x") || GETPOST("button_delmvt.x") || GETPOST("button_delmvt")) {
$action = 'delbookkeepingyear';
}
// Load variable for pagination
$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION);
$sortfield = GETPOST('sortfield', 'aZ09comma');
$sortorder = GETPOST('sortorder', 'aZ09comma');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page < 0) {
$page = 0;
}
$offset = $limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
if ($sortorder == "") {
$sortorder = "ASC";
}
if ($sortfield == "") {
$sortfield = "t.doc_date,t.rowid";
}
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$object = new BookKeeping($db);
$formfile = new FormFile($db);
$hookmanager->initHooks(array('bookkeepingbysubaccountlist'));
$formaccounting = new FormAccounting($db);
$form = new Form($db);
if (empty($search_date_start) && empty($search_date_end) && !GETPOSTISSET('search_date_startday') && !GETPOSTISSET('search_date_startmonth') && !GETPOSTISSET('search_date_starthour')) {
$sql = "SELECT date_start, date_end from ".MAIN_DB_PREFIX."accounting_fiscalyear ";
$sql .= " where date_start < '".$db->idate(dol_now())."' and date_end > '".$db->idate(dol_now())."'";
$sql .= $db->plimit(1);
$res = $db->query($sql);
if ($res->num_rows > 0) {
$fiscalYear = $db->fetch_object($res);
$search_date_start = strtotime($fiscalYear->date_start);
$search_date_end = strtotime($fiscalYear->date_end);
} else {
$month_start = ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1);
$year_start = dol_print_date(dol_now(), '%Y');
if (dol_print_date(dol_now(), '%m') < $month_start) {
$year_start--; // If current month is lower that starting fiscal month, we start last year
}
$year_end = $year_start + 1;
$month_end = $month_start - 1;
if ($month_end < 1) {
$month_end = 12;
$year_end--;
}
$search_date_start = dol_mktime(0, 0, 0, $month_start, 1, $year_start);
$search_date_end = dol_get_last_day($year_end, $month_end);
}
}
$arrayfields = array(
// 't.subledger_account'=>array('label'=>$langs->trans("SubledgerAccount"), 'checked'=>1),
't.piece_num'=>array('label'=>$langs->trans("TransactionNumShort"), 'checked'=>1),
't.code_journal'=>array('label'=>$langs->trans("Codejournal"), 'checked'=>1),
't.doc_date'=>array('label'=>$langs->trans("Docdate"), 'checked'=>1),
't.doc_ref'=>array('label'=>$langs->trans("Piece"), 'checked'=>1),
't.label_operation'=>array('label'=>$langs->trans("Label"), 'checked'=>1),
't.debit'=>array('label'=>$langs->trans("Debit"), 'checked'=>1),
't.credit'=>array('label'=>$langs->trans("Credit"), 'checked'=>1),
't.lettering_code'=>array('label'=>$langs->trans("LetteringCode"), 'checked'=>1),
't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1),
't.date_validated'=>array('label'=>$langs->trans("DateValidation"), 'checked'=>1),
);
if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) {
unset($arrayfields['t.lettering_code']);
}
if ($search_date_start && empty($search_date_startyear)) {
$tmparray = dol_getdate($search_date_start);
$search_date_startyear = $tmparray['year'];
$search_date_startmonth = $tmparray['mon'];
$search_date_startday = $tmparray['mday'];
}
if ($search_date_end && empty($search_date_endyear)) {
$tmparray = dol_getdate($search_date_end);
$search_date_endyear = $tmparray['year'];
$search_date_endmonth = $tmparray['mon'];
$search_date_endday = $tmparray['mday'];
}
if (empty($conf->accounting->enabled)) {
accessforbidden();
}
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->mouvements->lire)) {
accessforbidden();
}
/*
* Action
*/
if (GETPOST('cancel', 'alpha')) {
$action = 'list'; $massaction = '';
}
if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') {
$massaction = '';
}
$parameters = array('socid'=>$socid);
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
}
if (empty($reshook)) {
include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php';
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
$search_doc_date = '';
$search_accountancy_code = '';
$search_accountancy_code_start = '';
$search_accountancy_code_end = '';
$search_label_account = '';
$search_doc_ref = '';
$search_label_operation = '';
$search_mvt_num = '';
$search_direction = '';
$search_ledger_code = array();
$search_date_start = '';
$search_date_end = '';
$search_date_startyear = '';
$search_date_startmonth = '';
$search_date_startday = '';
$search_date_endyear = '';
$search_date_endmonth = '';
$search_date_endday = '';
$search_date_export_start = '';
$search_date_export_end = '';
$search_date_export_startyear = '';
$search_date_export_startmonth = '';
$search_date_export_startday = '';
$search_date_export_endyear = '';
$search_date_export_endmonth = '';
$search_date_export_endday = '';
$search_date_validation_start = '';
$search_date_validation_end = '';
$search_date_validation_startyear = '';
$search_date_validation_startmonth = '';
$search_date_validation_startday = '';
$search_date_validation_endyear = '';
$search_date_validation_endmonth = '';
$search_date_validation_endday = '';
$search_debit = '';
$search_credit = '';
$search_lettering_code = '';
$search_not_reconciled = '';
}
// Must be after the remove filter action, before the export.
$param = '';
$filter = array();
if (!empty($search_date_start)) {
$filter['t.doc_date>='] = $search_date_start;
$param .= '&search_date_startmonth='.$search_date_startmonth.'&search_date_startday='.$search_date_startday.'&search_date_startyear='.$search_date_startyear;
}
if (!empty($search_date_end)) {
$filter['t.doc_date<='] = $search_date_end;
$param .= '&search_date_endmonth='.$search_date_endmonth.'&search_date_endday='.$search_date_endday.'&search_date_endyear='.$search_date_endyear;
}
if (!empty($search_doc_date)) {
$filter['t.doc_date'] = $search_doc_date;
$param .= '&doc_datemonth='.GETPOST('doc_datemonth', 'int').'&doc_dateday='.GETPOST('doc_dateday', 'int').'&doc_dateyear='.GETPOST('doc_dateyear', 'int');
}
if (!empty($search_accountancy_code_start)) {
$filter['t.subledger_account>='] = $search_accountancy_code_start;
$param .= '&search_accountancy_code_start='.urlencode($search_accountancy_code_start);
}
if (!empty($search_accountancy_code_end)) {
$filter['t.subledger_account<='] = $search_accountancy_code_end;
$param .= '&search_accountancy_code_end='.urlencode($search_accountancy_code_end);
}
if (!empty($search_label_account)) {
$filter['t.label_compte'] = $search_label_account;
$param .= '&search_label_compte='.urlencode($search_label_account);
}
if (!empty($search_mvt_num)) {
$filter['t.piece_num'] = $search_mvt_num;
$param .= '&search_mvt_num='.urlencode($search_mvt_num);
}
if (!empty($search_doc_ref)) {
$filter['t.doc_ref'] = $search_doc_ref;
$param .= '&search_doc_ref='.urlencode($search_doc_ref);
}
if (!empty($search_label_operation)) {
$filter['t.label_operation'] = $search_label_operation;
$param .= '&search_label_operation='.urlencode($search_label_operation);
}
if (!empty($search_direction)) {
$filter['t.sens'] = $search_direction;
$param .= '&search_direction='.urlencode($search_direction);
}
if (!empty($search_ledger_code)) {
$filter['t.code_journal'] = $search_ledger_code;
foreach ($search_ledger_code as $code) {
$param .= '&search_ledger_code[]='.urlencode($code);
}
}
if (!empty($search_debit)) {
$filter['t.debit'] = $search_debit;
$param .= '&search_debit='.urlencode($search_debit);
}
if (!empty($search_credit)) {
$filter['t.credit'] = $search_credit;
$param .= '&search_credit='.urlencode($search_credit);
}
if (!empty($search_lettering_code)) {
$filter['t.lettering_code'] = $search_lettering_code;
$param .= '&search_lettering_code='.urlencode($search_lettering_code);
}
if (!empty($search_not_reconciled)) {
$filter['t.reconciled_option'] = $search_not_reconciled;
$param .= '&search_not_reconciled='.urlencode($search_not_reconciled);
}
if (!empty($search_date_export_start)) {
$filter['t.date_export>='] = $search_date_export_start;
$param .= '&search_date_export_startmonth='.$search_date_export_startmonth.'&search_date_export_startday='.$search_date_export_startday.'&search_date_export_startyear='.$search_date_export_startyear;
}
if (!empty($search_date_export_end)) {
$filter['t.date_export<='] = $search_date_export_end;
$param .= '&search_date_export_endmonth='.$search_date_export_endmonth.'&search_date_export_endday='.$search_date_export_endday.'&search_date_export_endyear='.$search_date_export_endyear;
}
if (!empty($search_date_validation_start)) {
$filter['t.date_validated>='] = $search_date_validation_start;
$param .= '&search_date_validation_startmonth='.$search_date_validation_startmonth.'&search_date_validation_startday='.$search_date_validation_startday.'&search_date_validation_startyear='.$search_date_validation_startyear;
}
if (!empty($search_date_validation_end)) {
$filter['t.date_validated<='] = $search_date_validation_end;
$param .= '&search_date_validation_endmonth='.$search_date_validation_endmonth.'&search_date_validation_endday='.$search_date_validation_endday.'&search_date_validation_endyear='.$search_date_validation_endyear;
}
}
if ($action == 'delbookkeeping' && $user->rights->accounting->mouvements->supprimer) {
$import_key = GETPOST('importkey', 'alpha');
if (!empty($import_key)) {
$result = $object->deleteByImportkey($import_key);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
// Make a redirect to avoid to launch the delete later after a back button
header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : ''));
exit;
}
}
if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouvements->supprimer_tous) {
$delmonth = GETPOST('delmonth', 'int');
$delyear = GETPOST('delyear', 'int');
if ($delyear == -1) {
$delyear = 0;
}
$deljournal = GETPOST('deljournal', 'alpha');
if ($deljournal == -1) {
$deljournal = 0;
}
if (!empty($delmonth) || !empty($delyear) || !empty($deljournal)) {
$result = $object->deleteByYearAndJournal($delyear, $deljournal, '', ($delmonth > 0 ? $delmonth : 0));
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
} else {
setEventMessages("RecordDeleted", null, 'mesgs');
}
// Make a redirect to avoid to launch the delete later after a back button
header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : ''));
exit;
} else {
setEventMessages("NoRecordDeleted", null, 'warnings');
}
}
if ($action == 'delmouvconfirm' && $user->rights->accounting->mouvements->supprimer) {
$mvt_num = GETPOST('mvt_num', 'int');
if (!empty($mvt_num)) {
$result = $object->deleteMvtNum($mvt_num);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
} else {
setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs');
}
header("Location: ".$_SERVER["PHP_SELF"]."?noreset=1".($param ? '&'.$param : ''));
exit;
}
}
/*
* View
*/
$formaccounting = new FormAccounting($db);
$formfile = new FormFile($db);
$formother = new FormOther($db);
$form = new Form($db);
$title_page = $langs->trans("Operations").' - '.$langs->trans("VueByAccountAccounting").' ('.$langs->trans("BookkeepingSubAccount").')';
llxHeader('', $title_page);
// List
$nbtotalofrecords = '';
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
$nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter, 'AND', 1);
if ($nbtotalofrecords < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
}
$result = $object->fetchAllByAccount($sortorder, $sortfield, $limit, $offset, $filter, 'AND', 1);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
$num = count($object->lines);
if ($action == 'delmouv') {
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?mvt_num='.GETPOST('mvt_num'), $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvtPartial'), 'delmouvconfirm', '', 0, 1);
print $formconfirm;
}
if ($action == 'delbookkeepingyear') {
$form_question = array();
$delyear = GETPOST('delyear', 'int');
$deljournal = GETPOST('deljournal', 'alpha');
if (empty($delyear)) {
$delyear = dol_print_date(dol_now(), '%Y');
}
$month_array = array();
for ($i = 1; $i <= 12; $i++) {
$month_array[$i] = $langs->trans("Month".sprintf("%02d", $i));
}
$year_array = $formaccounting->selectyear_accountancy_bookkepping($delyear, 'delyear', 0, 'array');
$journal_array = $formaccounting->select_journal($deljournal, 'deljournal', '', 1, 1, 1, '', 0, 1);
$form_question['delmonth'] = array(
'name' => 'delmonth',
'type' => 'select',
'label' => $langs->trans('DelMonth'),
'values' => $month_array,
'default' => ''
);
$form_question['delyear'] = array(
'name' => 'delyear',
'type' => 'select',
'label' => $langs->trans('DelYear'),
'values' => $year_array,
'default' => $delyear
);
$form_question['deljournal'] = array(
'name' => 'deljournal',
'type' => 'other', // We don't use select here, the journal_array is already a select html component
'label' => $langs->trans('DelJournal'),
'value' => $journal_array,
'default' => $deljournal
);
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'delbookkeepingyearconfirm', $form_question, '', 1, 300);
print $formconfirm;
}
print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="list">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
}
print '<input type="hidden" name="formfilteraction" id="formfilteraction" value="list">';
print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
$parameters = array();
$reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
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('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly'));
$newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected'));
$newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create');
}
if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
$param .= '&contextpage='.urlencode($contextpage);
}
if ($limit > 0 && $limit != $conf->liste_limit) {
$param .= '&limit='.urlencode($limit);
}
print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1);
print info_admin($langs->trans("WarningRecordWithoutSubledgerAreExcluded"));
$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
if ($massactionbutton) {
$selectedfields .= $form->showCheckAddButtons('checkforselect', 1);
}
// Reverse sort order
if (preg_match('/^asc/i', $sortorder)) {
$sortorder = "asc";
} else {
$sortorder = "desc";
}
$moreforfilter = '';
// Accountancy account
$moreforfilter .= '<div class="divsearchfield">';
$moreforfilter .= $langs->trans('AccountAccounting').': ';
$moreforfilter .= '<div class="nowrap inline-block">';
$moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), 'maxwidth200');
$moreforfilter .= ' ';
$moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), 'maxwidth200');
$moreforfilter .= '</div>';
$moreforfilter .= '</div>';
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
if (empty($reshook)) {
$moreforfilter .= $hookmanager->resPrint;
} else {
$moreforfilter = $hookmanager->resPrint;
}
print '<div class="liste_titre liste_titre_bydiv centpercent">';
print $moreforfilter;
print '</div>';
print '<div class="div-table-responsive">';
print '<table class="tagtable liste centpercent">';
// Filters lines
print '<tr class="liste_titre_filter">';
// Movement number
if (!empty($arrayfields['t.piece_num']['checked'])) {
print '<td class="liste_titre"><input type="text" name="search_mvt_num" size="6" value="'.dol_escape_htmltag($search_mvt_num).'"></td>';
}
// Code journal
if (!empty($arrayfields['t.code_journal']['checked'])) {
print '<td class="liste_titre center">';
print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1);
print '</td>';
}
// Date document
if (!empty($arrayfields['t.doc_date']['checked'])) {
print '<td class="liste_titre center">';
print '<div class="nowrap">';
print $form->selectDate($search_date_start, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"));
print '</div>';
print '<div class="nowrap">';
print $form->selectDate($search_date_end, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"));
print '</div>';
print '</td>';
}
// Ref document
if (!empty($arrayfields['t.doc_ref']['checked'])) {
print '<td class="liste_titre"><input type="text" size="7" class="flat" name="search_doc_ref" value="'.dol_escape_htmltag($search_doc_ref).'"/></td>';
}
// Label operation
if (!empty($arrayfields['t.label_operation']['checked'])) {
print '<td class="liste_titre"><input type="text" size="7" class="flat" name="search_label_operation" value="'.dol_escape_htmltag($search_label_operation).'"/></td>';
}
// Debit
if (!empty($arrayfields['t.debit']['checked'])) {
print '<td class="liste_titre right"><input type="text" class="flat" name="search_debit" size="4" value="'.dol_escape_htmltag($search_debit).'"></td>';
}
// Credit
if (!empty($arrayfields['t.credit']['checked'])) {
print '<td class="liste_titre right"><input type="text" class="flat" name="search_credit" size="4" value="'.dol_escape_htmltag($search_credit).'"></td>';
}
// Lettering code
if (!empty($arrayfields['t.lettering_code']['checked'])) {
print '<td class="liste_titre center">';
print '<input type="text" size="3" class="flat" name="search_lettering_code" value="'.$search_lettering_code.'"/>';
print '<br><span class="nowrap"><input type="checkbox" name="search_not_reconciled" value="notreconciled"'.($search_not_reconciled == 'notreconciled' ? ' checked' : '').'>'.$langs->trans("NotReconciled").'</span>';
print '</td>';
}
// Date export
if (!empty($arrayfields['t.date_export']['checked'])) {
print '<td class="liste_titre center">';
print '<div class="nowrap">';
print $form->selectDate($search_date_export_start, 'search_date_export_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"));
print '</div>';
print '<div class="nowrap">';
print $form->selectDate($search_date_export_end, 'search_date_export_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"));
print '</div>';
print '</td>';
}
// Date validation
if (!empty($arrayfields['t.date_validated']['checked'])) {
print '<td class="liste_titre center">';
print '<div class="nowrap">';
print $form->selectDate($search_date_validation_start, 'search_date_validation_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"));
print '</div>';
print '<div class="nowrap">';
print $form->selectDate($search_date_validation_end, 'search_date_validation_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"));
print '</div>';
print '</td>';
}
// Fields from hook
$parameters = array('arrayfields'=>$arrayfields);
$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
// Action column
print '<td class="liste_titre center">';
$searchpicto = $form->showFilterButtons();
print $searchpicto;
print '</td>';
print "</tr>\n";
print '<tr class="liste_titre">';
if (!empty($arrayfields['t.piece_num']['checked'])) {
print_liste_field_titre($arrayfields['t.piece_num']['label'], $_SERVER['PHP_SELF'], "t.piece_num", "", $param, '', $sortfield, $sortorder);
}
if (!empty($arrayfields['t.code_journal']['checked'])) {
print_liste_field_titre($arrayfields['t.code_journal']['label'], $_SERVER['PHP_SELF'], "t.code_journal", "", $param, '', $sortfield, $sortorder, 'center ');
}
if (!empty($arrayfields['t.doc_date']['checked'])) {
print_liste_field_titre($arrayfields['t.doc_date']['label'], $_SERVER['PHP_SELF'], "t.doc_date", "", $param, '', $sortfield, $sortorder, 'center ');
}
if (!empty($arrayfields['t.doc_ref']['checked'])) {
print_liste_field_titre($arrayfields['t.doc_ref']['label'], $_SERVER['PHP_SELF'], "t.doc_ref", "", $param, "", $sortfield, $sortorder);
}
if (!empty($arrayfields['t.label_operation']['checked'])) {
print_liste_field_titre($arrayfields['t.label_operation']['label'], $_SERVER['PHP_SELF'], "t.label_operation", "", $param, "", $sortfield, $sortorder);
}
if (!empty($arrayfields['t.debit']['checked'])) {
print_liste_field_titre($arrayfields['t.debit']['label'], $_SERVER['PHP_SELF'], "t.debit", "", $param, '', $sortfield, $sortorder, 'right ');
}
if (!empty($arrayfields['t.credit']['checked'])) {
print_liste_field_titre($arrayfields['t.credit']['label'], $_SERVER['PHP_SELF'], "t.credit", "", $param, '', $sortfield, $sortorder, 'right ');
}
if (!empty($arrayfields['t.lettering_code']['checked'])) {
print_liste_field_titre($arrayfields['t.lettering_code']['label'], $_SERVER['PHP_SELF'], "t.lettering_code", "", $param, '', $sortfield, $sortorder, 'center ');
}
if (!empty($arrayfields['t.date_export']['checked'])) {
print_liste_field_titre($arrayfields['t.date_export']['label'], $_SERVER['PHP_SELF'], "t.date_export", "", $param, '', $sortfield, $sortorder, 'center ');
}
if (!empty($arrayfields['t.date_validated']['checked'])) {
print_liste_field_titre($arrayfields['t.date_validated']['label'], $_SERVER['PHP_SELF'], "t.date_validated", "", $param, '', $sortfield, $sortorder, 'center ');
}
// Hook fields
$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder);
$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
print "</tr>\n";
$total_debit = 0;
$total_credit = 0;
$sous_total_debit = 0;
$sous_total_credit = 0;
$displayed_account_number = null; // Start with undefined to be able to distinguish with empty
// Loop on record
// --------------------------------------------------------------------
$i = 0;
$totalarray = array();
while ($i < min($num, $limit)) {
$line = $object->lines[$i];
$total_debit += $line->debit;
$total_credit += $line->credit;
$accountg = length_accounta($line->subledger_account);
//if (empty($accountg)) $accountg = '-';
$colspan = 0; // colspan before field 'label of operation'
$colspanend = 3; // colspan after debit/credit
if (!empty($arrayfields['t.piece_num']['checked'])) { $colspan++; }
if (!empty($arrayfields['t.code_journal']['checked'])) { $colspan++; }
if (!empty($arrayfields['t.doc_date']['checked'])) { $colspan++; }
if (!empty($arrayfields['t.doc_ref']['checked'])) { $colspan++; }
if (!empty($arrayfields['t.label_operation']['checked'])) { $colspan++; }
if (!empty($arrayfields['t.date_export']['checked'])) { $colspanend++; }
if (!empty($arrayfields['t.date_validating']['checked'])) { $colspanend++; }
if (!empty($arrayfields['t.lettering_code']['checked'])) { $colspanend++; }
// Is it a break ?
if ($accountg != $displayed_account_number || !isset($displayed_account_number)) {
// Show a subtotal by accounting account
if (isset($displayed_account_number)) {
print '<tr class="liste_total">';
print '<td class="right" colspan="'.$colspan.'">'.$langs->trans("TotalForAccount").' '.length_accounta($displayed_account_number).':</td>';
print '<td class="nowrap right">'.price($sous_total_debit).'</td>';
print '<td class="nowrap right">'.price($sous_total_credit).'</td>';
print '<td colspan="'.$colspanend.'"></td>';
print '</tr>';
// Show balance of last shown account
$balance = $sous_total_debit - $sous_total_credit;
print '<tr class="liste_total">';
print '<td class="right" colspan="'.$colspan.'">'.$langs->trans("Balance").':</td>';
if ($balance > 0) {
print '<td class="nowraponall right">';
print price($sous_total_debit - $sous_total_credit);
print '</td>';
print '<td></td>';
} else {
print '<td></td>';
print '<td class="nowraponall right">';
print price($sous_total_credit - $sous_total_debit);
print '</td>';
}
print '<td colspan="'.$colspanend.'"></td>';
print '</tr>';
}
// Show the break account
print '<tr class="trforbreak">';
print '<td colspan="'.($totalarray['nbfield'] ? $totalarray['nbfield'] : 10).'" class="tdforbreak">';
if ($line->subledger_account != "" && $line->subledger_account != '-1') {
print $line->subledger_label.' : '.length_accounta($line->subledger_account);
} else {
// Should not happen: subledger account must be null or a non empty value
print '<span class="error">'.$langs->trans("Unknown");
if ($line->subledger_label) {
print ' ('.$line->subledger_label.')';
$htmltext = 'EmptyStringForSubledgerAccountButSubledgerLabelDefined';
} else {
$htmltext = 'EmptyStringForSubledgerAccountAndSubledgerLabel';
}
print $form->textwithpicto('', $htmltext);
print '</span>';
}
print '</td>';
print '</tr>';
$displayed_account_number = $accountg;
//if (empty($displayed_account_number)) $displayed_account_number='-';
$sous_total_debit = 0;
$sous_total_credit = 0;
$colspan = 0;
}
print '<tr class="oddeven">';
// Piece number
if (!empty($arrayfields['t.piece_num']['checked'])) {
print '<td>';
$object->id = $line->id;
$object->piece_num = $line->piece_num;
print $object->getNomUrl(1, '', 0, '', 1);
print '</td>';
if (!$i) {
$totalarray['nbfield']++;
}
}
// Journal code
if (!empty($arrayfields['t.code_journal']['checked'])) {
$accountingjournal = new AccountingJournal($db);
$result = $accountingjournal->fetch('', $line->code_journal);
$journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $line->code_journal);
print '<td class="center">'.$journaltoshow.'</td>';
if (!$i) {
$totalarray['nbfield']++;
}
}
// Document date
if (!empty($arrayfields['t.doc_date']['checked'])) {
print '<td class="center">'.dol_print_date($line->doc_date, 'day').'</td>';
if (!$i) {
$totalarray['nbfield']++;
}
}
// Document ref
if (!empty($arrayfields['t.doc_ref']['checked'])) {
if ($line->doc_type == 'customer_invoice') {
$langs->loadLangs(array('bills'));
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
$objectstatic = new Facture($db);
$objectstatic->fetch($line->fk_doc);
//$modulepart = 'facture';
$filename = dol_sanitizeFileName($line->doc_ref);
$filedir = $conf->facture->dir_output.'/'.dol_sanitizeFileName($line->doc_ref);
$urlsource = $_SERVER['PHP_SELF'].'?id='.$objectstatic->id;
$documentlink = $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir);
} elseif ($line->doc_type == 'supplier_invoice') {
$langs->loadLangs(array('bills'));
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
$objectstatic = new FactureFournisseur($db);
$objectstatic->fetch($line->fk_doc);
//$modulepart = 'invoice_supplier';
$filename = dol_sanitizeFileName($line->doc_ref);
$filedir = $conf->fournisseur->facture->dir_output.'/'.get_exdir($line->fk_doc, 2, 0, 0, $objectstatic, $modulepart).dol_sanitizeFileName($line->doc_ref);
$subdir = get_exdir($objectstatic->id, 2, 0, 0, $objectstatic, $modulepart).dol_sanitizeFileName($line->doc_ref);
$documentlink = $formfile->getDocumentsLink($objectstatic->element, $subdir, $filedir);
} elseif ($line->doc_type == 'expense_report') {
$langs->loadLangs(array('trips'));
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
$objectstatic = new ExpenseReport($db);
$objectstatic->fetch($line->fk_doc);
//$modulepart = 'expensereport';
$filename = dol_sanitizeFileName($line->doc_ref);
$filedir = $conf->expensereport->dir_output.'/'.dol_sanitizeFileName($line->doc_ref);
$urlsource = $_SERVER['PHP_SELF'].'?id='.$objectstatic->id;
$documentlink = $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir);
} elseif ($line->doc_type == 'bank') {
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
$objectstatic = new AccountLine($db);
$objectstatic->fetch($line->fk_doc);
} else {
// Other type
}
print '<td class="maxwidth400">';
print '<table class="nobordernopadding"><tr class="nocellnopadd">';
// Picto + Ref
print '<td class="nobordernopadding">';
if ($line->doc_type == 'customer_invoice' || $line->doc_type == 'supplier_invoice' || $line->doc_type == 'expense_report') {
print $objectstatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1);
print $documentlink;
} elseif ($line->doc_type == 'bank') {
print $objectstatic->getNomUrl(1);
$bank_ref = strstr($line->doc_ref, '-');
print " " . $bank_ref;
} else {
print $line->doc_ref;
}
print '</td></tr></table>';
print "</td>\n";
if (!$i) {
$totalarray['nbfield']++;
}
}
// Label operation
if (!empty($arrayfields['t.label_operation']['checked'])) {
// Affiche un lien vers la facture client/fournisseur
$doc_ref = preg_replace('/\(.*\)/', '', $line->doc_ref);
print strlen(length_accounta($line->subledger_account)) == 0 ? '<td>'.$line->label_operation.'</td>' : '<td>'.$line->label_operation.'<br><span style="font-size:0.8em">('.length_accounta($line->subledger_account).')</span></td>';
if (!$i) {
$totalarray['nbfield']++;
}
}
// Amount debit
if (!empty($arrayfields['t.debit']['checked'])) {
print '<td class="right nowraponall amount">'.($line->debit ? price($line->debit) : '').'</td>';
if (!$i) {
$totalarray['nbfield']++;
}
if (!$i) {
$totalarray['pos'][$totalarray['nbfield']] = 'totaldebit';
}
$totalarray['val']['totaldebit'] += $line->debit;
}
// Amount credit
if (!empty($arrayfields['t.credit']['checked'])) {
print '<td class="right nowraponall amount">'.($line->credit ? price($line->credit) : '').'</td>';
if (!$i) {
$totalarray['nbfield']++;
}
if (!$i) {
$totalarray['pos'][$totalarray['nbfield']] = 'totalcredit';
}
$totalarray['val']['totalcredit'] += $line->credit;
}
// Lettering code
if (!empty($arrayfields['t.lettering_code']['checked'])) {
print '<td class="center">'.$line->lettering_code.'</td>';
if (!$i) {
$totalarray['nbfield']++;
}
}
// Exported operation date
if (!empty($arrayfields['t.date_export']['checked'])) {
print '<td class="center">'.dol_print_date($line->date_export, 'dayhour').'</td>';
if (!$i) {
$totalarray['nbfield']++;
}
}
// Validated operation date
if (!empty($arrayfields['t.date_validated']['checked'])) {
print '<td class="center">'.dol_print_date($line->date_validation, 'dayhour').'</td>';
if (!$i) {
$totalarray['nbfield']++;
}
}
// Fields from hook
$parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj);
$reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
// Action column
print '<td class="nowraponall center">';
if (empty($line->date_export) && empty($line->date_validation)) {
if ($user->rights->accounting->mouvements->creer) {
print '<a class="editfielda paddingleft marginrightonly" href="' . DOL_URL_ROOT . '/accountancy/bookkeeping/card.php?piece_num=' . $line->piece_num . $param . '&page=' . $page . ($sortfield ? '&sortfield=' . $sortfield : '') . ($sortorder ? '&sortorder=' . $sortorder : '') . '">' . img_edit() . '</a>';
}
}
if (empty($line->date_validation)) {
if ($user->rights->accounting->mouvements->supprimer) {
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>';
if (!$i) {
$totalarray['nbfield']++;
}
// Comptabilise le sous-total
$sous_total_debit += $line->debit;
$sous_total_credit += $line->credit;
print "</tr>\n";
$i++;
}
if ($num > 0 && $colspan > 0) {
print '<tr class="liste_total">';
print '<td class="right" colspan="'.$colspan.'">'.$langs->trans("TotalForAccount").' '.$accountg.':</td>';
print '<td class="nowrap right">'.price($sous_total_debit).'</td>';
print '<td class="nowrap right">'.price($sous_total_credit).'</td>';
print '<td colspan="'.$colspanend.'"></td>';
print '</tr>';
// Show balance of last shown account
$balance = $sous_total_debit - $sous_total_credit;
print '<tr class="liste_total">';
print '<td class="right" colspan="'.$colspan.'">'.$langs->trans("Balance").':</td>';
if ($balance > 0) {
print '<td class="nowraponall right">';
print price($sous_total_debit - $sous_total_credit);
print '</td>';
print '<td></td>';
} else {
print '<td></td>';
print '<td class="nowraponall right">';
print price($sous_total_credit - $sous_total_debit);
print '</td>';
}
print '<td colspan="'.$colspanend.'"></td>';
print '</tr>';
}
// Show total line
include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
print "</table>";
print '</div>';
// TODO Replace this with mass delete action
if ($user->rights->accounting->mouvements->supprimer_tous) {
print '<div class="tabsAction tabsActionNoBottom">'."\n";
print '<a class="butActionDelete" name="button_delmvt" href="'.$_SERVER["PHP_SELF"].'?action=delbookkeepingyear&token='.newToken().($param ? '&'.$param : '').'">'.$langs->trans("DeleteMvt").'</a>';
print '</div>';
}
print '</form>';
// End of page
llxFooter();
$db->close();

View File

@ -785,12 +785,13 @@ class AccountancyCategory // extends CommonObject
}
/**
* Return list of custom groups that are active
* Return list of custom groups.
*
* @param int $categorytype -1=All, 0=Only non computed groups, 1=Only computed groups
* @param int $active 1= active, 0=not active
* @return array|int Array of groups or -1 if error
*/
public function getCats($categorytype = -1)
public function getCats($categorytype = -1, $active = 1)
{
global $conf, $mysoc;
@ -801,7 +802,7 @@ class AccountancyCategory // extends CommonObject
$sql = "SELECT c.rowid, c.code, c.label, c.formula, c.position, c.category_type, c.sens";
$sql .= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c";
$sql .= " WHERE c.active = 1";
$sql .= " WHERE c.active = " . (int) $active;
$sql .= " AND c.entity = ".$conf->entity;
if ($categorytype >= 0) {
$sql .= " AND c.category_type = 1";

View File

@ -11,6 +11,7 @@
* Copyright (C) 2017-2019 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2017 André Schild <a.schild@aarboard.ch>
* Copyright (C) 2020 Guillaume Alexandre <guillaume@tag-info.fr>
* Copyright (C) 2022 Joachim Kueter <jkueter@gmx.de>
*
* 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
@ -34,6 +35,7 @@
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
/**
@ -93,11 +95,13 @@ class AccountancyExport
*/
public function __construct(DoliDB $db)
{
global $conf;
global $conf, $hookmanager;
$this->db = $db;
$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");
$hookmanager->initHooks(array('accountancyexport'));
}
/**
@ -105,9 +109,9 @@ class AccountancyExport
*
* @return array of type
*/
public static function getType()
public function getType()
{
global $langs;
global $langs, $hookmanager;
$listofexporttypes = array(
self::$EXPORT_TYPE_CONFIGURABLE => $langs->trans('Modelcsv_configurable'),
@ -132,6 +136,10 @@ class AccountancyExport
self::$EXPORT_TYPE_ISUITEEXPERT => 'Export iSuite Expert',
);
// allow modules to define export formats
$parameters = array();
$reshook = $hookmanager->executeHooks('getType', $parameters, $listofexporttypes);
ksort($listofexporttypes, SORT_NUMERIC);
return $listofexporttypes;
@ -168,7 +176,12 @@ class AccountancyExport
self::$EXPORT_TYPE_ISUITEEXPERT => 'isuiteexpert',
);
return $formatcode[$type];
global $hookmanager;
$code = $formatcode[$type];
$parameters = array('type' => $type);
$reshook = $hookmanager->executeHooks('getFormatCode', $parameters, $code);
return $code;
}
/**
@ -176,11 +189,11 @@ class AccountancyExport
*
* @return array of type
*/
public static function getTypeConfig()
public function getTypeConfig()
{
global $conf, $langs;
return array(
$exporttypes = array(
'param' => array(
self::$EXPORT_TYPE_CONFIGURABLE => array(
'label' => $langs->trans('Modelcsv_configurable'),
@ -265,6 +278,11 @@ class AccountancyExport
'txt' => $langs->trans("txt")
),
);
global $hookmanager;
$parameters = array();
$reshook = $hookmanager->executeHooks('getTypeConfig', $parameters, $exporttypes);
return $exporttypes;
}
@ -350,7 +368,13 @@ class AccountancyExport
$this->exportiSuiteExpert($TData);
break;
default:
$this->errors[] = $langs->trans('accountancy_error_modelnotfound');
global $hookmanager;
$parameters = array('format' => $formatexportset);
// file contents will be created in the hooked function via print
$reshook = $hookmanager->executeHooks('export', $parameters, $TData);
if ($reshook != 1) {
$this->errors[] = $langs->trans('accountancy_error_modelnotfound');
}
break;
}
}
@ -980,6 +1004,8 @@ class AccountancyExport
print dol_string_unaccent($date_creation) . $separator;
// FEC:EcritureLib
// Clean label operation to prevent problem on export with tab separator & other character
$line->label_operation = str_replace(array("\t", "\n", "\r"), " ", $line->label_operation);
print dol_string_unaccent($line->label_operation) . $separator;
// FEC:Debit
@ -1007,6 +1033,8 @@ class AccountancyExport
print $date_limit_payment . $separator;
// FEC_suppl:NumFacture
// Clean ref invoice to prevent problem on export with tab separator & other character
$refInvoice = str_replace(array("\t", "\n", "\r"), " ", $refInvoice);
print dol_trunc(self::toAnsi($refInvoice), 17, 'right', 'UTF-8', 1);
print $end_line;
@ -1107,6 +1135,8 @@ class AccountancyExport
print $date_document . $separator;
// FEC:EcritureLib
// Clean label operation to prevent problem on export with tab separator & other character
$line->label_operation = str_replace(array("\t", "\n", "\r"), " ", $line->label_operation);
print dol_string_unaccent($line->label_operation) . $separator;
// FEC:Debit
@ -1134,6 +1164,8 @@ class AccountancyExport
print $date_limit_payment . $separator;
// FEC_suppl:NumFacture
// Clean ref invoice to prevent problem on export with tab separator & other character
$refInvoice = str_replace(array("\t", "\n", "\r"), " ", $refInvoice);
print dol_trunc(self::toAnsi($refInvoice), 17, 'right', 'UTF-8', 1);
@ -1315,7 +1347,7 @@ class AccountancyExport
}
print $nature_piece.$separator;
// RACI
// if (! empty($line->subledger_account)) {
// if (!empty($line->subledger_account)) {
// if ($line->doc_type == 'supplier_invoice') {
// $racine_subledger_account = '40';
// } elseif ($line->doc_type == 'customer_invoice') {
@ -1578,7 +1610,7 @@ class AccountancyExport
}
print $nature_piece.$separator;
// RACI
// if (! empty($line->subledger_account)) {
// if (!empty($line->subledger_account)) {
// if ($line->doc_type == 'supplier_invoice') {
// $racine_subledger_account = '40';
// } elseif ($line->doc_type == 'customer_invoice') {
@ -1712,6 +1744,8 @@ class AccountancyExport
print self::trunc($line->label_compte, 60).$separator; //Account label
print self::trunc($line->doc_ref, 20).$separator; //Piece
// Clean label operation to prevent problem on export with tab separator & other character
$line->label_operation = str_replace(array("\t", "\n", "\r"), " ", $line->label_operation);
print self::trunc($line->label_operation, 60).$separator; //Operation label
print price(abs($line->debit - $line->credit)).$separator; //Amount
print $line->sens.$separator; //Direction

View File

@ -347,8 +347,8 @@ class AccountingAccount extends CommonObject
/**
* Update record
*
* @param User $user Use making update
* @return int <0 if KO, >0 if OK
* @param User $user User making update
* @return int <0 if KO (-2 = duplicate), >0 if OK
*/
public function update($user)
{
@ -378,6 +378,12 @@ class AccountingAccount extends CommonObject
$this->db->commit();
return 1;
} else {
if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
$this->error = $this->db->lasterror();
$this->db->rollback();
return -2;
}
$this->error = $this->db->lasterror();
$this->db->rollback();
return -1;
@ -586,26 +592,19 @@ class AccountingAccount extends CommonObject
$sql .= ' WHERE a.rowid = ' . ((int) $id);
dol_syslog(get_class($this) . '::info sql=' . $sql);
$result = $this->db->query($sql);
$resql = $this->db->query($sql);
if ($result) {
if ($this->db->num_rows($result)) {
$obj = $this->db->fetch_object($result);
if ($resql) {
if ($this->db->num_rows($resql)) {
$obj = $this->db->fetch_object($resql);
$this->id = $obj->rowid;
if ($obj->fk_user_author) {
$cuser = new User($this->db);
$cuser->fetch($obj->fk_user_author);
$this->user_creation = $cuser;
}
if ($obj->fk_user_modif) {
$muser = new User($this->db);
$muser->fetch($obj->fk_user_modif);
$this->user_modification = $muser;
}
$this->user_creation_id = $obj->fk_user_author;
$this->user_modification_id = $obj->fk_user_modif;
$this->date_creation = $this->db->jdate($obj->datec);
$this->date_modification = $this->db->jdate($obj->tms);
}
$this->db->free($result);
$this->db->free($resql);
} else {
dol_print_error($this->db);
}
@ -733,7 +732,7 @@ class AccountingAccount extends CommonObject
* @param FactureLigne|SupplierInvoiceLine $factureDet Facture Det
* @param array $accountingAccount Array of Account account
* @param string $type Customer / Supplier
* @return array Accounting accounts suggested
* @return array|int Accounting accounts suggested or < 0 if technical error.
*/
public function getAccountingCodeToBind(Societe $buyer, Societe $seller, Product $product, $facture, $factureDet, $accountingAccount = array(), $type = '')
{
@ -741,13 +740,14 @@ class AccountingAccount extends CommonObject
global $hookmanager;
// Instantiate hooks for external modules
$hookmanager->initHooks(array('accoutancyBindingCalculation'));
$hookmanager->initHooks(array('accountancyBindingCalculation'));
// Execute hook accoutancyBindingCalculation
// Execute hook accountancyBindingCalculation
$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
$reshook = $hookmanager->executeHooks('accountancyBindingCalculation', $parameters); // Note that $action and $object may have been modified by some hooks
if (empty($reshook)) {
$const_name = '';
if ($type == 'customer') {
$const_name = "SOLD";
} elseif ($type == 'supplier') {
@ -863,14 +863,18 @@ class AccountingAccount extends CommonObject
if (!empty($buyer->code_compta_product)) {
$code_t = $buyer->code_compta_product;
$suggestedid = $accountingAccount['thirdparty'];
$suggestedaccountingaccountfor = 'thridparty';
$suggestedaccountingaccountfor = 'thirdparty';
}
}
// 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 ($type=='customer') {
$result = $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1);
} elseif ($type=='supplier') {
$result = $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT, 1);
}
if ($result < 0) {
return -1;
}

View File

@ -281,7 +281,7 @@ class AccountingJournal extends CommonObject
}
$label_link = $this->code;
if ($withlabel) {
if ($withlabel && !empty($this->label)) {
$label_link .= ' - '.($nourl ? '<span class="opacitymedium">' : '').$langs->transnoentities($this->label).($nourl ? '</span>' : '');
}
@ -429,7 +429,7 @@ class AccountingJournal extends CommonObject
{
global $conf, $langs;
if (empty($conf->asset->enabled)) {
if (!isModEnabled('asset')) {
return array();
}
@ -867,7 +867,7 @@ class AccountingJournal extends CommonObject
}
}
//
// if (!$error_for_line && !empty($conf->asset->enabled) && $this->nature == 1 && $bookkeeping->fk_doc > 0) {
// if (!$error_for_line && isModEnabled('asset') && $this->nature == 1 && $bookkeeping->fk_doc > 0) {
// // Set last cumulative depreciation
// require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php';
// $asset = new Asset($this->db);

View File

@ -1,6 +1,6 @@
<?php
/* Copyright (C) 2014-2017 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2015-2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2015-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2015-2020 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2018-2020 Frédéric France <frederic.france@netlogic.fr>
*
@ -606,9 +606,13 @@ class BookKeeping extends CommonObject
if (empty($this->credit)) {
$this->credit = 0;
}
if (empty($this->montant)) {
$this->montant = 0;
}
$this->debit = price2num($this->debit, 'MT');
$this->credit = price2num($this->credit, 'MT');
$this->montant = price2num($this->montant, 'MT');
$now = dol_now();
@ -852,7 +856,8 @@ class BookKeeping extends CommonObject
$sql .= " t.piece_num,";
$sql .= " t.date_creation,";
$sql .= " t.date_export,";
$sql .= " t.date_validated as date_validation";
$sql .= " t.date_validated as date_validation,";
$sql .= " t.import_key";
// Manage filter
$sqlwhere = array();
if (count($filter) > 0) {
@ -947,6 +952,7 @@ class BookKeeping extends CommonObject
$line->date_creation = $this->db->jdate($obj->date_creation);
$line->date_export = $this->db->jdate($obj->date_export);
$line->date_validation = $this->db->jdate($obj->date_validation);
$line->import_key = $obj->import_key;
$this->lines[] = $line;
@ -1117,14 +1123,13 @@ class BookKeeping extends CommonObject
/**
* Load object in memory from the database
*
* @param string $sortorder Sort Order
* @param string $sortfield Sort field
* @param int $limit offset limit
* @param int $offset offset limit
* @param array $filter filter array
* @param string $filtermode filter mode (AND or OR)
*
* @return int <0 if KO, >0 if OK
* @param string $sortorder Sort Order
* @param string $sortfield Sort field
* @param int $limit offset limit
* @param int $offset offset limit
* @param array $filter filter array
* @param string $filtermode filter mode (AND or OR)
* @return int <0 if KO, >0 if OK
*/
public function fetchAllBalance($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND')
{
@ -1145,7 +1150,7 @@ class BookKeeping extends CommonObject
foreach ($filter as $key => $value) {
if ($key == 't.doc_date') {
$sqlwhere[] = $key." = '".$this->db->idate($value)."'";
} elseif ($key == 't.doc_date>=' || $key == 't.doc_date<=') {
} elseif ($key == 't.doc_date>=' || $key == 't.doc_date<=' || $key == 't.doc_date>' || $key == 't.doc_date<') {
$sqlwhere[] = $key."'".$this->db->idate($value)."'";
} elseif ($key == 't.numero_compte>=' || $key == 't.numero_compte<=' || $key == 't.subledger_account>=' || $key == 't.subledger_account<=') {
$sqlwhere[] = $key."'".$this->db->escape($value)."'";
@ -1659,11 +1664,12 @@ class BookKeeping extends CommonObject
$this->doc_date = $this->db->jdate($obj->doc_date);
$this->doc_ref = $obj->doc_ref;
$this->doc_type = $obj->doc_type;
$this->date_creation = $obj->date_creation;
$this->date_modification = $obj->date_modification;
$this->date_export = $obj->date_export;
$this->date_validation = $obj->date_validated;
$this->date_validation = $obj->date_validation;
$this->date_creation = $this->db->jdate($obj->date_creation);
$this->date_modification = $this->db->jdate($obj->date_modification);
if ($mode != "_tmp") {
$this->date_export = $this->db->jdate($obj->date_export);
}
$this->date_validation = $this->db->jdate($obj->date_validation);
} else {
$this->error = "Error ".$this->db->lasterror();
dol_syslog(__METHOD__.$this->error, LOG_ERR);
@ -1759,7 +1765,9 @@ class BookKeeping extends CommonObject
$line->piece_num = $obj->piece_num;
$line->date_creation = $obj->date_creation;
$line->date_modification = $obj->date_modification;
$line->date_export = $obj->date_export;
if ($mode != "_tmp") {
$line->date_export = $obj->date_export;
}
$line->date_validation = $obj->date_validation;
$this->linesmvt[] = $line;
@ -1841,8 +1849,8 @@ class BookKeeping extends CommonObject
/**
* Transform transaction
*
* @param number $direction If 0 tmp => real, if 1 real => tmp
* @param string $piece_num Piece num
* @param number $direction If 0: tmp => real, if 1: real => tmp
* @param string $piece_num Piece num = Transaction ref
* @return int int <0 if KO, >0 if OK
*/
public function transformTransaction($direction = 0, $piece_num = '')
@ -1860,57 +1868,82 @@ class BookKeeping extends CommonObject
if ($next_piecenum < 0) {
$error++;
}
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.' (doc_date, doc_type,';
$sql .= ' doc_ref, fk_doc, fk_docdet, entity, thirdparty_code, subledger_account, subledger_label,';
$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
$sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num, date_creation)';
$sql .= ' SELECT doc_date, doc_type,';
$sql .= ' doc_ref, fk_doc, fk_docdet, entity, thirdparty_code, subledger_account, subledger_label,';
$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
$sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, '.((int) $next_piecenum).", '".$this->db->idate($now)."'";
$sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = 'Error '.$this->db->lasterror();
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
if (!$error) {
// Delete if there is an empty line
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity)." AND numero_compte IS NULL AND debit = 0 AND credit = 0";
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = 'Error '.$this->db->lasterror();
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
}
}
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = 'Error '.$this->db->lasterror();
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
if (!$error) {
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.' (doc_date, doc_type,';
$sql .= ' doc_ref, fk_doc, fk_docdet, entity, thirdparty_code, subledger_account, subledger_label,';
$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
$sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num, date_creation)';
$sql .= ' SELECT doc_date, doc_type,';
$sql .= ' doc_ref, fk_doc, fk_docdet, entity, thirdparty_code, subledger_account, subledger_label,';
$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
$sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, '.((int) $next_piecenum).", '".$this->db->idate($now)."'";
$sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND numero_compte IS NOT NULL AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = 'Error '.$this->db->lasterror();
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
}
}
if (!$error) {
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = 'Error '.$this->db->lasterror();
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
}
}
} elseif ($direction == 1) {
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = 'Error '.$this->db->lasterror();
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
if (!$error) {
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = 'Error '.$this->db->lasterror();
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
}
}
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'_tmp (doc_date, doc_type,';
$sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,';
$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
$sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num)';
$sql .= ' SELECT doc_date, doc_type,';
$sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,';
$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
$sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num';
$sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = 'Error '.$this->db->lasterror();
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
if (!$error) {
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'_tmp (doc_date, doc_type,';
$sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,';
$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
$sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num)';
$sql .= ' SELECT doc_date, doc_type,';
$sql .= ' doc_ref, fk_doc, fk_docdet, thirdparty_code, subledger_account, subledger_label,';
$sql .= ' numero_compte, label_compte, label_operation, debit, credit,';
$sql .= ' montant, sens, fk_user_author, import_key, code_journal, journal_label, piece_num';
$sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = 'Error '.$this->db->lasterror();
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
}
}
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = 'Error '.$this->db->lasterror();
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
if (!$error) {
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element.'_tmp WHERE piece_num = '.((int) $piece_num).' AND entity = ' .((int) $conf->entity);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = 'Error '.$this->db->lasterror();
dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR);
}
}
}
if (!$error) {

View File

@ -33,6 +33,12 @@ include_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php";
*/
class Lettering extends BookKeeping
{
/**
* @var BookKeeping[] Bookkeeping cached
*/
public static $bookkeeping_cached = array();
/**
* letteringThirdparty
*
@ -119,6 +125,7 @@ class Lettering extends BookKeeping
$ids[$obj2->rowid] = $obj2->rowid;
$ids_fact[] = $obj2->fact_id;
}
$this->db->free($resql2);
} else {
$this->errors[] = $this->db->lasterror;
return -1;
@ -146,6 +153,7 @@ class Lettering extends BookKeeping
while ($obj2 = $this->db->fetch_object($resql2)) {
$ids[$obj2->rowid] = $obj2->rowid;
}
$this->db->free($resql2);
} else {
$this->errors[] = $this->db->lasterror;
return -1;
@ -205,6 +213,7 @@ class Lettering extends BookKeeping
while ($obj2 = $this->db->fetch_object($resql2)) {
$ids[$obj2->rowid] = $obj2->rowid;
}
$this->db->free($resql2);
} else {
$this->errors[] = $this->db->lasterror;
return -1;
@ -216,6 +225,7 @@ class Lettering extends BookKeeping
$result = $this->updateLettering($ids);
}
}
$this->db->free($resql);
}
if ($error) {
foreach ($this->errors as $errmsg) {
@ -230,39 +240,55 @@ class Lettering extends BookKeeping
/**
*
* @param array $ids ids array
* @param boolean $notrigger no trigger
* @return number
* @param array $ids ids array
* @param boolean $notrigger no trigger
* @return int
*/
public function updateLettering($ids = array(), $notrigger = false)
{
$error = 0;
$lettre = 'AAA';
$sql = "SELECT DISTINCT lettering_code FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE ";
$sql .= " lettering_code != '' ORDER BY lettering_code DESC limit 1";
$sql = "SELECT DISTINCT ab2.lettering_code";
$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping As ab";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url AS bu ON bu.fk_bank = ab.fk_doc";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url AS bu2 ON bu2.url_id = bu.url_id";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab2 ON ab2.fk_doc = bu2.fk_bank";
$sql .= " WHERE ab.rowid IN (" . $this->db->sanitize(implode(',', $ids)) . ")";
$sql .= " AND ab.doc_type = 'bank'";
$sql .= " AND ab2.doc_type = 'bank'";
$sql .= " AND bu.type = 'company'";
$sql .= " AND bu2.type = 'company'";
$sql .= " AND ab.subledger_account != ''";
$sql .= " AND ab2.subledger_account != ''";
$sql .= " AND ab.lettering_code IS NULL";
$sql .= " AND ab2.lettering_code != ''";
$sql .= " ORDER BY ab2.lettering_code DESC";
$sql .= " LIMIT 1 ";
$result = $this->db->query($sql);
if ($result) {
$obj = $this->db->fetch_object($result);
$resqla = $this->db->query($sql);
if ($resqla) {
$obj = $this->db->fetch_object($resqla);
$lettre = (empty($obj->lettering_code) ? 'AAA' : $obj->lettering_code);
if (!empty($obj->lettering_code)) {
$lettre++;
}
$this->db->free($resqla);
} else {
$this->errors[] = 'Error'.$this->db->lasterror();
$error++;
}
$sql = "SELECT SUM(ABS(debit)) as deb, SUM(ABS(credit)) as cred FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE ";
$sql .= " rowid IN (".$this->db->sanitize(implode(',', $ids)).") AND date_validated IS NULL";
$result = $this->db->query($sql);
if ($result) {
$obj = $this->db->fetch_object($result);
$sql .= " rowid IN (".$this->db->sanitize(implode(',', $ids)).") AND lettering_code IS NULL AND subledger_account != ''";
$resqlb = $this->db->query($sql);
if ($resqlb) {
$obj = $this->db->fetch_object($resqlb);
if (!(round(abs($obj->deb), 2) === round(abs($obj->cred), 2))) {
$this->errors[] = 'Total not exacts '.round(abs($obj->deb), 2).' vs '.round(abs($obj->cred), 2);
$error++;
}
$this->db->free($resqlb);
} else {
$this->errors[] = 'Erreur sql'.$this->db->lasterror();
$error++;
@ -276,8 +302,7 @@ class Lettering extends BookKeeping
$sql = "UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping SET";
$sql .= " lettering_code='".$this->db->escape($lettre)."'";
$sql .= " , date_lettering = '".$this->db->idate($now)."'"; // todo correct date it's false
$sql .= " WHERE rowid IN (".$this->db->sanitize(implode(',', $ids)).") AND date_validated IS NULL ";
$this->db->begin();
$sql .= " WHERE rowid IN (".$this->db->sanitize(implode(',', $ids)).") AND lettering_code IS NULL AND subledger_account != ''";
dol_syslog(get_class($this)."::update", LOG_DEBUG);
$resql = $this->db->query($sql);
@ -293,11 +318,431 @@ class Lettering extends BookKeeping
dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
$this->error .= ($this->error ? ', '.$errmsg : $errmsg);
}
$this->db->rollback();
return -1 * $error;
} else {
$this->db->commit();
return 1;
}
}
/**
*
* @param array $ids ids array
* @param boolean $notrigger no trigger
* @return int
*/
public function deleteLettering($ids, $notrigger = false)
{
$error = 0;
$sql = "UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping SET";
$sql .= " lettering_code = NULL";
$sql .= " , date_lettering = NULL";
$sql .= " WHERE rowid IN (".$this->db->sanitize(implode(',', $ids)).")";
$sql .= " AND subledger_account != ''";
dol_syslog(get_class($this)."::update", LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$error++;
$this->errors[] = "Error ".$this->db->lasterror();
}
// Commit or rollback
if ($error) {
foreach ($this->errors as $errmsg) {
dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
$this->error .= ($this->error ? ', '.$errmsg : $errmsg);
}
return -1 * $error;
} else {
return 1;
}
}
/**
* Lettering bookkeeping lines all types
*
* @param array $bookkeeping_ids Lettering specific list of bookkeeping id
* @param bool $unlettering Do unlettering
* @return int <0 if error (nb lettered = result -1), 0 if noting to lettering, >0 if OK (nb lettered)
*/
public function bookkeepingLetteringAll($bookkeeping_ids, $unlettering = false)
{
dol_syslog(__METHOD__ . " - ", LOG_DEBUG);
$error = 0;
$errors = array();
$nb_lettering = 0;
$result = $this->bookkeepingLettering($bookkeeping_ids, 'customer_invoice', $unlettering);
if ($result < 0) {
$error++;
$errors = array_merge($errors, $this->errors);
$nb_lettering += abs($result) - 2;
} else {
$nb_lettering += $result;
}
$result = $this->bookkeepingLettering($bookkeeping_ids, 'supplier_invoice', $unlettering);
if ($result < 0) {
$error++;
$errors = array_merge($errors, $this->errors);
$nb_lettering += abs($result) - 2;
} else {
$nb_lettering += $result;
}
if ($error) {
$this->errors = $errors;
return -2 - $nb_lettering;
} else {
return $nb_lettering;
}
}
/**
* Lettering bookkeeping lines
*
* @param array $bookkeeping_ids Lettering specific list of bookkeeping id
* @param string $type Type of bookkeeping type to lettering ('customer_invoice' or 'supplier_invoice')
* @param bool $unlettering Do unlettering
* @return int <0 if error (nb lettered = result -1), 0 if noting to lettering, >0 if OK (nb lettered)
*/
public function bookkeepingLettering($bookkeeping_ids, $type = 'customer_invoice', $unlettering = false)
{
global $langs;
$this->errors = array();
// Clean parameters
$bookkeeping_ids = is_array($bookkeeping_ids) ? $bookkeeping_ids : array();
$type = trim($type);
$error = 0;
$nb_lettering = 0;
$grouped_lines = $this->getLinkedLines($bookkeeping_ids, $type);
foreach ($grouped_lines as $lines) {
$group_error = 0;
$total = 0;
$do_it = !$unlettering;
$lettering_code = null;
$piece_num_lines = array();
$bookkeeping_lines = array();
foreach ($lines as $line_infos) {
$bookkeeping_lines[$line_infos['id']] = $line_infos['id'];
$piece_num_lines[$line_infos['piece_num']] = $line_infos['piece_num'];
$total += ($line_infos['credit'] > 0 ? $line_infos['credit'] : -$line_infos['debit']);
// Check lettering code
if ($unlettering) {
if (isset($lettering_code) && $lettering_code != $line_infos['lettering_code']) {
$this->errors[] = $langs->trans('AccountancyErrorMismatchLetteringCode');
$group_error++;
break;
}
if (!isset($lettering_code)) $lettering_code = (string) $line_infos['lettering_code'];
if (!empty($line_infos['lettering_code'])) $do_it = true;
} elseif (!empty($line_infos['lettering_code'])) $do_it = false;
}
// Check balance amount
if (!$group_error && !$unlettering && price2num($total) != 0) {
$this->errors[] = $langs->trans('AccountancyErrorMismatchBalanceAmount', $total);
$group_error++;
}
// Lettering/Unlettering the group of bookkeeping lines
if (!$group_error && $do_it) {
if ($unlettering) $result = $this->deleteLettering($bookkeeping_lines);
else $result = $this->updateLettering($bookkeeping_lines);
if ($result < 0) {
$group_error++;
} else {
$nb_lettering++;
}
}
if ($group_error) {
$this->errors[] = $langs->trans('AccountancyErrorLetteringBookkeeping', implode(', ', $piece_num_lines));
$error++;
}
}
if ($error) {
return -2 - $nb_lettering;
} else {
return $nb_lettering;
}
}
/**
* Lettering bookkeeping lines
*
* @param array $bookkeeping_ids Lettering specific list of bookkeeping id
* @param string $type Type of bookkeeping type to lettering ('customer_invoice' or 'supplier_invoice')
* @return array|int <0 if error otherwise all linked lines by block
*/
public function getLinkedLines($bookkeeping_ids, $type = 'customer_invoice')
{
global $conf, $langs;
$this->errors = array();
// Clean parameters
$bookkeeping_ids = is_array($bookkeeping_ids) ? $bookkeeping_ids : array();
$type = trim($type);
if ($type == 'customer_invoice') {
$doc_type = 'customer_invoice';
$bank_url_type = 'payment';
$payment_element = 'paiement_facture';
$fk_payment_element = 'fk_paiement';
$fk_element = 'fk_facture';
$account_number = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER;
} elseif ($type == 'supplier_invoice') {
$doc_type = 'supplier_invoice';
$bank_url_type = 'payment_supplier';
$payment_element = 'paiementfourn_facturefourn';
$fk_payment_element = 'fk_paiementfourn';
$fk_element = 'fk_facturefourn';
$account_number = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER;
} else {
$langs->load('errors');
$this->errors[] = $langs->trans('ErrorBadParameters');
return -1;
}
$payment_ids = array();
// Get all payment id from bank lines
$sql = "SELECT DISTINCT bu.url_id AS payment_id";
$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url AS bu ON bu.fk_bank = ab.fk_doc";
$sql .= " WHERE ab.doc_type = 'bank'";
// $sql .= " AND ab.subledger_account != ''";
// $sql .= " AND ab.numero_compte = '" . $this->db->escape($account_number) . "'";
$sql .= " AND bu.type = '" . $this->db->escape($bank_url_type) . "'";
if (!empty($bookkeeping_ids)) $sql .= " AND ab.rowid IN (" . $this->db->sanitize(implode(',', $bookkeeping_ids)) . ")";
dol_syslog(__METHOD__ . " - Get all payment id from bank lines", LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$this->errors[] = "Error " . $this->db->lasterror();
return -1;
}
while ($obj = $this->db->fetch_object($resql)) {
$payment_ids[$obj->payment_id] = $obj->payment_id;
}
$this->db->free($resql);
// Get all payment id from payment lines
$sql = "SELECT DISTINCT pe.$fk_payment_element AS payment_id";
$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "$payment_element AS pe ON pe.$fk_element = ab.fk_doc";
$sql .= " WHERE ab.doc_type = '" . $this->db->escape($doc_type) . "'";
// $sql .= " AND ab.subledger_account != ''";
// $sql .= " AND ab.numero_compte = '" . $this->db->escape($account_number) . "'";
$sql .= " AND pe.$fk_payment_element IS NOT NULL";
if (!empty($bookkeeping_ids)) $sql .= " AND ab.rowid IN (" . $this->db->sanitize(implode(',', $bookkeeping_ids)) . ")";
dol_syslog(__METHOD__ . " - Get all payment id from bank lines", LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$this->errors[] = "Error " . $this->db->lasterror();
return -1;
}
while ($obj = $this->db->fetch_object($resql)) {
$payment_ids[$obj->payment_id] = $obj->payment_id;
}
$this->db->free($resql);
if (empty($payment_ids)) {
return array();
}
// Get all payments linked by group
$payment_by_group = $this->getLinkedPaymentByGroup($payment_ids, $type);
$groups = array();
foreach ($payment_by_group as $payment_list) {
$lines = array();
// Get bank lines
$sql = "SELECT DISTINCT ab.rowid, ab.piece_num, ab.lettering_code, ab.debit, ab.credit";
$sql .= " FROM " . MAIN_DB_PREFIX . "bank_url AS bu";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab ON ab.fk_doc = bu.fk_bank";
$sql .= " WHERE bu.url_id IN (" . $this->db->sanitize(implode(',', $payment_list)) . ")";
$sql .= " AND bu.type = '" . $this->db->escape($bank_url_type) . "'";
$sql .= " AND ab.doc_type = 'bank'";
$sql .= " AND ab.subledger_account != ''";
$sql .= " AND ab.numero_compte = '" . $this->db->escape($account_number) . "'";
dol_syslog(__METHOD__ . " - Get bank lines", LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$this->errors[] = "Error " . $this->db->lasterror();
return -1;
}
while ($obj = $this->db->fetch_object($resql)) {
$lines[$obj->rowid] = array('id' => $obj->rowid, 'piece_num' => $obj->piece_num, 'lettering_code' => $obj->lettering_code, 'debit' => $obj->debit, 'credit' => $obj->credit);
}
$this->db->free($resql);
// Get payment lines
$sql = "SELECT DISTINCT ab.rowid, ab.piece_num, ab.lettering_code, ab.debit, ab.credit";
$sql .= " FROM " . MAIN_DB_PREFIX . "$payment_element AS pe";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab ON ab.fk_doc = pe.$fk_element";
$sql .= " WHERE pe.$fk_payment_element IN (" . $this->db->sanitize(implode(',', $payment_list)) . ")";
$sql .= " AND ab.doc_type = '" . $this->db->escape($doc_type) . "'";
$sql .= " AND ab.subledger_account != ''";
$sql .= " AND ab.numero_compte = '" . $this->db->escape($account_number) . "'";
dol_syslog(__METHOD__ . " - Get payment lines", LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$this->errors[] = "Error " . $this->db->lasterror();
return -1;
}
while ($obj = $this->db->fetch_object($resql)) {
$lines[$obj->rowid] = array('id' => $obj->rowid, 'piece_num' => $obj->piece_num, 'lettering_code' => $obj->lettering_code, 'debit' => $obj->debit, 'credit' => $obj->credit);
}
$this->db->free($resql);
if (!empty($lines)) {
$groups[] = $lines;
}
}
return $groups;
}
/**
* Linked payment by group
*
* @param array $payment_ids list of payment id
* @param string $type Type of bookkeeping type to lettering ('customer_invoice' or 'supplier_invoice')
* @return array|int <0 if error otherwise all linked lines by block
*/
public function getLinkedPaymentByGroup($payment_ids, $type)
{
global $langs;
// Clean parameters
$payment_ids = is_array($payment_ids) ? $payment_ids : array();
$type = trim($type);
if (empty($payment_ids)) {
return array();
}
if ($type == 'customer_invoice') {
$payment_element = 'paiement_facture';
$fk_payment_element = 'fk_paiement';
$fk_element = 'fk_facture';
} elseif ($type == 'supplier_invoice') {
$payment_element = 'paiementfourn_facturefourn';
$fk_payment_element = 'fk_paiementfourn';
$fk_element = 'fk_facturefourn';
} else {
$langs->load('errors');
$this->errors[] = $langs->trans('ErrorBadParameters');
return -1;
}
// Get payment lines
$sql = "SELECT DISTINCT pe2.$fk_payment_element, pe2.$fk_element";
$sql .= " FROM " . MAIN_DB_PREFIX . "$payment_element AS pe";
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "$payment_element AS pe2 ON pe2.$fk_element = pe.$fk_element";
$sql .= " WHERE pe.$fk_payment_element IN (" . $this->db->sanitize(implode(',', $payment_ids)) . ")";
dol_syslog(__METHOD__ . " - Get payment lines", LOG_DEBUG);
$resql = $this->db->query($sql);
if (!$resql) {
$this->errors[] = "Error " . $this->db->lasterror();
return -1;
}
$current_payment_ids = array();
$payment_by_element = array();
$element_by_payment = array();
while ($obj = $this->db->fetch_object($resql)) {
$current_payment_ids[$obj->$fk_payment_element] = $obj->$fk_payment_element;
$element_by_payment[$obj->$fk_payment_element][$obj->$fk_element] = $obj->$fk_element;
$payment_by_element[$obj->$fk_element][$obj->$fk_payment_element] = $obj->$fk_payment_element;
}
$this->db->free($resql);
if (count(array_diff($payment_ids, $current_payment_ids))) {
return $this->getLinkedPaymentByGroup($current_payment_ids, $type);
}
return $this->getGroupElements($payment_by_element, $element_by_payment);
}
/**
* Get payment ids grouped by payment id and element id in common
*
* @param array $payment_by_element List of payment ids by element id
* @param array $element_by_payment List of element ids by payment id
* @param int $element_id Element Id (used for recursive function)
* @param array $current_group Current group (used for recursive function)
* @return array List of payment ids grouped by payment id and element id in common
*/
public function getGroupElements(&$payment_by_element, &$element_by_payment, $element_id = 0, &$current_group = array())
{
$grouped_payments = array();
if ($element_id > 0 && !isset($payment_by_element[$element_id])) {
// Return if specific element id not found
return $grouped_payments;
}
$save_payment_by_element = null;
$save_element_by_payment = null;
if ($element_id == 0) {
// Save list when is the begin of recursive function
$save_payment_by_element = $payment_by_element;
$save_element_by_payment = $element_by_payment;
}
do {
// Get current element id, get this payment id list and delete the entry
$current_element_id = $element_id > 0 ? $element_id : array_keys($payment_by_element)[0];
$payment_ids = $payment_by_element[$current_element_id];
unset($payment_by_element[$current_element_id]);
foreach ($payment_ids as $payment_id) {
// Continue if payment id in not found
if (!isset($element_by_payment[$payment_id])) continue;
// Set the payment in the current group
$current_group[$payment_id] = $payment_id;
// Get current element ids, get this payment id list and delete the entry
$element_ids = $element_by_payment[$payment_id];
unset($element_by_payment[$payment_id]);
// Set payment id on the current group for each element id of the payment
foreach ($element_ids as $id) {
$this->getGroupElements($payment_by_element, $element_by_payment, $id, $current_group);
}
}
if ($element_id == 0) {
// Save current group and reset the current group when is the begin of recursive function
$grouped_payments[] = $current_group;
$current_group = array();
}
} while (!empty($payment_by_element) && $element_id == 0);
if ($element_id == 0) {
// Restore list when is the begin of recursive function
$payment_by_element = $save_payment_by_element;
$element_by_payment = $save_element_by_payment;
}
return $grouped_payments;
}
}

View File

@ -21,6 +21,7 @@
* \brief Home closure page
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
@ -57,7 +58,7 @@ $search_date_end = dol_get_last_day($year_end, $month_end);
$year_current = $year_start;
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -75,7 +76,7 @@ if (empty($user->rights->accounting->fiscalyear->write)) {
$now = dol_now();
if ($action == 'validate_movements_confirm' && !empty($user->rights->accounting->fiscalyear->write)) {
if ($action == 'validate_movements_confirm' && $user->hasRight('accounting', 'fiscalyear', 'write')) {
$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'));
@ -112,6 +113,7 @@ if ($action == 'validate_movements_confirm' && !empty($user->rights->accounting-
}
}
/*
* View
*/
@ -178,20 +180,40 @@ for ($i = 1; $i <= 12; $i++) {
}
print '<td width="60" class="right"><b>'.$langs->trans("Total").'</b></td></tr>';
$sql = "SELECT COUNT(b.rowid) as detail,";
for ($i = 1; $i <= 12; $i++) {
$j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) - 1;
if ($j > 12) {
$j -= 12;
if (getDolGlobalString("ACCOUNTANCY_DISABLE_CLOSURE_LINE_BY_LINE")) {
// TODO Analyse is done by finding record not into a closed period
$sql = "SELECT COUNT(b.rowid) as detail,";
for ($i = 1; $i <= 12; $i++) {
$j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) - 1;
if ($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 .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as b";
$sql .= " WHERE b.doc_date >= '".$db->idate($search_date_start)."'";
$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
// Loop on each closed period
$sql .= " AND b.doc_date BETWEEN 0 AND 0";
} else {
// Analyse closed record using the unitary flag/date on each record
$sql = "SELECT COUNT(b.rowid) as detail,";
for ($i = 1; $i <= 12; $i++) {
$j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) - 1;
if ($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 .= " COUNT(b.rowid) as total";
$sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as b";
$sql .= " WHERE b.doc_date >= '".$db->idate($search_date_start)."'";
$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 date_validated IS NULL";
}
$sql .= " COUNT(b.rowid) as total";
$sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as b";
$sql .= " WHERE b.doc_date >= '".$db->idate($search_date_start)."'";
$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 date_validated IS NULL";
dol_syslog('htdocs/accountancy/closure/index.php', LOG_DEBUG);
$resql = $db->query($sql);

View File

@ -38,7 +38,7 @@ $codeventil = GETPOST('codeventil', 'int');
$id = GETPOST('id', 'int');
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {

View File

@ -1,9 +1,9 @@
<?php
/* Copyright (C) 2013 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2014 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
/* Copyright (C) 2013 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2014 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,6 +26,7 @@
* \brief Home customer journalization page
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
@ -40,7 +41,7 @@ $validatemonth = GETPOST('validatemonth', 'int');
$validateyear = GETPOST('validateyear', 'int');
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -77,7 +78,7 @@ $action = GETPOST('action', 'aZ09');
$chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version');
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -174,7 +175,9 @@ 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 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 .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0 AND l.product_type <= 2 AND f.entity = ".((int) $conf->entity);
$sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0";
$sql .= " AND l.product_type <= 2";
$sql .= " AND f.entity IN (".getEntity('invoice', 0).")"; // We don't share object for accountancy
if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) {
$sql .= " AND f.datef >= '".$db->idate($conf->global->ACCOUNTING_DATE_START_BINDING)."'";
}
@ -620,7 +623,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) { // This part of code looks strange
print '</div>';
if (!empty($conf->margin->enabled)) {
if (isModEnabled('margin')) {
print "<br>\n";
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';

View File

@ -85,7 +85,7 @@ if (!$sortorder) {
}
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {

View File

@ -5,6 +5,7 @@
* Copyright (C) 2013-2021 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -46,6 +47,7 @@ $show_files = GETPOST('show_files', 'int');
$confirm = GETPOST('confirm', 'alpha');
$toselect = GETPOST('toselect', 'array');
$optioncss = GETPOST('optioncss', 'alpha');
$default_account = GETPOST('default_account', 'int');
// Select Box
$mesCasesCochees = GETPOST('toselect', 'array');
@ -102,7 +104,7 @@ $accountingAccount = new AccountingAccount($db);
$chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version');
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -156,8 +158,8 @@ if (empty($reshook)) {
// Mass actions
$objectclass = 'AccountingAccount';
$permissiontoread = $user->rights->accounting->read;
$permissiontodelete = $user->rights->accounting->delete;
$permissiontoread = $user->hasRight('accounting', 'read');
$permissiontodelete = $user->hasRight('accounting', 'delete');
$uploaddir = $conf->accounting->dir_output;
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
}
@ -434,12 +436,15 @@ if ($result) {
$arrayofmassactions = array(
'ventil'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Ventilate")
,'set_default_account'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("ConfirmPreselectAccount")
//'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
//'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
);
//if ($user->rights->mymodule->supprimer) $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
//if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array();
$massactionbutton = $form->selectMassAction('ventil', $arrayofmassactions, 1);
if ($massaction !== 'set_default_account') {
$massactionbutton = $form->selectMassAction('ventil', $arrayofmassactions, 1);
}
print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">'."\n";
print '<input type="hidden" name="action" value="ventil">';
@ -454,9 +459,17 @@ if ($result) {
print_barre_liste($langs->trans("InvoiceLines"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
if ($massaction == 'set_default_account') {
$formquestion[]=array('type' => 'other',
'name' => 'set_default_account',
'label' => $langs->trans("AccountancyCode"),
'value' => $formaccounting->select_account('', 'default_account', 1, array(), 0, 0, 'maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone'));
print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmPreselectAccount"), $langs->trans("ConfirmPreselectAccountQuestion", count($toselect)), "confirm_set_default_account", $formquestion, 1, 0, 200, 500, 1);
}
print '<span class="opacitymedium">'.$langs->trans("DescVentilTodoCustomer").'</span></br><br>';
if ($msg) {
if (!empty($msg)) {
print $msg.'<br>';
}
@ -712,7 +725,7 @@ if ($result) {
// Suggested accounting account
print '<td>';
print $formaccounting->select_account($suggestedid, 'codeventil'.$facture_static_det->id, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone');
print $formaccounting->select_account(($default_account > 0 && $confirm === 'yes' && in_array($objp->rowid."_".$i, $toselect)) ? $default_account : $suggestedid, 'codeventil'.$facture_static_det->id, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone');
print '</td>';
// Column with checkbox
@ -721,6 +734,14 @@ if ($result) {
if (!empty($suggestedid) && $suggestedaccountingaccountfor != '' && $suggestedaccountingaccountfor != 'eecwithoutvatnumber') {
$ischecked = 1;
}
if (!empty($toselect)) {
$ischecked = 0;
if (in_array($objp->rowid."_".$i, $toselect)) {
$ischecked=1;
}
}
print '<input type="checkbox" class="flat checkforselect checkforselect'.$facture_static_det->id.'" name="toselect[]" value="'.$facture_static_det->id."_".$i.'"'.($ischecked ? " checked" : "").'/>';
print '</td>';

View File

@ -42,7 +42,7 @@ $codeventil = GETPOST('codeventil', 'int');
$id = GETPOST('id', 'int');
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {

View File

@ -24,6 +24,7 @@
* \brief Home expense report ventilation
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
@ -58,7 +59,7 @@ $year_current = $year_start;
$action = GETPOST('action', 'aZ09');
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {

View File

@ -79,7 +79,7 @@ if (!$sortorder) {
}
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {

View File

@ -97,7 +97,7 @@ $accounting = new AccountingAccount($db);
$chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version');
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -150,8 +150,8 @@ if (empty($reshook)) {
// Mass actions
$objectclass = 'ExpenseReport';
$objectlabel = 'ExpenseReport';
$permissiontoread = $user->rights->expensereport->read;
$permissiontodelete = $user->rights->expensereport->delete;
$permissiontoread = $user->hasRight('accounting', 'read');
$permissiontodelete = $user->hasRight('accounting', 'delete');
$uploaddir = $conf->expensereport->dir_output;
include DOL_DOCUMENT_ROOT . '/core/actions_massactions.inc.php';
}
@ -370,7 +370,7 @@ if ($result) {
print '<span class="opacitymedium">'.$langs->trans("DescVentilTodoExpenseReport").'</span></br><br>';
if ($msg) {
if (!empty($msg)) {
print $msg.'<br>';
}

View File

@ -23,6 +23,8 @@
* \brief Home accounting module
*/
// Load Dolibarr environment
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
@ -39,17 +41,17 @@ if ($user->socid > 0) {
accessforbidden();
}
/*
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if (empty($user->rights->accounting->mouvements->lire)) {
if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
accessforbidden();
}
*/
if (empty($conf->comptabilite->enabled) && empty($conf->accounting->enabled) && empty($conf->asset->enabled) && empty($conf->intracommreport->enabled)) {
if (!isModEnabled('comptabilite') && !isModEnabled('accounting') && !isModEnabled('asset') && !isModEnabled('intracommreport')) {
accessforbidden();
}
if (empty($user->rights->compta->resultat->lire) && empty($user->rights->accounting->comptarapport->lire) && empty($user->rights->accounting->mouvements->lire) && empty($user->rights->asset->read) && empty($user->rights->intracommreport->read)) {
if (!$user->hasRight('compta', 'resultat', 'lire') && !$user->hasRight('accounting', 'comptarapport', 'lire') && !$user->hasRight('accounting', 'mouvements', 'lire') && !$user->hasRight('asset', 'read') && !$user->hasRight('intracommreport', 'read')) {
accessforbidden();
}
@ -86,7 +88,7 @@ if (!empty($conf->global->INVOICE_USE_SITUATION) && $conf->global->INVOICE_USE_S
print '<span class="opacitymedium">'.$langs->trans("SorryThisModuleIsNotCompatibleWithTheExperimentalFeatureOfSituationInvoices")."</span>\n";
print "<br>";
} elseif ($conf->accounting->enabled) {
} elseif (isModEnabled('accounting')) {
$step = 0;
$resultboxes = FormOther::getBoxesArea($user, "27"); // Load $resultboxes (selectboxlist + boxactivated + boxlista + boxlistb)
@ -117,7 +119,7 @@ if (!empty($conf->global->INVOICE_USE_SITUATION) && $conf->global->INVOICE_USE_S
print '<div class="'.($helpisexpanded ? '' : 'hideobject').'" id="idfaq">'; // hideobject is to start hidden
print "<br>\n";
print '<span class="opacitymedium">'.$langs->trans("AccountancyAreaDescIntro")."</span><br>\n";
if (!empty($user->rights->accounting->chartofaccount)) {
if ($user->hasRight('accounting', 'chartofaccount')) {
print "<br>\n"; print "<br>\n";
print load_fiche_titre('<span class="fa fa-calendar-check-o"></span> '.$langs->trans("AccountancyAreaDescActionOnce"), '', '')."\n";
@ -165,7 +167,7 @@ if (!empty($conf->global->INVOICE_USE_SITUATION) && $conf->global->INVOICE_USE_S
print $s;
print "<br>\n";
if (!empty($conf->tax->enabled)) {
if (isModEnabled('tax')) {
$textlink = '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=7&from=accountancy"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuTaxAccounts").'</strong></a>';
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescContrib", $step, '{s}');
@ -173,7 +175,7 @@ if (!empty($conf->global->INVOICE_USE_SITUATION) && $conf->global->INVOICE_USE_S
print $s;
print "<br>\n";
}
if (!empty($conf->expensereport->enabled)) { // TODO Move this in the default account page because this is only one accounting account per purpose, not several.
if (isModEnabled('expensereport')) { // TODO Move this in the default account page because this is only one accounting account per purpose, not several.
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescExpenseReport", $step, '{s}');
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/admin/dict.php?id=17&from=accountancy"><strong>'.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("MenuExpenseReportAccounts").'</strong></a>', $s);
@ -212,7 +214,7 @@ if (!empty($conf->global->INVOICE_USE_SITUATION) && $conf->global->INVOICE_USE_S
print $s;
print "<br>\n";
if (!empty($conf->expensereport->enabled) || !empty($conf->deplacement->enabled)) {
if (isModEnabled('expensereport') || isModEnabled('deplacement')) {
$step++;
$s = img_picto('', 'puce').' '.$langs->trans("AccountancyAreaDescBind", chr(64 + $step), $langs->transnoentitiesnoconv("ExpenseReports"), '{s}')."\n";
$s = str_replace('{s}', '<a href="'.DOL_URL_ROOT.'/accountancy/expensereport/index.php"><strong>'.$langs->transnoentitiesnoconv("TransferInAccounting").' - '.$langs->transnoentitiesnoconv("ExpenseReportsVentilation").'</strong></a>', $s);

View File

@ -83,7 +83,7 @@ $now = dol_now();
$action = GETPOST('action', 'aZ09');
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -305,8 +305,16 @@ if ($result) {
// get_url may return -1 which is not traversable
if (is_array($links) && count($links) > 0) {
$is_sc = false;
foreach ($links as $v) {
if ($v['type'] == 'sc') {
$is_sc = true;
break;
}
}
// Now loop on each link of record in bank (code similar to bankentries_list.php)
foreach ($links as $key => $val) {
if ($links[$key]['type'] == 'user' && !$is_sc) continue;
if (in_array($links[$key]['type'], array('sc', 'payment_sc', 'payment', 'payment_supplier', 'payment_vat', 'payment_expensereport', 'banktransfert', 'payment_donation', 'member', 'payment_loan', 'payment_salary', 'payment_various'))) {
// So we excluded 'company' and 'user' here. We want only payment lines
@ -558,11 +566,11 @@ if ($result) {
}
/*var_dump($tabpay);
var_dump($tabcompany);
var_dump($tabbq);
var_dump($tabtp);
var_dump($tabtype);*/
//var_dump($tabpay);
//var_dump($tabcompany);
//var_dump($tabbq);
//var_dump($tabtp);
//var_dump($tabtype);
// Write bookkeeping
if (!$error && $action == 'writebookkeeping') {
@ -594,9 +602,9 @@ if (!$error && $action == 'writebookkeeping') {
$db->begin();
// Introduce a protection. Total of tabtp must be total of tabbq
/*var_dump($tabpay);
var_dump($tabtp);
var_dump($tabbq);exit;*/
//var_dump($tabpay);
//var_dump($tabtp);
//var_dump($tabbq);exit;
// Bank
if (!$errorforline && is_array($tabbq[$key])) {
@ -665,6 +673,8 @@ if (!$error && $action == 'writebookkeeping') {
// Line into thirdparty account
foreach ($tabtp[$key] as $k => $mt) {
if ($mt) {
$lettering = false;
$reflabel = '';
if (!empty($val['lib'])) {
$reflabel .= dol_string_nohtmltag($val['lib']).($val['soclib'] ? " - " : "");
@ -693,11 +703,13 @@ if (!$error && $action == 'writebookkeeping') {
$bookkeeping->date_creation = $now;
if ($tabtype[$key] == 'payment') { // If payment is payment of customer invoice, we get ref of invoice
$lettering = true;
$bookkeeping->subledger_account = $k; // For payment, the subledger account is stored as $key of $tabtp
$bookkeeping->subledger_label = $tabcompany[$key]['name']; // $tabcompany is defined only if we are sure there is 1 thirdparty for the bank transaction
$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER;
$bookkeeping->label_compte = $accountingaccountcustomer->label;
} elseif ($tabtype[$key] == 'payment_supplier') { // If payment is payment of supplier invoice, we get ref of invoice
$lettering = true;
$bookkeeping->subledger_account = $k; // For payment, the subledger account is stored as $key of $tabtp
$bookkeeping->subledger_label = $tabcompany[$key]['name']; // $tabcompany is defined only if we are sure there is 1 thirdparty for the bank transaction
$bookkeeping->numero_compte = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER;
@ -780,6 +792,12 @@ if (!$error && $action == 'writebookkeeping') {
$errorforline++;
setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
}
} else {
if ($lettering && getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING')) {
require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
$lettering_static = new Lettering($db);
$nb_lettering = $lettering_static->bookkeepingLetteringAll(array($bookkeeping->id));
}
}
}
}
@ -1257,9 +1275,9 @@ if (empty($action) || $action == 'view') {
$accounttoshowsubledger = length_accounta($k);
if ($accounttoshow != $accounttoshowsubledger) {
if (empty($accounttoshowsubledger) || $accounttoshowsubledger == 'NotDefined') {
/*var_dump($tabpay[$key]);
var_dump($tabtype[$key]);
var_dump($tabbq[$key]);*/
//var_dump($tabpay[$key]);
//var_dump($tabtype[$key]);
//var_dump($tabbq[$key]);
//print '<span class="error">'.$langs->trans("ThirdpartyAccountNotDefined").'</span>';
if (!empty($tabcompany[$key]['code_compta'])) {
if (in_array($tabtype[$key], array('payment_various', 'payment_salary'))) {

View File

@ -58,7 +58,7 @@ if ($in_bookkeeping == '') {
$now = dol_now();
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -328,7 +328,7 @@ if ($action == 'writebookkeeping') {
foreach ($arrayofvat[$key] as $k => $mt) {
if ($mt) {
$accountingaccount->fetch($k, null, true); // TODO Use a cache for label
$accountingaccount->fetch(null, $k, true); // TODO Use a cache for label
$account_label = $accountingaccount->label;
// get compte id and label

View File

@ -61,7 +61,7 @@ $hookmanager->initHooks(array('purchasesjournal'));
$parameters = array();
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -377,6 +377,12 @@ if ($action == 'writebookkeeping') {
$errorforinvoice[$key] = 'other';
setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
}
} else {
if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING')) {
require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
$lettering_static = new Lettering($db);
$nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id), 'supplier_invoice');
}
}
}
}
@ -399,8 +405,18 @@ if ($action == 'writebookkeeping') {
$bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
$bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
$bookkeeping->subledger_account = '';
$bookkeeping->subledger_label = '';
if (!empty($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT)) {
if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT')) {
$bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
$bookkeeping->subledger_label = $tabcompany[$key]['name'];
} else {
$bookkeeping->subledger_account = '';
$bookkeeping->subledger_label = '';
}
} else {
$bookkeeping->subledger_account = '';
$bookkeeping->subledger_label = '';
}
$bookkeeping->numero_compte = $k;
$bookkeeping->label_compte = $label_account;
@ -451,7 +467,7 @@ if ($action == 'writebookkeeping') {
foreach ($arrayofvat[$key] as $k => $mt) {
if ($mt) {
$accountingaccount->fetch($k, null, true); // TODO Use a cache for label
$accountingaccount->fetch(null, $k, true); // TODO Use a cache for label
$label_account = $accountingaccount->label;
$bookkeeping = new BookKeeping($db);
@ -946,6 +962,13 @@ if (empty($action) || $action == 'view') {
print "</td>";
// Subledger account
print "<td>";
if (!empty($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT)) {
if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT')) {
print length_accounta($tabcompany[$key]['code_compta']);
}
} elseif (($accountoshow == "") || $accountoshow == 'NotDefined') {
print '<span class="error">' . $langs->trans("ThirdpartyAccountNotDefined") . '</span>';
}
print '</td>';
$companystatic->id = $tabcompany[$key]['id'];
$companystatic->name = $tabcompany[$key]['name'];

View File

@ -30,6 +30,7 @@
* \brief Page with sells journal
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
@ -63,7 +64,7 @@ $hookmanager->initHooks(array('sellsjournal'));
$parameters = array();
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -390,6 +391,12 @@ if ($action == 'writebookkeeping') {
$errorforinvoice[$key] = 'other';
setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
}
} else {
if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING')) {
require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
$lettering_static = new Lettering($db);
$nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id), 'customer_invoice');
}
}
}
}
@ -412,9 +419,14 @@ if ($action == 'writebookkeeping') {
$bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
$bookkeeping->thirdparty_code = $companystatic->code_client;
if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT')) {
$bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
$bookkeeping->subledger_label = $tabcompany[$key]['name'];
if (!empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT)) {
if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT')) {
$bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
$bookkeeping->subledger_label = $tabcompany[$key]['name'];
} else {
$bookkeeping->subledger_account = '';
$bookkeeping->subledger_label = '';
}
} else {
$bookkeeping->subledger_account = '';
$bookkeeping->subledger_label = '';
@ -468,7 +480,7 @@ if ($action == 'writebookkeeping') {
foreach ($arrayofvat[$key] as $k => $mt) {
if ($mt) {
$accountingaccount->fetch($k, null, true); // TODO Use a cache for label
$accountingaccount->fetch(null, $k, true); // TODO Use a cache for label
$label_account = $accountingaccount->label;
$bookkeeping = new BookKeeping($db);
@ -891,12 +903,12 @@ if (empty($action) || $action == 'view') {
print "</td>";
// Subledger account
print "<td>";
if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT')) {
if (($accountoshow == "") || $accountoshow == 'NotDefined') {
print '<span class="error">'.$langs->trans("ThirdpartyAccountNotDefined").'</span>';
} else {
if (!empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT)) {
if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT')) {
print length_accounta($tabcompany[$key]['code_compta']);
}
} elseif (($accountoshow == "") || $accountoshow == 'NotDefined') {
print '<span class="error">' . $langs->trans("ThirdpartyAccountNotDefined") . '</span>';
}
print '</td>';
$companystatic->id = $tabcompany[$key]['id'];

View File

@ -21,6 +21,7 @@
* \brief Page of a journal
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
@ -43,17 +44,6 @@ if ($in_bookkeeping == '') {
$in_bookkeeping = 'notyet';
}
// Security check
if (empty($conf->accounting->enabled)) {
accessforbidden();
}
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->mouvements->lire)) {
accessforbidden();
}
// Get information of journal
$object = new AccountingJournal($db);
$result = $object->fetch($id_journal);
@ -62,10 +52,10 @@ if ($result > 0) {
} elseif ($result < 0) {
dol_print_error('', $object->error, $object->errors);
} elseif ($result == 0) {
accessforbidden($langs->trans('ErrorRecordNotFound'));
accessforbidden('ErrorRecordNotFound');
}
$hookmanager->initHooks(array('globaljournal', $object->nature_text . 'journal'));
$hookmanager->initHooks(array('globaljournal', $object->nature.'journal'));
$parameters = array();
$date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear);
@ -93,6 +83,18 @@ if (!is_array($journal_data)) {
setEventMessages($object->error, $object->errors, 'errors');
}
// Security check
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->mouvements->lire)) {
accessforbidden();
}
/*
* Actions
*/
@ -235,7 +237,7 @@ if ($some_mandatory_steps_of_setup_were_not_done) {
print ' : ' . $langs->trans("AccountancyAreaDescMisc", 4, '<strong>' . $langs->transnoentitiesnoconv("MenuAccountancy") . '-' . $langs->transnoentitiesnoconv("Setup") . "-" . $langs->transnoentitiesnoconv("MenuDefaultAccounts") . '</strong>');
print '</div>';
}
print '<div class="tabsAction tabsActionNoBottom">';
print '<div class="tabsAction tabsActionNoBottom centerimp">';
if (!empty($conf->global->ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL) && $in_bookkeeping == 'notyet') {
print '<input type="button" class="butAction" name="exportcsv" value="' . $langs->trans("ExportDraftJournal") . '" onclick="launch_export();" />';
}

View File

@ -42,7 +42,7 @@ $codeventil = GETPOST('codeventil', 'int');
$id = GETPOST('id', 'int');
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {

View File

@ -1,7 +1,7 @@
<?php
/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2021 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2013-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
*
* This program is free software; you can redistribute it and/or modify
@ -24,6 +24,7 @@
* \brief Home supplier journalization page
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
@ -38,7 +39,7 @@ $validatemonth = GETPOST('validatemonth', 'int');
$validateyear = GETPOST('validateyear', 'int');
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -75,7 +76,7 @@ $action = GETPOST('action', 'aZ09');
$chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version');
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -171,8 +172,10 @@ if ($action == 'validatehistory') {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON " . $alias_product_perentity . ".accountancy_code_buy = aa.account_number AND aa.active = 1 AND aa.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa.entity = ".$conf->entity;
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa2 ON " . $alias_product_perentity . ".accountancy_code_buy_intra = aa2.account_number AND aa2.active = 1 AND aa2.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa2.entity = ".$conf->entity;
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa3 ON " . $alias_product_perentity . ".accountancy_code_buy_export = aa3.account_number AND aa3.active = 1 AND aa3.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa3.entity = ".$conf->entity;
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON " . $alias_societe_perentity . ".accountancy_code_buy = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity;
$sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0 AND l.product_type <= 2 AND f.entity = ".((int) $conf->entity);
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa4 ON " . $alias_product_perentity . ".accountancy_code_buy = aa4.account_number AND aa4.active = 1 AND aa4.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND aa4.entity = ".$conf->entity;
$sql .= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0";
$sql .= " AND l.product_type <= 2";
$sql .= " AND f.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy
if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) {
$sql .= " AND f.datef >= '".$db->idate($conf->global->ACCOUNTING_DATE_START_BINDING)."'";
}
@ -373,10 +376,14 @@ $sql .= " AND ff.fk_statut > 0";
$sql .= " AND ffd.product_type <= 2";
$sql .= " AND ff.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy
$sql .= " AND aa.account_number IS NULL";
if (!empty($conf->global->FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS)) {
$sql .= " AND ff.type IN (".FactureFournisseur::TYPE_STANDARD.",".FactureFournisseur::TYPE_REPLACEMENT.",".FactureFournisseur::TYPE_CREDIT_NOTE.")";
} else {
$sql .= " AND ff.type IN (".FactureFournisseur::TYPE_STANDARD.",".FactureFournisseur::TYPE_REPLACEMENT.",".FactureFournisseur::TYPE_CREDIT_NOTE.",".FactureFournisseur::TYPE_DEPOSIT.")";
}
$sql .= " GROUP BY ffd.fk_code_ventilation,aa.account_number,aa.label";
$sql .= ' ORDER BY aa.account_number';
dol_syslog('htdocs/accountancy/supplier/index.php');
dol_syslog('htdocs/accountancy/supplier/index.php', LOG_DEBUG);
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
@ -474,11 +481,17 @@ $sql .= " AND ff.datef <= '".$db->idate($search_date_end)."'";
if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) {
$sql .= " AND ff.datef >= '".$db->idate($conf->global->ACCOUNTING_DATE_START_BINDING)."'";
}
$sql .= " AND ff.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy
$sql .= " AND ff.fk_statut > 0";
$sql .= " AND ffd.product_type <= 2";
$sql .= " AND ff.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy
if (!empty($conf->global->FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS)) {
$sql .= " AND ff.type IN (".FactureFournisseur::TYPE_STANDARD.", ".FactureFournisseur::TYPE_REPLACEMENT.", ".FactureFournisseur::TYPE_CREDIT_NOTE.")";
} else {
$sql .= " AND ff.type IN (".FactureFournisseur::TYPE_STANDARD.", ".FactureFournisseur::TYPE_REPLACEMENT.", ".FactureFournisseur::TYPE_CREDIT_NOTE.", ".FactureFournisseur::TYPE_DEPOSIT.")";
}
$sql .= " AND aa.account_number IS NOT NULL";
$sql .= " GROUP BY ffd.fk_code_ventilation,aa.account_number,aa.label";
$sql .= ' ORDER BY aa.account_number';
dol_syslog('htdocs/accountancy/supplier/index.php');
$resql = $db->query($sql);
@ -494,13 +507,15 @@ if ($resql) {
print length_accountg($row[0]);
}
print '</td>';
print '<td>';
print '<td class="left">';
if ($row[0] == 'tobind') {
print $langs->trans("UseMenuToSetBindindManualy", DOL_URL_ROOT.'/accountancy/supplier/list.php?search_year='.((int) $y), $langs->transnoentitiesnoconv("ToBind"));
} else {
print $row[1];
}
print '</td>';
for ($i = 2; $i <= 13; $i++) {
print '<td class="right nowraponall amount">';
print price($row[$i]);
@ -523,7 +538,6 @@ print "</table>\n";
print '</div>';
if ($conf->global->MAIN_FEATURES_LEVEL > 0) { // This part of code looks strange. Why showing a report that should rely on result of this step ?
print '<br>';
print '<br>';
@ -560,9 +574,14 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) { // This part of code looks strange
if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) {
$sql .= " AND ff.datef >= '".$db->idate($conf->global->ACCOUNTING_DATE_START_BINDING)."'";
}
$sql .= " AND ff.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy
$sql .= " AND ff.fk_statut > 0";
$sql .= " AND ffd.product_type <= 2";
$sql .= " AND ff.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy
if (!empty($conf->global->FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS)) {
$sql .= " AND ff.type IN (".FactureFournisseur::TYPE_STANDARD.", ".FactureFournisseur::TYPE_REPLACEMENT.", ".FactureFournisseur::TYPE_CREDIT_NOTE.")";
} else {
$sql .= " AND ff.type IN (".FactureFournisseur::TYPE_STANDARD.", ".FactureFournisseur::TYPE_REPLACEMENT.", ".FactureFournisseur::TYPE_CREDIT_NOTE.", ".FactureFournisseur::TYPE_DEPOSIT.")";
}
dol_syslog('htdocs/accountancy/supplier/index.php');
$resql = $db->query($sql);

View File

@ -89,7 +89,7 @@ if (!$sortorder) {
$formaccounting = new FormAccounting($db);
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -384,7 +384,7 @@ if ($result) {
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="page" value="'.$page.'">';
print_barre_liste($langs->trans("InvoiceLinesDone"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
print_barre_liste($langs->trans("InvoiceLinesDone"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
print '<span class="opacitymedium">'.$langs->trans("DescVentilDoneSupplier").'</span><br>';
print '<br><div class="inline-block divButAction paddingbottom">'.$langs->trans("ChangeAccount").' ';

View File

@ -1,8 +1,9 @@
<?php
/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2014-2015 Ari Elbaz (elarifr) <github@accedinfo.com>
* Copyright (C) 2013-2014 Florian Henry <florian.henry@open-concept.pro>
/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2014-2015 Ari Elbaz (elarifr) <github@accedinfo.com>
* Copyright (C) 2013-2021 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>s
* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
*
@ -47,6 +48,7 @@ $show_files = GETPOST('show_files', 'int');
$confirm = GETPOST('confirm', 'alpha');
$toselect = GETPOST('toselect', 'array');
$optioncss = GETPOST('optioncss', 'alpha');
$default_account = GETPOST('default_account', 'int');
// Select Box
$mesCasesCochees = GETPOST('toselect', 'array');
@ -104,7 +106,7 @@ $accountingAccount = new AccountingAccount($db);
$chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version');
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
@ -159,8 +161,8 @@ if (empty($reshook)) {
// Mass actions
$objectclass = 'AccountingAccount';
$permissiontoread = $user->rights->accounting->read;
$permissiontodelete = $user->rights->accounting->delete;
$permissiontoread = $user->hasRight('accounting', 'read');
$permissiontodelete = $user->hasRight('accounting', 'delete');
$uploaddir = $conf->accounting->dir_output;
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
}
@ -442,12 +444,15 @@ if ($result) {
$arrayofmassactions = array(
'ventil'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Ventilate")
,'set_default_account'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("ConfirmPreselectAccount")
//'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
//'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
);
//if ($user->rights->mymodule->supprimer) $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
//if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array();
$massactionbutton = $form->selectMassAction('ventil', $arrayofmassactions, 1);
if ($massaction !== 'set_default_account') {
$massactionbutton = $form->selectMassAction('ventil', $arrayofmassactions, 1);
}
print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">'."\n";
print '<input type="hidden" name="action" value="ventil">';
@ -462,9 +467,17 @@ if ($result) {
print_barre_liste($langs->trans("InvoiceLines"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit);
if ($massaction == 'set_default_account') {
$formquestion[]=array('type' => 'other',
'name' => 'set_default_account',
'label' => $langs->trans("AccountancyCode"),
'value' => $formaccounting->select_account('', 'default_account', 1, array(), 0, 0, 'maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone'));
print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmPreselectAccount"), $langs->trans("ConfirmPreselectAccountQuestion", count($toselect)), "confirm_set_default_account", $formquestion, 1, 0, 200, 500, 1);
}
print '<span class="opacitymedium">'.$langs->trans("DescVentilTodoCustomer").'</span></br><br>';
if ($msg) {
if (!empty($msg)) {
print $msg.'<br>';
}
@ -736,7 +749,7 @@ if ($result) {
// Suggested accounting account
print '<td>';
print $formaccounting->select_account($suggestedid, 'codeventil'.$facturefourn_static_det->id, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone');
print $formaccounting->select_account(($default_account > 0 && $confirm === 'yes' && in_array($objp->rowid."_".$i, $toselect)) ? $default_account : $suggestedid, 'codeventil'.$facturefourn_static_det->id, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone');
print '</td>';
// Column with checkbox
@ -745,6 +758,14 @@ if ($result) {
if (!empty($suggestedid) && $suggestedaccountingaccountfor != '' && $suggestedaccountingaccountfor != 'eecwithoutvatnumber') {
$ischecked = 1;
}
if (!empty($toselect)) {
$ischecked = 0;
if (in_array($objp->rowid."_".$i, $toselect)) {
$ischecked=1;
}
}
print '<input type="checkbox" class="flat checkforselect checkforselect'.$facturefourn_static_det->id.'" name="toselect[]" value="'.$facturefourn_static_det->id."_".$i.'"'.($ischecked ? " checked" : "").'/>';
print '</td>';

View File

@ -1,5 +1,5 @@
<?php
/* Copyright (C) 2015-2018 Alexandre Spangaro <aspangaro@open-dsi.fr>
/* Copyright (C) 2015-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2016 Charlie Benke <charlie@patas-monkey.com>
*
* This program is free software; you can redistribute it and/or modify
@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// $formatexportset ùust be defined
// $formatexportset must be defined
// Protection to avoid direct call of template
if (empty($conf) || !is_object($conf)) {
@ -24,11 +24,11 @@ if (empty($conf) || !is_object($conf)) {
exit;
}
$code = $conf->global->MAIN_INFO_ACCOUNTANT_CODE;
$prefix = $conf->global->ACCOUNTING_EXPORT_PREFIX_SPEC;
$format = $conf->global->ACCOUNTING_EXPORT_FORMAT;
$nodateexport = $conf->global->ACCOUNTING_EXPORT_NO_DATE_IN_FILENAME;
$siren = $conf->global->MAIN_INFO_SIREN;
$code = getDolGlobalString('MAIN_INFO_ACCOUNTANT_CODE');
$prefix = getDolGlobalString('ACCOUNTING_EXPORT_PREFIX_SPEC');
$format = getDolGlobalString('ACCOUNTING_EXPORT_FORMAT');
$nodateexport = getDolGlobalInt('ACCOUNTING_EXPORT_NO_DATE_IN_FILENAME');
$siren = getDolGlobalString('MAIN_INFO_SIREN');
$date_export = "_".dol_print_date(dol_now(), '%Y%m%d%H%M%S');
$endaccountingperiod = dol_print_date(dol_now(), '%Y%m%d');

View File

@ -30,6 +30,7 @@
* \brief Page to setup the module Foundation
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
@ -64,7 +65,7 @@ if ($action == 'set_default') {
} elseif ($action == 'del_default') {
$ret = delDocumentModel($value, $type);
if ($ret > 0) {
if ($conf->global->MEMBER_ADDON_PDF_ODT == "$value") {
if (getDolGlobalString('MEMBER_ADDON_PDF_ODT') == "$value") {
dolibarr_del_const($db, 'MEMBER_ADDON_PDF_ODT', $conf->entity);
}
}
@ -108,10 +109,10 @@ if ($action == 'set_default') {
$res3 = dolibarr_set_const($db, 'ADHERENT_CREATE_EXTERNAL_USER_LOGIN', GETPOST('ADHERENT_CREATE_EXTERNAL_USER_LOGIN', 'alpha'), 'chaine', 0, '', $conf->entity);
$res4 = dolibarr_set_const($db, 'ADHERENT_BANK_USE', GETPOST('ADHERENT_BANK_USE', 'alpha'), 'chaine', 0, '', $conf->entity);
// Use vat for invoice creation
if ($conf->facture->enabled) {
if (isModEnabled('facture')) {
$res4 = dolibarr_set_const($db, 'ADHERENT_VAT_FOR_SUBSCRIPTIONS', GETPOST('ADHERENT_VAT_FOR_SUBSCRIPTIONS', 'alpha'), 'chaine', 0, '', $conf->entity);
$res5 = dolibarr_set_const($db, 'ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS', GETPOST('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS', 'alpha'), 'chaine', 0, '', $conf->entity);
if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) {
if (isModEnabled("product") || isModEnabled("service")) {
$res6 = dolibarr_set_const($db, 'ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS', GETPOST('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS', 'alpha'), 'chaine', 0, '', $conf->entity);
}
}
@ -238,27 +239,27 @@ print "</td></tr>\n";
// Insert subscription into bank account
print '<tr class="oddeven"><td>'.$langs->trans("MoreActionsOnSubscription").'</td>';
$arraychoices = array('0'=>$langs->trans("None"));
if (!empty($conf->banque->enabled)) {
if (isModEnabled("banque")) {
$arraychoices['bankdirect'] = $langs->trans("MoreActionBankDirect");
}
if (!empty($conf->banque->enabled) && !empty($conf->societe->enabled) && !empty($conf->facture->enabled)) {
if (isModEnabled("banque") && isModEnabled("societe") && isModEnabled('facture')) {
$arraychoices['invoiceonly'] = $langs->trans("MoreActionInvoiceOnly");
}
if (!empty($conf->banque->enabled) && !empty($conf->societe->enabled) && !empty($conf->facture->enabled)) {
if (isModEnabled("banque") && isModEnabled("societe") && isModEnabled('facture')) {
$arraychoices['bankviainvoice'] = $langs->trans("MoreActionBankViaInvoice");
}
print '<td>';
print $form->selectarray('ADHERENT_BANK_USE', $arraychoices, $conf->global->ADHERENT_BANK_USE, 0);
if ($conf->global->ADHERENT_BANK_USE == 'bankdirect' || $conf->global->ADHERENT_BANK_USE == 'bankviainvoice') {
print $form->selectarray('ADHERENT_BANK_USE', $arraychoices, getDolGlobalString('ADHERENT_BANK_USE'), 0);
if (getDolGlobalString('ADHERENT_BANK_USE') == 'bankdirect' || getDolGlobalString('ADHERENT_BANK_USE') == 'bankviainvoice') {
print '<br><div style="padding-top: 5px;"><span class="opacitymedium">'.$langs->trans("ABankAccountMustBeDefinedOnPaymentModeSetup").'</span></div>';
}
print '</td>';
print "</tr>\n";
// Use vat for invoice creation
if ($conf->facture->enabled) {
if (isModEnabled('facture')) {
print '<tr class="oddeven"><td>'.$langs->trans("VATToUseForSubscriptions").'</td>';
if (!empty($conf->banque->enabled)) {
if (isModEnabled("banque")) {
print '<td>';
print $form->selectarray('ADHERENT_VAT_FOR_SUBSCRIPTIONS', array('0'=>$langs->trans("NoVatOnSubscription"), 'defaultforfoundationcountry'=>$langs->trans("Default")), (empty($conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS) ? '0' : $conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS), 0);
print '</td>';
@ -269,7 +270,7 @@ if ($conf->facture->enabled) {
}
print "</tr>\n";
if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) {
if (isModEnabled("product") || isModEnabled("service")) {
print '<tr class="oddeven"><td>'.$langs->trans("ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS").'</td>';
print '<td>';
$selected = (empty($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS) ? '' : $conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS);
@ -378,16 +379,16 @@ foreach ($dirmodels as $reldir) {
print '</td>';
} else {
print '<td class="center">'."\n";
print '<a href="'.$_SERVER["PHP_SELF"].'?action=set_default&token='.newToken().'&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
print '<a href="'.$_SERVER["PHP_SELF"].'?action=set_default&token='.newToken().'&value='.$name.'&scandir='.(!empty($module->scandir) ? $module->scandir : '').'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
print "</td>";
}
// Defaut
print '<td class="center">';
if ($conf->global->MEMBER_ADDON_PDF == $name) {
if (getDolGlobalString('MEMBER_ADDON_PDF') == $name) {
print img_picto($langs->trans("Default"), 'on');
} else {
print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&token='.newToken().'&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&token='.newToken().'&value='.$name.'&scandir='.(!empty($module->scandir) ? $module->scandir : '').'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
}
print '</td>';
@ -398,8 +399,8 @@ foreach ($dirmodels as $reldir) {
$htmltooltip .= '<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur;
}
$htmltooltip .= '<br><br><u>'.$langs->trans("FeaturesSupported").':</u>';
$htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1);
$htmltooltip .= '<br>'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1);
$htmltooltip .= '<br>'.$langs->trans("Logo").': '.yn(!empty($module->option_logo) ? $module->option_logo : 0, 1, 1);
$htmltooltip .= '<br>'.$langs->trans("MultiLanguage").': '.yn(!empty($module->option_multilang) ? $module->option_multilang : 0, 1, 1);
print '<td class="center">';

View File

@ -29,6 +29,7 @@
* \brief Page to setup the module Foundation
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';

View File

@ -24,6 +24,7 @@
* \brief Page to setup extra fields of members
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
@ -84,7 +85,7 @@ print dol_get_fiche_end();
// Buttons
if ($action != 'create' && $action != 'edit') {
print '<div class="tabsAction">';
print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute").'</a></div>';
print '<a class="butAction reposition" href="'.$_SERVER["PHP_SELF"].'?action=create">'.$langs->trans("NewAttribute").'</a>';
print "</div>";
}

View File

@ -27,6 +27,7 @@
* \brief Page to setup extra fields of members
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
@ -87,7 +88,7 @@ print dol_get_fiche_end();
// Buttons
if ($action != 'create' && $action != 'edit') {
print '<div class="tabsAction">';
print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"]."?action=create\">".$langs->trans("NewAttribute").'</a></div>';
print '<a class="butAction reposition" href="'.$_SERVER["PHP_SELF"].'?action=create">'.$langs->trans("NewAttribute").'</a>';
print "</div>";
}

View File

@ -24,6 +24,7 @@
* \brief File of main public page for member module
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
@ -95,12 +96,13 @@ if ($action == 'update') {
$form = new Form($db);
$title = $langs->trans("MembersSetup");
$help_url = 'EN:Module_Foundations|FR:Module_Adh&eacute;rents|ES:M&oacute;dulo_Miembros';
llxHeader('', $langs->trans("MembersSetup"), $help_url);
llxHeader('', $title, $help_url);
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
print load_fiche_titre($langs->trans("MembersSetup"), $linkback, 'title_setup');
print load_fiche_titre($title, $linkback, 'title_setup');
$head = member_admin_prepare_head();
@ -166,10 +168,30 @@ if (empty($conf->global->MEMBER_ENABLE_PUBLIC)) {
print $enabledisablehtml;
print '<input type="hidden" id="MEMBER_ENABLE_PUBLIC" name="MEMBER_ENABLE_PUBLIC" value="'.(empty($conf->global->MEMBER_ENABLE_PUBLIC) ? 0 : 1).'">';
print '<br><br>';
print '<br>';
if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) {
print '<br>';
//print $langs->trans('FollowingLinksArePublic').'<br>';
print img_picto('', 'globe').' <span class="opacitymedium">'.$langs->trans('BlankSubscriptionForm').'</span><br>';
if (isModEnabled('multicompany')) {
$entity_qr = '?entity='.$conf->entity;
} else {
$entity_qr = '';
}
// Define $urlwithroot
$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
print '<div class="urllink">';
print '<input type="text" id="publicurlmember" class="quatrevingtpercentminusx" value="'.$urlwithroot.'/public/members/new.php'.$entity_qr.'">';
print '<a target="_blank" rel="noopener noreferrer" href="'.$urlwithroot.'/public/members/new.php'.$entity_qr.'">'.img_picto('', 'globe', 'class="paddingleft"').'</a>';
print '</div>';
print ajax_autoselect('publicurlmember');
print '<br>';
print '<div class="div-table-responsive-no-min">';
@ -177,14 +199,14 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) {
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Parameter").'</td>';
print '<td class="right">'.$langs->trans("Value").'</td>';
print '<td>'.$langs->trans("Value").'</td>';
print "</tr>\n";
// Force Type
$adht = new AdherentType($db);
print '<tr class="oddeven drag" id="trforcetype"><td>';
print $langs->trans("ForceMemberType");
print '</td><td class="right">';
print '</td><td>';
$listofval = array();
$listofval += $adht->liste_array(1);
$forcetype = empty($conf->global->MEMBER_NEWFORM_FORCETYPE) ? -1 : $conf->global->MEMBER_NEWFORM_FORCETYPE;
@ -196,7 +218,7 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) {
$morphys["mor"] = $langs->trans("Moral");
print '<tr class="oddeven drag" id="trforcenature"><td>';
print $langs->trans("ForceMemberNature");
print '</td><td class="right">';
print '</td><td>';
$forcenature = empty($conf->global->MEMBER_NEWFORM_FORCEMORPHY) ? 0 : $conf->global->MEMBER_NEWFORM_FORCEMORPHY;
print $form->selectarray("MEMBER_NEWFORM_FORCEMORPHY", $morphys, $forcenature, 1);
print "</td></tr>\n";
@ -204,31 +226,31 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) {
// Amount
print '<tr class="oddeven" id="tramount"><td>';
print $langs->trans("DefaultAmount");
print '</td><td class="right">';
print '<input type="text" class="right width75" id="MEMBER_NEWFORM_AMOUNT" name="MEMBER_NEWFORM_AMOUNT" value="'.(!empty($conf->global->MEMBER_NEWFORM_AMOUNT) ? $conf->global->MEMBER_NEWFORM_AMOUNT : '').'">';
print '</td><td>';
print '<input type="text" class="right width50" id="MEMBER_NEWFORM_AMOUNT" name="MEMBER_NEWFORM_AMOUNT" value="'.(!empty($conf->global->MEMBER_NEWFORM_AMOUNT) ? $conf->global->MEMBER_NEWFORM_AMOUNT : '').'">';
print "</td></tr>\n";
// Can edit
print '<tr class="oddeven" id="tredit"><td>';
print $langs->trans("CanEditAmount");
print '</td><td class="right">';
print '</td><td>';
print $form->selectyesno("MEMBER_NEWFORM_EDITAMOUNT", (!empty($conf->global->MEMBER_NEWFORM_EDITAMOUNT) ? $conf->global->MEMBER_NEWFORM_EDITAMOUNT : 0), 1);
print "</td></tr>\n";
// Jump to an online payment page
print '<tr class="oddeven" id="trpayment"><td>';
print $langs->trans("MEMBER_NEWFORM_PAYONLINE");
print '</td><td class="right">';
print '</td><td>';
$listofval = array();
$listofval['-1'] = $langs->trans('No');
$listofval['all'] = $langs->trans('Yes').' ('.$langs->trans("VisitorCanChooseItsPaymentMode").')';
if (!empty($conf->paybox->enabled)) {
if (isModEnabled('paybox')) {
$listofval['paybox'] = 'Paybox';
}
if (!empty($conf->paypal->enabled)) {
if (isModEnabled('paypal')) {
$listofval['paypal'] = 'PayPal';
}
if (!empty($conf->stripe->enabled)) {
if (isModEnabled('stripe')) {
$listofval['stripe'] = 'Stripe';
}
print $form->selectarray("MEMBER_NEWFORM_PAYONLINE", $listofval, (!empty($conf->global->MEMBER_NEWFORM_PAYONLINE) ? $conf->global->MEMBER_NEWFORM_PAYONLINE : ''), 0);
@ -247,29 +269,6 @@ print dol_get_fiche_end();
print '</form>';
if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) {
print '<br>';
//print $langs->trans('FollowingLinksArePublic').'<br>';
print img_picto('', 'globe').' <span class="opacitymedium">'.$langs->trans('BlankSubscriptionForm').'</span><br>';
if (!empty($conf->multicompany->enabled)) {
$entity_qr = '?entity='.$conf->entity;
} else {
$entity_qr = '';
}
// Define $urlwithroot
$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
print '<div class="urllink">';
print '<input type="text" id="publicurlmember" class="quatrevingtpercentminusx" value="'.$urlwithroot.'/public/members/new.php'.$entity_qr.'">';
print '<a target="_blank" rel="noopener noreferrer" href="'.$urlwithroot.'/public/members/new.php'.$entity_qr.'">'.img_picto('', 'globe', 'class="paddingleft"').'</a>';
print '</div>';
print ajax_autoselect('publicurlmember');
}
// End of page
llxFooter();
$db->close();

View File

@ -26,6 +26,7 @@
* \brief Page of members events
*/
// Load Dolibarr environment
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
@ -130,7 +131,7 @@ if ($object->id > 0) {
llxHeader("", $title, $help_url);
if (!empty($conf->notification->enabled)) {
if (isModEnabled('notification')) {
$langs->load("mails");
}
$head = member_prepare_head($object);
@ -162,11 +163,11 @@ if ($object->id > 0) {
$newcardbutton = '';
if (!empty($conf->agenda->enabled)) {
$newcardbutton .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create&backtopage=1&origin=member&originid='.$id);
if (isModEnabled('agenda')) {
$newcardbutton .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']).($object->id > 0 ? '?id='.$object->id : '').'&origin=member&originid='.$id);
}
if (!empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
print '<br>';
$param = '&id='.$id;

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