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

This commit is contained in:
atm-florian 2023-01-10 11:06:29 +01:00
commit 36c51de284
5498 changed files with 345764 additions and 94514 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"

25
.github/workflows/code_quality.yml vendored Normal file
View File

@ -0,0 +1,25 @@
name: Qodana
on:
schedule:
- cron: "0 20 * * *"
workflow_dispatch:
branches:
- develop
# push:
# branches:
# - develop
jobs:
qodana:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 1
#php-version: '7.1'
- name: 'Qodana Scan'
uses: JetBrains/qodana-action@v2022.3.0
#with:
# php-version: '7.1'
env:
QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}

View File

@ -0,0 +1,38 @@
# See syntax file on https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions
name: Doxygen
on:
schedule:
- cron: "0 15 * * *"
workflow_dispatch:
branches:
- develop
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Build
uses: DenverCoder1/doxygen-github-pages-action@v1.2.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: gh-pages
folder: build/html
config_file: build/doxygen/dolibarr-doxygen.doxyfile
# - name: Deploy
# uses: JamesIves/github-pages-deploy-action@v4
# with:
# branch: gh-pages
# folder: build/html # The folder the action should deploy.
# target-folder: docs/html2
#jobs:
# doxygen:
# runs-on: ubuntu-latest
# steps:
# - name: 'Doxygen'
# uses: mattnotmitt/doxygen-action@1.9.5
# with:
# doxyfile-path: build/doxygen

View File

@ -4,12 +4,20 @@ name: "Exakat analysis"
on:
schedule:
- cron: "0 20 * * *"
workflow_dispatch:
branches:
- develop
permissions:
contents: read
jobs:
exakat:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Exakat
uses: docker://exakat/exakat-ga
with:

View File

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

4
.gitignore vendored
View File

@ -19,6 +19,7 @@ default.properties
*.orig
Thumbs.db
/dolibarr_genesis.mp4
.phpunit.result.cache
# Log files
dolibarr_install.log
upgrade.log
@ -42,6 +43,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 +58,3 @@ yarn.lock
package-lock.json
doc/install.lock
/factory/

View File

@ -6,22 +6,26 @@ build:
analysis:
tests:
override:
- php-scrutinizer-run
- command: php-scrutinizer-run
idle_timeout: 8000
#- php-scrutinizer-run --sub-project-dir=htdocs/admin
imports:
- javascript
- php
filter:
excluded_paths:
- build/*
- dev/*
- doc/*
- documents/*
- node_modules/*
- test/*
dependency_paths:
- htdocs/includes/*
- build/
- dev/
- doc/
- documents/
- node_modules/
- test/
- htdocs/custom/
- htdocs/includes/
- htdocs/install/doctemplates/
#dependency_paths:
# - htdocs/includes/
paths:
- htdocs/*
- scripts/*
@ -32,19 +36,23 @@ tools:
enabled: true
extensions:
- php
dependency_paths:
- htdocs/includes/
#dependency_paths:
# - htdocs/includes/
filter:
excluded_paths:
- build/*
- dev/*
- doc/*
- test/*
- htdocs/includes/*
- build/
- dev/
- doc/
- documents/
- htdocs/custom/
- htdocs/includes/
- htdocs/install/doctemplates/
- htdocs/core/class/lessc.class.php
- node_modules/
- test/
paths:
- htdocs/
- scripts/
- htdocs/*
- scripts/*
config:
parameter_reference_check:
enabled: true
@ -153,67 +161,73 @@ tools:
# To use specific config for a specific path, use path_configs: (see example on page https://scrutinizer-ci.com/docs/configuration/tool_config_structure)
# php_depend
php_pdepend:
enabled: false
configuration_file: null
suffixes:
- php
excluded_dirs: { }
filter:
excluded_paths:
- 'build/*'
- 'dev/*'
- 'doc/*'
- 'test/*'
- 'htdocs/includes/*'
paths: { }
#php_pdepend:
# enabled: false
# configuration_file: null
# suffixes:
# - php
# excluded_dirs: { }
# filter:
# excluded_paths:
# - 'build/*'
# - 'dev/*'
# - 'doc/*'
# - 'test/*'
# - 'htdocs/includes/*'
# paths: { }
# change tracking
php_changetracking:
enabled: false
bug_patterns:
- '\bfix(?:es|ed)?\b'
feature_patterns:
- '\badd(?:s|ed)?\b'
- '\bimplement(?:s|ed)?\b'
filter:
excluded_paths:
- 'build/*'
- 'dev/*'
- 'doc/*'
- 'test/*'
- 'htdocs/includes/*'
paths: { }
#php_changetracking:
# enabled: false
# bug_patterns:
# - '\bfix(?:es|ed)?\b'
# feature_patterns:
# - '\badd(?:s|ed)?\b'
# - '\bimplement(?:s|ed)?\b'
# filter:
# excluded_paths:
# - 'build/*'
# - 'dev/*'
# - 'doc/*'
# - 'documents/*'
# - 'htdocs/includes/*'
# - 'node_modules/*'
# - 'test/*'
# paths: { }
# Similar code detection
php_sim:
enabled: false
min_mass: 30
filter:
excluded_paths:
- 'build/*'
- 'dev/*'
- 'doc/*'
- 'test/*'
- 'htdocs/includes/*'
paths: { }
#php_sim:
# enabled: false
# min_mass: 30
# filter:
# excluded_paths:
# - 'build/*'
# - 'dev/*'
# - 'doc/*'
# - 'documents/*'
# - 'htdocs/includes/*'
# - 'node_modules/*'
# - 'test/*'
# paths: { }
# Coding-Style / Bug Detection
js_hint:
enabled: false
use_native_config: true
extensions:
- js
filter:
excluded_paths:
- 'build/*'
- 'dev/*'
- 'doc/*'
- 'test/*'
- 'htdocs/includes/*'
paths: { }
config: { }
path_configs: { }
#js_hint:
# enabled: false
# use_native_config: true
# extensions:
# - js
# filter:
# excluded_paths:
# - 'build/*'
# - 'dev/*'
# - 'doc/*'
# - 'documents/*'
# - 'htdocs/includes/*'
# - 'node_modules/*'
# - 'test/*'
# paths: { }
# config: { }
# path_configs: { }
before_commands: { }

View File

@ -2,10 +2,9 @@
# from Dolibarr GitHub repository.
# For syntax, see https://docs.travis-ci.com/user/languages/php/
# We use dist: xenial to have php 5.6+ available
# We use dist: bionic = 18.04
os: linux
dist: xenial
#dist: bionic
dist: bionic
language: php
@ -18,22 +17,43 @@ services:
- mysql
- postgresql
before_install:
- |
echo "Add ondrej PPA"
sudo add-apt-repository -y ppa:ondrej/php
sudo apt-get update
echo "Disabling Xdebug for composer"
export PHP_VERSION_NAME=$(phpenv version-name)
echo $PHP_VERSION_NAME
ls ~/.phpenv/versions/$PHP_VERSION_NAME/etc/conf.d/
cp ~/.phpenv/versions/$PHP_VERSION_NAME/etc/conf.d/xdebug.ini /tmp/xdebug.ini
phpenv config-rm xdebug.ini
phpenv rehash
echo
addons:
# Force postgresql to 9.4 (the oldest availablable on xenial)
postgresql: '9.4'
# Force postgresql version
postgresql: '10'
apt:
sources:
# To use the last version of pgloader, we add repo of postgresql with a name available in http://apt.postgresql.org/pub/repos/apt/
- pgdg-xenial
- sourceline: 'ppa:ondrej/php'
packages:
# We need a webserver to test the webservices
# Let's install Apache with.
- apache2
# mod_php is not supported by Travis. Add fcgi. We install FPM later on.
- libapache2-mod-fastcgi
# We need pgloader for import mysql database into pgsql
- pgloader
- php
- php7.1-pgsql
- php7.1-mysqli
- php7.1-xml
- php7.1-intl
- php8.1-pgsql
- php8.1-mysqli
- php8.1-xml
- php8.1-intl
env:
global:
# Set to true for very verbose output
@ -44,21 +64,21 @@ jobs:
#allow_failures:
#- php: nightly
include:
- stage: PHP 5.6-7.4
- stage: PHP 7.0-8.1
if: type = push
php: '5.6'
php: '7.1'
env: DB=postgresql
- stage: PHP 5.6-7.4
- stage: PHP 7.0-8.1
if: type = pull_request OR type = push
php: '7.4.22'
php: '8.1'
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
if: type = push AND branch = 17.0
php: nightly
env: DB=mysql
notifications:
@ -72,43 +92,31 @@ notifications:
on_failure: always
use_notice: true
before_install:
- |
echo "Disabling Xdebug for composer"
export PHP_VERSION_NAME=$(phpenv version-name)
cp ~/.phpenv/versions/$PHP_VERSION_NAME/etc/conf.d/xdebug.ini /tmp/xdebug.ini
phpenv config-rm xdebug.ini
echo
install:
- |
echo "Updating Composer"
rm $TRAVIS_BUILD_DIR/composer.json
rm $TRAVIS_BUILD_DIR/composer.lock
echo "Updating Composer config"
composer -V
composer self-update
composer -n init
composer -n config vendor-dir htdocs/includes
#rm $TRAVIS_BUILD_DIR/composer.json
#rm $TRAVIS_BUILD_DIR/composer.lock
#composer -n init
#composer -n config vendor-dir htdocs/includes
composer -n config -g vendor-dir htdocs/includes
echo
- |
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
echo "Update Composer version and Install tools - PHP Unit, Parallel Lint, PHP CodeSniffer, PHP Vardump check - for $TRAVIS_PHP_VERSION"
echo "(version 2.5 is bugged and generate phpunit error Exception: Serialization of 'Closure' is not allowed)"
if [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] || [ "$TRAVIS_PHP_VERSION" = '7.2' ]; then
composer self-update 2.2.18
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
if [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ]; then
composer self-update 2.2.18
composer -n require phpunit/phpunit ^7 \
php-parallel-lint/php-parallel-lint ^1.2 \
php-parallel-lint/php-console-highlighter ^0 \
@ -116,13 +124,16 @@ install:
squizlabs/php_codesniffer ^3
fi
# phpunit 9 is required for php 8
if [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then
composer -n require --ignore-platform-reqs phpunit/phpunit ^7 \
if [ "$TRAVIS_PHP_VERSION" = '8.0' ] || [ "$TRAVIS_PHP_VERSION" = '8.1' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then
composer self-update 2.4.4
composer -n require --ignore-platform-reqs phpunit/phpunit ^8 \
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
# Remove non expected files
rm -fr /home/travis/build/Dolibarr/dolibarr/htdocs/includes/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js
echo
- |
@ -246,17 +257,22 @@ before_script:
- echo "Setting up Apache + FPM"
# setup link for php legacy
- sudo ln -s ~/.phpenv/versions/$(phpenv version-name)/bin/php /bin/php
# install apache web server
- sudo apt-get install apache2 php-fpm php-mysql php-pgsql php-gd php-ldap php-xml php-mbstring libapache2-mod-php
# enable php-fpm
- sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
- |
if [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] || [ "$TRAVIS_PHP_VERSION" = '7.2' ] || [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ] || [ "$TRAVIS_PHP_VERSION" = '7.4.22' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then
if [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] || [ "$TRAVIS_PHP_VERSION" = '7.2' ] || [ "$TRAVIS_PHP_VERSION" = '7.3' ] || [ "$TRAVIS_PHP_VERSION" = '7.4' ] || [ "$TRAVIS_PHP_VERSION" = '8.0' ] || [ "$TRAVIS_PHP_VERSION" = '8.1' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then
# Copy the included pool
sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.d/www.conf
fi
- sudo a2enmod rewrite actions fastcgi alias
- sudo a2enmod proxy_fcgi rewrite setenvif cgi alias
- echo "cgi.fix_pathinfo = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
- sudo sed -i -e "s,www-data,travis,g" /etc/apache2/envvars
- sudo chown -R travis:travis /var/lib/apache2/fastcgi
#- sudo chown -R travis:travis /var/lib/apache2/fastcgi
# start php-fpm
- ~/.phpenv/versions/$(phpenv version-name)/sbin/php-fpm
# configure apache virtual hosts
- sudo cp -f build/travis-ci/apache.conf /etc/apache2/sites-available/000-default.conf
@ -284,12 +300,12 @@ script:
set -e
#parallel-lint --exclude htdocs/includes --blame .
# Exclusions are defined in the ruleset.xml file
if [ "$TRAVIS_PHP_VERSION" = "7.4.22" ]; then
if [ "$TRAVIS_PHP_VERSION" = "8.1" ]; then
parallel-lint -e php --exclude dev/tools/test/namespacemig --exclude htdocs/includes/composer --exclude htdocs/includes/myclabs --exclude htdocs/includes/phpspec --exclude dev/initdata/dbf/includes \
--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
@ -299,7 +315,7 @@ script:
# 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
if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_PHP_VERSION" = "8.1" ]; then
phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .;
fi
set +e
@ -310,7 +326,7 @@ script:
# 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
if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_PHP_VERSION" = "8.1" ]; 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
@ -436,6 +452,12 @@ 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
php upgrade.php 17.0.0 18.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade17001800.log
php upgrade2.php 17.0.0 18.0.0 > $TRAVIS_BUILD_DIR/upgrade17001800-2.log
php step5.php 17.0.0 18.0.0 > $TRAVIS_BUILD_DIR/upgrade17001800-3.log
ls -alrt $TRAVIS_BUILD_DIR/
- |
@ -468,6 +490,9 @@ after_script:
ls $TRAVIS_BUILD_DIR/documents
#cat $TRAVIS_BUILD_DIR/documents/dolibarr.log
sudo tail -n 50 $TRAVIS_BUILD_DIR/documents/dolibarr.log
echo "After script - Output last lines of apache error.log"
sudo ls /var/log/apache2
sudo tail -n 50 /var/log/apache2/travis_error_log
after_success:
- |
@ -476,16 +501,16 @@ after_success:
after_failure:
- |
echo Failure detected, so we show samples of log to help diagnose
# This part of code is executed only if previous command that fails are enclosed with set +e
# Upgrade log files
# This part of code is executed only if the command that fails are enclosed with set +e
# Show upgrade log files
for ficlog in `ls $TRAVIS_BUILD_DIR/*.log`
do
echo "Debugging informations for file $ficlog"
#cat $ficlog
done
# Apache log file
# Show Apache log file
echo "Debugging informations for file apache error.log"
sudo cat /var/log/apache2/travis_error_log
sudo tail -n 50 /var/log/apache2/travis_error_log
if [ "$DEBUG" = true ]; then
# Dolibarr log file
echo "Debugging informations for file dolibarr.log (latest 50 lines)"

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

@ -13,7 +13,7 @@ The Dolibarr images resources (available in the doc directory) is distributed un
The name Dolibarr is a trademark initially registered by Laurent Destailleur and ceased to the Dolibarr foundation. You can use the name Dolibarr
for your own need as long as you follow the rules defined on the page https://wiki.dolibarr.org/index.php/Rules_to_use_the_brand_name_%22Dolibarr%22
for your own need as long as you follow the rules defined on the page https://wiki.dolibarr.org/index.php/Rules_to_use_the_brand_name_%22Dolibarr%22
The use of the name DoliStore is also restricted to the same rules defined on https://wiki.dolibarr.org/index.php/Rules_to_use_the_brand_name_%22Dolibarr%22
@ -23,7 +23,6 @@ Licence of dependencies of third-party components used by Dolibarr (all compatib
Component Version License GPL Compatible Usage
-------------------------------------------------------------------------------------
PHP libraries:
ADOdb-Date 0.36 Modified BSD License Yes Date convertion (not into rpm package)
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
@ -31,17 +30,19 @@ Mobiledetect 2.8.39 MIT License Yes
NuSoap 0.9.5 LGPL 2.1+ Yes Library to develop SOAP Web services (not into rpm and deb package)
PEAR Mail_MIME 1.8.9 BSD Yes NuSoap dependency
ParseDown 1.6 MIT License Yes Markdown parser
PCLZip 2.8.4 LGPL-3+ Yes Library to zip/unzip files
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.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
@ -51,7 +52,7 @@ Ace 1.4.14 BSD Yes
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

698
ChangeLog
View File

@ -3,124 +3,523 @@ English Dolibarr ChangeLog
--------------------------------------------------------------
***** ChangeLog for 18.0.0 compared to 17.0.0 *****
WARNING:
Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
* The deprecated method escapeunderscore() of database handlers has been removed. You must use escapeforlike instead.
* The method nb_expedition() has been renamed into countNbOfShipments()
***** ChangeLog for 17.0.0 compared to 16.0.0 *****
For users:
---------------
NEW: Minimal PHP version is now PHP 7.0 instead of PHP 5.6
NEW: #21780 Add pid field to Cronjob class and store PID on job execution
NEW: #19680 Add option PRODUCT_ALLOW_EXTERNAL_DOWNLOAD to automatically have uploaded files shared publicly by a link
NEW: #20650 can move the checkbox column on left (experimental option MAIN_CHECKBOX_LEFT_COLUMN)
NEW: #21000 Added columns 'alias_name' on project, supplier invoice, supplier order, supplier proposals and task list
NEW: #21395 Added option for dark theme mode in display - color and theme
NEW: #21397 added option to auto define barcode numbers for third-parties in barcode module setup
NEW: #21399
NEW: #21442 Enhancement of module builder init
NEW: #21654 add bank account number used on invoices for debit
NEW: #22048 Added notes to productlot module
NEW: #22298 Bank - Add salaries & vat in the tab of planned entries of a bank account
NEW: #22328
NEW: #22424
NEW: #22500 member module set up made easier
NEW: #22527 projects and thirdparties can be viewed as conversation ("Message" view), like events/agenda.
NEW: #22546 can now set user supervisors using mass action in htdocs/user
NEW: #22594 can chose if VAT ID is unique or not for third parties
NEW: #22622 all partnerships displayed on tab partnership of a thirdparty and member
NEW: #22676 massaction for updating product prices
NEW: #22735 Massaction to affect users on projects
NEW: #25594 can chose if VAT ID is unique or not for third parties
NEW: #4482 adding js to hide/show advanced option on the export data page
NEW: Accountancy - Add a graphic option to enable lettering function - FPC21
NEW: Accountancy - Add a way to clean some words when you generate thirdparty accounting account
NEW: Accountancy - Added an option during export to export or not the lettering FPC21
NEW: Accountancy - Manage supplier deposit with specific account
NEW: Accountancy - Model Digitaria - Add a way to clean some words when you generate thirdparty accounting account FPC22
NEW: Add a constant to disallow modification of the product reference.
NEW: Add a method doAutoRenewContracts that can be used as a cron task.
NEW: Add " as enclosure by default for CSV export. Keep removing CR/LF.
NEW: add attached file in presend email form of thirdparty card
NEW: Add a way to enter LICENSE file content in property of website
NEW: Add badge in admin extrafields setup
NEW: add constant PROPAL_BYPASS_VALIDATED_STATUS
NEW: Add date event (!= date project) and location on event organization
NEW: Add employment anniversary in birthday box
NEW: Add extrafield type "IP" to store IP addresses
NEW: Add fail2ban rules examples to limit access to /public pages
NEW: Add filter "Product subject to lot/Serial" in stock per lot/serial
NEW: Add hidden option MAIN_EMAIL_SUPPORT_ACK to restore Email ack checkbox (feature abandonned by mailers)
NEW: Add link to create an element from the category page
NEW: add margin infos to takepos invoice lines
NEW: Add max size send for "backup and link to mail" option
NEW: Add method httponly_accessforbidden()
NEW: Add more advices into the Setup security page
NEW: Add new global variable for keeping the previous signature information on proposale (case of reopen a proposale)
NEW: Add objectLink on expedition
NEW: Add oldcopy to Ticket so triggers intercepting TICKET_MODIFY have access to old values of the updated properties
NEW: Add option FICHINTER_ALLOW_EXTERNAL_DOWNLOAD
NEW: Add option --force on CLI cron_run_jobs.php
NEW: Add option "Show price on the generated documents for receptions"
NEW: Add performance index (name for company and contact) and llx_bank_url(url_id)
NEW: Add picto property on sub-module for password generation
NEW: add redirect on action confirm addconsumedline and addproduceline
NEW: Add a new advanced permission "read price"
NEW: Add substitution key __SENDEREMAIL_SIGNATURE__
NEW: Add the referrer-policy to "same-origin" by default on all public pages.
NEW: Add the SMTP header References on ticket email created by email
NEW: Add the thirdparty column to the time list (projet/tasks/time.php)
NEW: Add trigger to record the event of sending an email from a project #20912
NEW: Allow download link option in module configuration (propal,invoice,supplier proposal, order)
NEW: Bank - Add salaries & vat in tab planned entries
NEW: Bulk action to remove a category in list/search website pages
NEW: Can copy/paste images into emails sent.
NEW: Can edit label of an emailing even once sent
NEW: Can edit property css, cssview, csslist on extrafields
NEW: Can enter the unit price including the vat
NEW: Can invoice task time per different services
NEW: Can join several files by default on email form
NEW: Can send an email on scheduled job error
NEW: Can set a commercial discount by entering amount including VAT
NEW: Can set a monthly frequency (or multiple) in cron tasks.
NEW: Can set start and end dates and comment on button "Activate all services"
NEW: can sort and preselected best supplier price
NEW: Can use products categories to make inventory
NEW: Change filter type on tickets list into a multiselect combo
NEW: conf TIMESPENT_ALWAYS_UPDATE_THM, when it's on we always check current thm of user to update it in task time line
NEW: constant PROPAL_NEW_AS_SIGNED
NEW: show date delivery planned on orders linked to company and product
NEW: Default values in extrafields are not more limited to 255 char.
NEW: display currency in takepos menu
NEW: Enable online signature for interventions
NEW: Encrypt all sensitive constants in llx_const
NEW: extrafield price with currency
NEW: filter on reception dates (from / to) in cheque paiement card
NEW: Contracts: Default template of contract is not mandatory
NEW: Contracts: Manage Position (Rank) on Contract Lines
NEW: EMail-Collector: add IMAP port setting
NEW: EMail-Collector: add a button "Test collect"
NEW: Members: default_lang for members
NEW: Members: Table of membership types
NEW: Members: add free membership amounts at the membership type level
NEW: Projects: add author on list
NEW: Proposals: show delivery mode on PDF for proposals
NEW: Reception: add a from/to on search on date field
NEW: TakePOS: Header Scroll in TakePOS
NEW: TakePOS: add price to product box in TakePOS
NEW: TakePOS: add setup parameters, can setup terminal name
NEW: TakePOS: support of Stripe Terminal with TakePOS
NEW: TakePOS: Receipt preview in TakePOS setup
NEW: TakePOS: different product list on smartphone
NEW: Website: can delete a whole website if disabled
NEW: Website: can remove a website template
NEW: Website: can set header "Strict-Transport-Security" in web sites.
NEW: Website: can switch status of website and page from the website toolbar
NEW: Website: Templates of websites are now directories and not zip into core repo
NEW: Website: add 4 other templates in website module
NEW: If we select another view list mode, we keep it
NEW: Init module bookcal
NEW: Introduce dolEncrypt and dolDecrypt to be able to encrypt data in db
NEW: Invoice - Add french mention on pdf when vat debit option is on
NEW: invoice export : add accounting affectation
NEW: label on products categories filter
NEW: The link "add to bookmark" is always on top in the bookmark popup
NEW: MAIN_SEARCH_CATEGORY_PRODUCT_ON_LISTS const to show category customer filter
NEW: Make module WebservicesClient deprecated. Use module WebHook instead.
NEW: manage no email with thirdparties (better for GDPR)
NEW: Manage VAT on all lines on purchases cycle
NEW: manage virtual stock at a future date
NEW: On a bank reconciled line, we can modify the bank receipt
NEW: On a form to send an email, we show all emails of all contacts of object
NEW: Option PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT showing wh on PDF
NEW: Option PRODUIT_DESC_IN_FORM accept (desktop only or +smartphone)
NEW: Page for mass stock transfer can be used with no source stock
NEW: parent company column and filter in invoice and order list
NEW: Add show "Sales rep" option for PDF
NEW: Picto for shared link is clickable
NEW: possibility to select scopes with checkbox for Oauth tokens
NEW: private and public note on user, thirdparty and contact list
NEW: product categories filter on inventory list
NEW: Product supplier price: autofill default supplier VAT
NEW: Public counters feature
NEW: Start a simple support of recurrent events on agenda
NEW: Resize parent company column in order list
NEW: Saved token of OAUTH module are now encrypted into llx_oauth_token
NEW: Save one click to select on delivery ack, on emails.
NEW: scheduled job to send unpaid invoice reminder can now use the cc and bcc from email template
NEW: set thirdparty type with company modify trigger
NEW: Show also scheduled task never finished in scheduled task widget
NEW: show badge with number of extrafields in setup
NEW: show category tree in sellist and chkbxlst for common object
NEW: Show picto and color into combo for selection of tags
NEW: show product label on inventory
NEW: show sell-by and eat-by dates only if not empty
NEW: show SellBy/EatBy dates for each batch product in shipment card
NEW: skip accept/refuse process for proposals (option PROPAL_SKIP_ACCEPT_REFUSE)
NEW: experimental SMTP using PhpImap allowing OAuth2 authentication (need to add option MAIN_IMAP_USE_PHPIMAP)
NEW: can substitue project title in mail template
NEW: Supplier order list - Add column private and public note
NEW: Support IP type in extrafields
NEW: The purge of files can purge only if older than a number of seconds
NEW: Update ActionComm type_code on email message ticket
NEW: VAT - Admin - Add information on deadline day for submission of VAT declaration
NEW: expand/collapse permissions on user permission page
NEW: Add the target to select attendees of event for emailings
Localisation:
NEW: adding JAPAN Chart-of-Account and regions/departments
NEW: adding NIF verification for Algeria
Modules
NEW: Experimental module Asset
For developers or integrators:
------------------------------
NEW: ModuleBuilder can generate code of class from an existing SQL table
NEW: #20912 Add trigger to record the event of sending an email from a project
NEW: #21750 Added "Get lines and Post lines from BOM" at the REST Service
NEW: #22370 Modulebuilder supports 'alwayseditable' (like extrafields)
NEW: Removed completely the need for the library adodbtime
NEW: hook on agenda pages
NEW: hook to complete payment in TakePOS
NEW: hook "changeHelpURL" to modify target of the help button
NEW: hook formConfirm on action comm card
NEW: hook to modify supplier product html select
NEW: Add new hook for show virtual stock details on product stock card
NEW: Add new hooks for actioncomm
NEW: conf->global->SYSLOG_FILE_ONEPERSESSION accept a string
NEW: translate for contact type API, setup/ticket API, shipping method API
NEW: All ajax pages have now a top_httphead()
NEW: support multilang in Civilities API
NEW: Add API for the partnership module
NEW: Add "Get lines and Post lines from BOM" in the API
NEW: Replace fk_categories_product with categories_product in inventory
NEW: Rewrite of SQL request. Removed the join on category (for filter on categ), replaced with a EXISTS/NOT
WARNING:
Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
* Minimal PHP version is now PHP 7.0 instead of PHP 5.6
* 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.
* All functions fetch_all() have been set to deprecated for naming consitency, use fetchAll() instead.
* Code standardization: '$user->rights->propale' is now '$user->rights->propal' everywhere.
* Deprecated method set_billed() on shipment and reception class has been removed. Use setBilled() instead.
* Tables llx_prelevement_facture and llx_prelevement_facture_demande have been renamed into llx_prelevement and llx_prelevement_demande.
* Rename MAIN_LIST_ALLOW_NOTES into MAIN_LIST_HIDE_NOTES and rename MAIN_LIST_ALLOW_PRIVATE_NOTES into MAIN_LIST_HIDE_PRIVATE_NOTES
* Rename the substitution for project label instead of project title in substitution variables
***** ChangeLog for 16.0.4 compared to 16.0.2 *****
FIX: Amount of localtax1 and 2 not correctly save on purchase order (the rate was saved instead)
FIX: #20415
FIX: #21280
FIX: #23008
FIX: #22271
FIX: #22837
FIX: #23019 Impossible to add task times to an existing draft invoice
FIX: #23072
FIX: #23087
FIX: #23115
FIX: #23116
FIX: #23281
FIX: bad selection of barcode numbering module
FIX: Can't see all time spent by all user
FIX: CI
FIX: CommonObject - showOptionals - Display blank td when MAIN_VIEW_LINE_NUMBER is enabled and action is confirm_valid
FIX: Documents API inconsistency
FIX: #23075
FIX: #23117
FIX: get multicurrency infos of propal when create order from propal with "WORKFLOW_PROPAL_AUTOCREATE_ORDER" conf
FIX: Give predictable order to inventory lines
FIX: include class multicurrency
FIX: methods declaration (backport fix 67b9a7dc07d708231d12b5e58800334d4a01ef98)
FIX: multicurrency_tx and not currency_tx
FIX: PGSQL Integer type does not have a free length
FIX: Product list in setup.php in new Module
FIX: propal and order stats broken on Tag+User(retricted customer list)
FIX: saving of numbering module for jobs
FIX: Stickler
FIX: travis
***** ChangeLog for 16.0.3 compared to 16.0.2 *****
FIX: $sign is useless
FIX: #18304 Member subscription confirmation email sent even if mandatory fields are missing
FIX: #19828
FIX: #19877
FIX: #22509 default value on integer fields don't retrieve by setSaveQuery
FIX: #22786
FIX: #22813
FIX: #22824 Accountancy - Journal - Search on subledger when list of subledger is disabled
FIX: Backup using the low memory mode
FIX: Bankaccounts API fetch with 'id' and 'socid'
FIX: base64_decode should be forbiden in dol_eval
FIX: Broken Permissions check, $object is null.
FIX: compute next value when year is on one digit for reset counter
FIX: copy same behaviour in other accountancy files
FIX: Fix the position of the verification condition of the test field in case of multi entities
FIX: for #22882
FIX: for #22952
FIX: merge errors on mailing card
FIX: PaymentBankTransfer Type page management with Select and Input on create.php
FIX: remove not initialized variable
FIX: SQL request parenthesis
FIX: Use the Hook addMoreActionsButtons resPrint
FIX: Wrong Extrafields Element For Assets
***** ChangeLog for 16.0.2 compared to 16.0.1 *****
FIX: 16.0 - computed extrafields are not displayed if the object has no other extrafields
FIX: #22538
FIX: Accountancy - Review of Winfic - eWinfic - Winsis compta export format
FIX: add loadRoleMode on getlinearray
FIX: Autosearch on takepos was broken
FIX: avoid access forbidden with numeric ref
FIX: avoid error, check of product fetch is already check before
FIX: avoid error, fetch of product is mandatory (by id or by ref)
FIX: avoid unnecessary multiple calculation (#22637)
FIX: bug on selected value for select_bom() function
FIX: can not set prospect status "Do not contact"
FIX: change in the communication status of the prospect
FIX: check $id, already checked before
FIX: closed warehouse for shipping
FIX: extrafields_add tpl for stock movement
FIX: the request SQL for transversal user, the join on usergroup table must be with getEntity('usergroup')
FIX: Import of contact when there is duplicate thirdparties
FIX: Import of socialnetwork field
FIX: input selector is wrong with PRODUCT_LOAD_EXTRAFIELD_INTO_OBJECTLINES usage
FIX: install wizard error management
FIX: just add integer
FIX: Missing $object for online signature link build
FIX: missing quote
FIX: only modify hidden checkbox/multislected extrafields on update if they are provided in request
FIX: php doc
FIX: private message ticket become public if edit action
FIX: remove > 0 and -1
FIX: remove db object to avoid error with postgresql
FIX: Search ambigous field on MO list
FIX: Search on social networks
FIX: Subscription must be stopped when max of attendees reached.
FIX: supplier price update: missing error reporting
FIX: travis & stickler feedbacks
FIX: we must be able to select only bom of a specific product + several fixes on select_bom() function
FIX: wrong perm check
FIX: wrong typo, remove quote
FIX: wrong var typo
***** ChangeLog for 16.0.1 compared to 16.0.0 *****
FIX: #16476 on massaction the pdf generation is not using the t…
FIX: #21416 Filter tag no-categorie in members
FIX: #21543
FIX: #21799 inactive companies shall not be selectable for new proposals, orders and invoices
FIX: #21859 Don't show html balise on list for private/public note
FIX: #22164
FIX: #22241
FIX: #22263 Accountancy - Account number expected in place of a rowid on parent account on export
FIX: #22264 Accountancy - Translation on chart of accounts export
FIX: #22265 Accountancy - Account number expected in place of a rowid on export
FIX: #22334
FIX: #22360
FIX: #22379 creating events on supplier order
FIX: #22382 Error on length of supplier reference
FIX: #22386 IBAN not mandatory for International Export Countries
FIX: #22440 Lang Key "UserAccountNotDefined" is missing
FIX: #22482
FIX: #22507
FIX: Accountancy - Some manuals operations are displayed in subledger
FIX: API reception return error 500
FIX: avoid override initial message ($this instead $object)
FIX: avoid some warnings (php8+)
FIX: Bad backtopage and CSRF on link for ticket message
FIX: bad closing select
FIX: broken feature, wrong fk_parent_line after cloning object
FIX: Column label
FIX: compatibility if javascript not actived
FIX: compatibility with Mysql <= 5.7
FIX: contact deletion: execute trigger before really deleting
FIX: CronJob sendBackup
FIX: CSRF + lost value of constant after use save button
FIX: CSS
FIX: data integrity for llx_delivery table
FIX: default value for partnership status
FIX: deletion of the MO_CHILD link
FIX: Dictionary - Display error on cache_vatrates
FIX: Dolibarr#16476 version 2a
FIX: Duplicate creation of invoice when closing shipment linked to order
FIX: Duplicate in list when filtering on categories
FIX: extrafields with value '0' was ''
FIX: filters lost when sorting on productMargin and customerMargins
FIX: fk_expedition in $line can be usefull for triggers
FIX: Import in upgrade when using a socialnetwork field.
FIX: input hidden with fk_product of line on mo production can be usefull
FIX: inventory code must be different at each transation
FIX: inventory total columns
FIX: Issue #16476 on massaction the pdf generation is not using the thirdparty language settings
FIX: Linked object agenda card
FIX: missing check if category module is enabled
FIX: missing check if incoice as a payment (wrong status)
FIX: missing class "societe" when create another object with workflow
FIX: missing error message if image size too large
FIX: Missing reposition
FIX: missing the management of a constant in the Ticket config
FIX: Missing token in different URLs links
FIX: @ must be allowed into dol_eval to allow rules including external module string 'abc@def'
FIX: - php V8 get number doc saphir
FIX: - php V8 propal index last draft
FIX: Preview button position on documents list (case when the file is too long)
FIX: Project - on global view, missing display of ref customer
FIX: Protection against bad value into accurancy setup
FIX: reading of trackid in emailcollector (when on recipient suffix)
FIX: recruitment linked files
FIX: Remove use of code we should not have
FIX: Restore the option MAIN_OPTIMIZEFORTEXTBROWSER
FIX: Rich text is not diplayed
FIX: same thing in deleteline
FIX: Supplier Reference is lost when page breaks
FIX: support of array parameters in "add to bookmark" feature.
FIX: Test that web dir is correct in install
FIX: the shipment PDF was using the full size logo instead of small
FIX: Token Error : delete stock transfer
FIX: ToOfferALinkForOnlinePayment not translated
FIX: tooltip of technical tables added of a module
FIX: wrong result check when update expensereport line
***** ChangeLog for 16.0.0 compared to 15.0.0 *****
For users:
---------------
NEW: PHP 8.1 compatibility
NEW: PHP 8.0 and 8.1 compatibility:
Warning!! Application works correctly with PHP 8.0 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 QRCode on PDFs
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: #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 we generate a transaction with a deposit invoice
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: Module Recruitment - Add a public page with all list of open job positions.
NEW: Module Recruitment - Add a tab with list of application on the jobposition file.
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 constant to hide categories in TakePos
NEW: Add constant to show category description in TakePos
NEW: Add constant to show only the products in stock in TakePos
NEW: Add entity filter in exports
NEW: Add configuration for text color of button action
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 margin info in proposal and order list
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 boder 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 status "Obsolete" to KM articles
NEW: Add private and public notes on tax files
NEW: Add substitutions "user numbers"
NEW: Add the possibility to add sub-BOMs to BOM
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: Availibility dictionnary has a new column unit and number
NEW: barcode rule to insert product in takepos
NEW: Can change value of AWP during the inventory
NEW: Backup tool has an "lowmemory" option for mysqldump on large database
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 set the parent company during the creation of thirdparty (action=add of societe/card.php)
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: create third-party with contact if not found on public ticket
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: 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: display errors in a message box after generating documents
NEW: Display physical and virtual stock of the products when creating OF from a BOM
NEW: Display product ref in "Object link" product tab for BOM
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: Exports - add entity filter in exports
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: MAIN_MAIL_AUTOCOPY_TO can accept several email and special keys
NEW: MAIN_SEARCH_CAT_OR_BY_DEFAULT const for search by category
NEW: Mass action "Close shipments"
NEW: Module website now supports the multicompany module
NEW: More mode for THEME_TOPMENU_DISABLE_IMAGE (2, 3, ...)
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: Add option to move checkbox column as first column on Thirdparty list (only few screens)
NEW: Add tabs for nets Bom
NEW: on redirect of page in website module, GET parameters are kept.
NEW: optional display warning icons on ticket list
NEW: option to default check "notify tier at creation" in ticket module
NEW: option update prices on proposal cloning
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: New permission to report time on timesheet.
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: Orders - support user_modif in order
NEW: Products - add massaction "Edit Extrafield" for Product
NEW: Products - List - add thumbnail field in product list
NEW: Products - Statistics - can filter on a thirdparty
NEW: Projects - add filter "opportunity status" on statistics of projects.
NEW: Proposals - option update prices on proposal cloning
NEW: Proposals - List - add column date of Signature on proposal list
NEW: SEPA XML - option to place payment Type Info at Credit transfer Transaction level
NEW: Show number of votes into the label of tab "Results" of a survey
NEW: Show product reference in Takepos
NEW: Some core tables are created only at module activation
NEW: split consumption line on MO
NEW: stock filter in reassort lists
NEW: stock limit in stock export CSV
NEW: Sub-bom are availables
NEW: Stocks - stock filter in reassort lists
NEW: Stocks - stock limit in stock export CSV
NEW: Stocks - Inventory - can change value of AWP during the inventory
NEW: Supplier order - Show ref supplier of reception in linked object block
NEW: support user_modif in order
NEW: TakePos - pagination on search results
NEW: The backup tools has an "lowmemory" option for mysqldump on large database
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: Themes - add param color button action
NEW: Themes - Change in theme colors does not need to use the refresh button
NEW: Themes - more modes for THEME_TOPMENU_DISABLE_IMAGE (2, 3, ...)
NEW: Themes - MD - add param border table for md theme
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 - allow a Ticket to be automatically marked as read when created from backend
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 'reposition' class works on ajax constantonoff that make redirects
NEW: Thirdparty - Add rules "customer accountancy code" is mandatory to validate invoice
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: Ticket triggers: allow to automatically send messages on new tickets
NEW: Accountancy - Add hidden feature for accounting reconciliation
NEW: Can store the session into database (instead of beeing managed by PHP)
NEW: Added MMK currency (Myanmar Kyat)
NEW: On a form to send an email, we show all emails of contacts of object
Modules
NEW: Module Partnership Management
NEW: Experimental module Event Organization Management
Modules state
NEW: Module Partnership Management - stable
NEW: Module Event Organization Management - stable
For developers or integrators:
@ -128,48 +527,46 @@ 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: update rank line is possible on API for customer invoices, sales orders and supplier invoice
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: Hook getNomUrl available everywhere in tooltip of ref links
NEW: Identification of tr is possible with by attribute data-id on some pages
NEW: Import with select boxes V2
NEW: Can update rank of invoice, proposal and order lines with API update
NEW: Can use current entity filter on 'chkbxlst'
NEW: Creation of the function select_bom() used to display bom select list
NEW: add printFieldListWhere hook in product reassort card
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: API Proposals - Add POST lines
NEW: API REST filter states by country
NEW: Add option INVOICEREC_SET_AUTOFILL_DATE_START/END
NEW: Add option MAIN_API_DEBUG to save API logs into a file
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: Add API to get a template invoice
NEW: Standardize a lot of code.
NEW: #20736 Allow extrafields SQL filters on REST API product lookup
NEW: #19294 implement detailed timespent in task of project API
NEW: Add a protection into PHPunit to avoid to forget a var_dump
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: 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: Add hooks: selectContactListWhere hook, selectThirdpartyListWhere hook
NEW: TakePos - add hooks complete product display
NEW: TakePos - add hooks for cart display
NEW: TakePos - add hooks to complete ajax return array
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
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 doaction in takepos invoice
NEW: Add Hook for Notif
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
@ -181,15 +578,28 @@ 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
* 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.
* 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 renamed with name XXX_MODIFY for code consistency purpose.
* Rename build_path_from_id_categ() into buildPathFromId() and set method to private.
@ -197,8 +607,82 @@ Following changes may create regressions for some external modules, but were nec
* 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'
* Because the module Resources highly linked to the Agenda module, the menu for Resources module has been moved into top menu Agenda.
***** 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 *****
@ -332,7 +816,7 @@ For users:
NEW: Online proposal signature
NEW: Can define some max limit on expense report (per period, per type or expense, ...)
NEW: Provide a special pages for bookmarks and multicompany for a better use of some mobile applications (like DoliDroid)
NEW: Provide a special pages for bookmarks and multicompany for a better use of some mobile applications (like DoliDroid)
NEW: Allow the use of __NEWREF__ to get for example the new reference a draft order will get after validation.
NEW: Add option to disable globaly some notifications emails.
NEW: #18401 Add __NEWREF__ subtitute to get new object reference.
@ -381,7 +865,7 @@ NEW: can enable/disable external calendar by default
NEW: Can hide sender name on PDF documents
NEW: Can select lot from a combo list of existing batch numbers (in MRP consumtion)
NEW: Can set the default BOM on a product
NEW: Can set/unset the usual working day of the week (friday, saturday, sunday)
NEW: Can set/unset the usual working day of the week (friday, saturday, sunday)
NEW: Can show progression of task into combo list of tasks
NEW: can upload the odt file for the product doc template
NEW: Contract - Add From/to input on search date
@ -445,7 +929,7 @@ For developers:
API:
NEW: #18319 REST API - Shipment: Add 'close' action / endpoint / POST method.
NEW: add API /approve and /makeOrder for purchase orders
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
@ -480,21 +964,23 @@ 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
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
* ALL EXTERNAL MODULES THAT WERE NOT CORRECTLY DEVELOPPED WILL NOT WORK ON V15 (All modules that forgot to manage the security token field
into forms will be broken. The security token field is expected since Dolibarr v9 but a lot of external modules did not implement it).
* Update hook 'printOriginObjectLine', removed check on product type and special code. Need now reshook.
* Old deprecated module "SimplePOS" has been completely removed. Use module "TakePOS" is you need a Point Of Sale.
* The method static ActionComm::getActions($db, ...) is no more static. Use $actioncomm->getActions(...) instead (without $db param).
* The method static ActionComm::getActions($db, ...) is no more static. Use $actioncomm->getActions(...) instead (without $db param).
* The 'action=delete&file=...' has been replaced with 'action=deletefile&file=...' to avoid confusion with deletion of object lines.
* Method getDictvalue has been renamed into getDictionaryValue to match camel case rule.
* To execute shell or command line command, your code must never use method like exec, shell_exec, popen, .. but must use the built-in
method executeCLI() available into core/class/utils.class.php
* To execute shell or command line command, your code must never use method like exec, shell_exec, popen, .. but must use the built-in
method executeCLI() available into core/class/utils.class.php
* Class file expeditionbatch.class.php renamed to expeditionlinebatch.class.php
* ExpeditionLineBatch::fetchAll is not static anymore and first parameter $db is removed
* ExtraFields->showOutputField parameter 4 'extrafieldsobjectkey' is now required
* CommonObject method add_object_linked now sets targettype to 'mymodule_myobject' instead of 'myobject',
* CommonObject method add_object_linked now sets targettype to 'mymodule_myobject' instead of 'myobject',
you can use hook 'setLinkedObjectSourceTargetType' to set your usual targettype
@ -783,10 +1269,10 @@ For users:
----------
NEW: Module Recruitment to follow application to job positions is now stable.
NEW: Feature to make Stock Inventories
NEW: Several security issues after a second private bug hunting campaign.
NEW: Several security issues after a second private bug hunting campaign.
NEW: A lot of fix into english text after a small proofreading campaign (still not perfect, but really better)
NEW: All main menu entries are using the picto of the module
NEW: Add a copy to clipboard button on some fields
NEW: Add a copy to clipboard button on some fields
NEW: Add an example of scheduled job to send email reminder for unpaid invoices
NEW: Add some color and picto for the direction of movement
NEW: add the column "Channel" into the list of orders
@ -857,7 +1343,7 @@ NEW: can show the leave dates/holidays on the agenda view
NEW: Support color for types of event
Bank
NEW: Bank Entries : display user linked to a salary or a taxes
NEW: Bank Entries : display user linked to a salary or a taxes
NEW: Add bulk actions for Bank Transfer
ECM/GED
@ -880,7 +1366,7 @@ NEW: option to automatically create a login/user when a new subscription of a me
NEW: option to select membership type on the online payment page for membership subscription or renewal
Products
NEW: Add price min and price min including tax into product export
NEW: Add price min and price min including tax into product export
NEW: Add a ref in product customer price
NEW: customer ref for product customer prices
NEW: Set status of all variants when changing status of parent
@ -933,8 +1419,8 @@ NEW: add option in Workflow module to set a shipment as closed
for Admins
NEW: Add a security center page with all information and advices related to the security of your instance
NEW: Add a performance center page with all information and advices related to the performance of your instance
NEW: Add a security center page with all information and advices related to the security of your instance
NEW: Add a performance center page with all information and advices related to the performance of your instance
Modules
NEW: Module Recruitment is now stable
@ -980,7 +1466,7 @@ NEW: API get the list of product ids only
NEW: add link to OpenAPI specifications XML file in REST API module setup: swagger.json file can be included into external tools like redoc
NEW: add native compression in REST APIs
NEW: Product Variants API, add variant stock to response by parameter
NEW: Product API route added to get product stock and product with or without variants #13739 #17390
NEW: Product API route added to get product stock and product with or without variants #13739 #17390
Hooks
NEW: hook printFieldListTitle for cabyprodserv.php
@ -1005,8 +1491,8 @@ Following changes may create regressions for some external modules, but were nec
* Removed deprecated substitution key __REFCLIENT__ (replaced with __REF_CLIENT__)
* Removed constant MAIN_COUNTRIES_IN_EEC. You can now set if country is in Europe or not from the dictionary of countries.
* v14 seems to work correctly on PHP v8 but it generates a lot of verbose warnings. Currently, v14 i snot yet officialy supported with PHP 8.
* To execute shell or command line command, your code must never use method like exec, shell_exec, popen, .. but must use the built-in
method executeCLI() available into core/class/utils.class.php
* To execute shell or command line command, your code must never use method like exec, shell_exec, popen, .. but must use the built-in
method executeCLI() available into core/class/utils.class.php
***** ChangeLog for 13.0.5 compared to 13.0.4 *****
@ -1233,7 +1719,7 @@ NEW: Module "Credit transfer SEPA" to manage payment of vendors using bank credi
NEW: Module Intracomm report
NEW: Module Reception (for a more accurate management of your receptions) moved from experimental to stable.
NEW: Module Recruitment to manage Job position and applications.
NEW: Several security issues after a private bug bounty campaign.
NEW: Several security issues after a private bug bounty campaign.
NEW: Accountancy - add chart of sub accounts
NEW: Accountancy - add options to disable binding on sales, purchases & expense reports independently of the modules
NEW: Accountancy balance - add a menu entry to show subtotal by group
@ -1369,7 +1855,7 @@ NEW: show user on external calender events (when found)
NEW: subject title with company name instead of application title in ticket message
NEW: Support for Samba4 AD
NEW: TakePOS appearance tab with more visual parameters
NEW: TakePOS add alert before changing thirdparty
NEW: TakePOS add alert before changing thirdparty
NEW: TakePOS add third order printer
NEW: TakePOS can change thirdparty with barcode scan
NEW: TakePOS can create a thirdparty customer from TakePOS frontend
@ -1380,9 +1866,9 @@ NEW: TakePOS display resiliate status for members
NEW: TakePOS Gift Receipt
NEW: TakePOS multicurrency compatibility
NEW: TakePOS multicurrency total
NEW: TakePOS print payment method and change
NEW: TakePOS print payment method and change
NEW: TakePOS restrict thirdparty to customer
NEW: TakePOS show available stock
NEW: TakePOS show available stock
NEW: TakePOS Weighing Scale compatibility with TakePOS connector #14725
NEW: Thirdparty Import new fields: mother company,outstanding debt limit,bank account,incoterms
NEW: Thirdparty module : box on customer/supplier tab for invoice outsantding amount late
@ -1395,8 +1881,8 @@ NEW: VAT report - Invert constant to show by default zero VAT in reports
NEW: website page fields selection
NEW: website - global header of a website can also have dynamic content
NEW: when creating a user from a member linked to a thirdparty, you can choose to create it as external or internal user
NEW: add clone button on miscellaneous payment
NEW: add option to put the product label in bold in the PDF templates if configured #15065
NEW: add clone button on miscellaneous payment
NEW: add option to put the product label in bold in the PDF templates if configured #15065
NEW: add option "If the feature to manage kits of module Stock is used, show details of subproducts of a kit on PDF."

View File

@ -56,6 +56,10 @@ Vous pouvez aussi utiliser un serveur Web et une base de données prise en charg
Pour mettre à jour Dolibarr depuis une vieille version vers celle ci:
- Faites une sauvegarde de votre instance [voir ce tutorial](https://wiki.dolibarr.org/index.php/Installation_-_Upgrade#Upgrade_Dolibarr)
- Vérifiez que la nouvelle version est compatible avec la version PHP de votre serveur [voir PHP support](https://wiki.dolibarr.org/index.php/Releases).
- Ecrasez les vieux fichiers dans le vieux répertoire 'dolibarr' par les fichiers
fournis dans ce nouveau package.

View File

@ -81,7 +81,7 @@ If you don't have time to install it yourself, you can try some commercial 'read
Dolibarr supports upgrading, usually without the need for any (commercial) support (depending on if you use any commercial extensions). It supports upgrading all the way from any version after 2.8 without breakage. This is unique in the ERP ecosystem and a benefit our users highly appreciate!
- At first make a backup of your Dolibarr files & then [see](https://wiki.dolibarr.org/index.php/Installation_-_Upgrade#Upgrade_Dolibarr)
- Check that your installed PHP version is supported by the new version [see PHP support](./doc/phpmatrix.md).
- Check that your installed PHP version is supported by the new version [see PHP support](https://wiki.dolibarr.org/index.php/Releases).
- Overwrite all old files from 'dolibarr' directory with files provided into the new version's package.
- At first next access, Dolibarr will redirect you to the "install/" page to follow the upgrade process.
 If an `install.lock` file exists to lock any other upgrade process, the application will ask you to remove the file manually (you should find the `install.lock` file in the directory used to store generated and uploaded documents, in most cases, it is the directory called "*documents*").

View File

@ -6,9 +6,8 @@ This file contains some policies about the security reports on Dolibarr ERP CRM
| Version | Supported |
| ---------- | ---------------------- |
| <= 15.0.0 | :x: |
| >= 15.0.1+ | :white_check_mark: except CSRF attacks|
| >= 16.0.0 | :white_check_mark: |
| <= 16.0.2 | :x: |
| >= 16.0.3 | :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

@ -19,7 +19,6 @@ Depends: libapache2-mod-php5 | libapache2-mod-php5filter | php5-cgi | php5-fpm |
php-pear, php-mail-mime,
# php-tcpdf,
# libfpdf-tpl-php, php-fpdf,
# libphp-adodb,
# libnusoap-php,
# libphp-pclzip,
# Required javascript libraries

View File

@ -61,31 +61,6 @@ License: GPL-3+
------------------------------------------------------------
Files: htdocs/includes/adodbtime/*
Copyright: 2003-2005, John Lim
unknown, jackbbs
License: BSD-3-Clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
.
Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
.
Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
.
Neither the name of the John Lim nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
Comment:
Those files are not shipped in the binary package since we use
the library as packaged in "libphp-adodb".
------------------------------------------------------------
Files: htdocs/includes/ckeditor/*
Copyright: 2003-2012 CKSource - Frederico Knabben
License: GPL-2+

View File

@ -146,7 +146,6 @@ case "$1" in
#else
# File already exist. We add params not found.
#echo Add new params to overwrite path to use shared libraries/fonts
#grep -q -c "dolibarr_lib_ADODB_PATH" $config || [ ! -d "/usr/share/php/adodb" ] || echo "<?php \$dolibarr_lib_ADODB_PATH='/usr/share/php/adodb'; ?>" >> $config
##grep -q -c "dolibarr_lib_GEOIP_PATH" $config || echo "<?php \$dolibarr_lib_GEOIP_PATH=''; ?>" >> $config
#grep -q -c "dolibarr_lib_NUSOAP_PATH" $config || [ ! -d "/usr/share/php/nusoap" ] || echo "<?php \$dolibarr_lib_NUSOAP_PATH='/usr/share/php/nusoap'; ?>" >> $config
#grep -q -c "dolibarr_lib_ODTPHP_PATHTOPCLZIP" $config || [ ! -d "/usr/share/php/libphp-pclzip" ] || echo "<?php \$dolibarr_lib_ODTPHP_PATHTOPCLZIP='/usr/share/php/libphp-pclzip'; ?>" >> $config

View File

@ -31,7 +31,6 @@ $force_install_distrib='debian';
// - not removed from package (see rm in rules file),
// - declared into dependencies (see Depends in control file)
//$force_dolibarr_lib_TCPDF_PATH='';
//$force_dolibarr_lib_ADODB_PATH='/usr/share/php/adodb';
//$force_dolibarr_lib_GEOIP_PATH='';
//$force_dolibarr_lib_NUSOAP_PATH='/usr/share/php/nusoap';
//$force_dolibarr_lib_ODTPHP_PATHTOPCLZIP='/usr/share/php/libphp-pclzip';

View File

@ -89,7 +89,6 @@ override_dh_install:
rm -fr build/zip
# clean from all PHP embedded libraries (we use package dependencies instead)
# rm -fr htdocs/includes/adodbtime
# rm -fr htdocs/includes/geoip
# rm -fr htdocs/includes/nusoap
# rm -fr htdocs/includes/odtphp/zip/pclzip

View File

@ -1,2 +0,0 @@
htdocs/install/doctemplates/websites/website_template-corporate.zip
htdocs/install/doctemplates/websites/website_template-stellar.zip

View File

@ -0,0 +1,3 @@
# Force use of gzip compression by dpkg-buildpackage
compression = "gzip"
#compression-level = 9

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

@ -17,9 +17,9 @@ use Cwd;
my $dir = getcwd;
print "Current dir is: $dir\n";
print "Running dir for doxygen must be: $DIR\n";
#print "Running dir for doxygen must be: $DIR\n";
if (! -s $CONFFILE)
if (! -s "build/doxygen/$CONFFILE")
{
print "Error: current directory for building Dolibarr doxygen documentation is not correct.\n";
print "\n";
@ -30,7 +30,7 @@ if (! -s $CONFFILE)
exit 1;
}
$SOURCE="../..";
$SOURCE=".";
# Get version $MAJOR, $MINOR and $BUILD
$result = open( IN, "< " . $SOURCE . "/htdocs/filefunc.inc.php" );
@ -47,8 +47,8 @@ $version=$MAJOR.".".$MINOR.".".$BUILD;
print "Running doxygen for version ".$version.", please wait...\n";
print "cat $CONFFILE | sed -e 's/x\.y\.z/".$version."/' | doxygen $OPTIONS - 2>&1\n";
$result=`cat $CONFFILE | sed -e 's/x\.y\.z/$version/' | doxygen $OPTIONS - 2>&1`;
print "cat build/doxygen/$CONFFILE | sed -e 's/x\.y\.z/".$version."/' | doxygen $OPTIONS - 2>&1\n";
$result=`cat build/doxygen/$CONFFILE | sed -e 's/x\.y\.z/$version/' | doxygen $OPTIONS - 2>&1`;
print $result;

View File

@ -1,14 +1,17 @@
# Doxyfile 1.7.3
# Doxyfile 1.8.16
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
# doxygen (www.doxygen.org) for a project.
#
# All text after a hash (#) is considered a comment and will be ignored
# All text after a double hash (##) is considered a comment and is placed in
# front of the TAG it is preceding.
#
# All text after a single hash (#) is considered a comment and will be ignored.
# The format is:
# TAG = value [value, ...]
# For lists items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (" ")
# TAG = value [value, ...]
# For lists, items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (\" \").
#---------------------------------------------------------------------------
# Project related configuration options
@ -38,7 +41,7 @@ PROJECT_NUMBER = x.y.z
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = ../../build
OUTPUT_DIRECTORY = build
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
@ -114,7 +117,7 @@ FULL_PATH_NAMES = YES
# If left blank the directory from which doxygen is run is used as the
# path to strip.
STRIP_FROM_PATH = "../.."
STRIP_FROM_PATH = "/home/dolibarr/doxygen.dolibarr.org/"
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
# the path mentioned in the documentation of a class, which tells
@ -287,7 +290,7 @@ TYPEDEF_HIDES_STRUCT = NO
# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
# corresponding to a cache size of 2^16 = 65536 symbols
SYMBOL_CACHE_SIZE = 0
#SYMBOL_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
@ -448,7 +451,7 @@ GENERATE_TODOLIST = NO
# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.
GENERATE_TESTLIST = YES
GENERATE_TESTLIST = NO
# The GENERATE_BUGLIST tag can be used to enable (YES) or
# disable (NO) the bug list. This list is created by putting \bug
@ -487,7 +490,7 @@ SHOW_USED_FILES = YES
# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
# in the documentation. The default is NO.
SHOW_DIRECTORIES = YES
#SHOW_DIRECTORIES = YES
# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
# This will remove the Files entry from the Quick Index and from the
@ -571,7 +574,7 @@ WARN_FORMAT = "$file:$line: $text"
# and error messages should be written. If left blank the output is written
# to stderr.
WARN_LOGFILE = doxygen_warnings.log
WARN_LOGFILE = build/html/doxygen_warnings.log
#---------------------------------------------------------------------------
# configuration options related to the input files
@ -582,7 +585,7 @@ WARN_LOGFILE = doxygen_warnings.log
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = ../../htdocs ../../scripts
INPUT = htdocs scripts
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@ -611,7 +614,7 @@ RECURSIVE = YES
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
EXCLUDE = ../../build ../../dev ../../doc ../../document ../../documents ../../htdocs/conf/conf.php ../../htdocs/custom ../../htdocs/document ../../htdocs/documents ../../htdocs/includes
EXCLUDE = build dev doc document documents htdocs/conf/conf.php htdocs/custom htdocs/document htdocs/documents htdocs/includes htdocs/install/doctemplates
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
# directories that are symbolic links (a Unix filesystem feature) are excluded
@ -625,7 +628,7 @@ EXCLUDE_SYMLINKS = YES
# against the file with absolute path, so to exclude all test directories
# for example use the pattern */test/*
EXCLUDE_PATTERNS = */CVS/* *google* *pibarcode*
EXCLUDE_PATTERNS = */CVS/*
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@ -639,27 +642,27 @@ EXCLUDE_SYMBOLS =
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH = ../../htdocs/modulebuilder/template
#EXAMPLE_PATH = htdocs/modulebuilder/template
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
EXAMPLE_PATTERNS = *.php
#EXAMPLE_PATTERNS = *.php
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
# searched for input files to be used with the \include or \dontinclude
# commands irrespective of the value of the RECURSIVE tag.
# Possible values are YES and NO. If left blank NO is used.
EXAMPLE_RECURSIVE = NO
#EXAMPLE_RECURSIVE = NO
# The IMAGE_PATH tag can be used to specify one or more files or
# directories that contain image that are included in the documentation (see
# the \image command).
IMAGE_PATH = ../../doc/images
IMAGE_PATH = doc/images
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
@ -762,7 +765,7 @@ ALPHABETICAL_INDEX = YES
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
#COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all
# classes will be put under the same header in the alphabetical index.
@ -775,14 +778,16 @@ IGNORE_PREFIX =
# configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
# The default value is: YES.
GENERATE_HTML = YES
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
# it.
# The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_OUTPUT = html
@ -797,14 +802,14 @@ HTML_FILE_EXTENSION = .html
# standard header.
# Does not work with 1.7.3
#HTML_HEADER = doxygen_header.html
#HTML_HEADER = build/doxygen/doxygen_header.html
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
# Does not work with 1.7.3
HTML_FOOTER = doxygen_footer.html
HTML_FOOTER = build/doxygen/doxygen_footer.html
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
# style sheet that is used by each HTML page. It can be used to
@ -850,7 +855,18 @@ HTML_TIMESTAMP = YES
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
#HTML_ALIGN_MEMBERS = YES
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
# documentation will contain a main index with vertical navigation menus that
# are dynamically created via Javascript. If disabled, the navigation index will
# consists of multiple levels of tabs that are statically embedded in every HTML
# page. Disable this option to support browsers that do not have Javascript,
# like the Qt help browser.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_DYNAMIC_MENUS = NO
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
@ -858,7 +874,7 @@ HTML_ALIGN_MEMBERS = YES
# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
HTML_DYNAMIC_SECTIONS = YES
HTML_DYNAMIC_SECTIONS = NO
# If the GENERATE_DOCSET tag is set to YES, additional index files
# will be generated that can be used as input for Apple's Xcode 3
@ -1003,7 +1019,7 @@ QHG_LOCATION =
# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
# the help appears.
GENERATE_ECLIPSEHELP = YES
GENERATE_ECLIPSEHELP = NO
# A unique identifier for the eclipse help plugin. When installing the plugin
# the directory name containing the HTML and XML files should also have
@ -1035,7 +1051,7 @@ GENERATE_TREEVIEW = NO
# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
# and Class Hierarchy pages using a tree view instead of an ordered list.
USE_INLINE_TREES = NO
#USE_INLINE_TREES = NO
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
# used to set the initial width (in pixels) of the frame in which the tree
@ -1072,7 +1088,7 @@ FORMULA_TRANSPARENT = YES
# typically be disabled. For large projects the javascript based search engine
# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
SEARCHENGINE = NO
SEARCHENGINE = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a PHP enabled web server instead of at the web client
@ -1082,7 +1098,7 @@ SEARCHENGINE = NO
# full text search. The disadvances is that it is more difficult to setup
# and does not have live searching capabilities.
SERVER_BASED_SEARCH = NO
SERVER_BASED_SEARCH = YES
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
@ -1260,13 +1276,13 @@ XML_OUTPUT = xml
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_SCHEMA =
#XML_SCHEMA =
# The XML_DTD tag can be used to specify an XML DTD,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_DTD =
#XML_DTD =
# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
# dump the program listings (including syntax highlighting
@ -1431,7 +1447,7 @@ EXTERNAL_GROUPS = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
@ -1453,7 +1469,7 @@ CLASS_DIAGRAMS = NO
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
#MSCGEN_PATH =
# If set to YES, the inheritance and collaboration graphs will hide
# inheritance and usage relations if the target is undocumented
@ -1485,7 +1501,7 @@ DOT_NUM_THREADS = 0
# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
# containing the font.
DOT_FONTNAME = FreeSans.ttf
#DOT_FONTNAME = FreeSans.ttf
# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
# The default size is 10pt.
@ -1634,3 +1650,7 @@ GENERATE_LEGEND = YES
# the various graphs.
DOT_CLEANUP = YES
FULL_SIDEBAR = NO
HTML_EXTRA_STYLESHEET = build/doxygen/doxygen-awesome.css

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -9,3 +9,5 @@ The build of .exe files need to have some windows executable files already insta
If you have technical knowledge in web administration and plan to share your server instance (Apache, Mysql or PHP) with other projects than Dolibarr or want to use Dolibarr other components (PostgreSQL), you should not use this assistant and make a manual installation of Dolibarr on your existing server by downloading the standard package (.tgz or .zip file).
!!! See file ../makepack-howto.txt

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,7 +24,6 @@ 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=DoliCloud
@ -32,7 +31,7 @@ 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-2022 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
@ -101,16 +100,10 @@ Source: "build\exe\doliwamp\UsedPort.exe"; DestDir: "{app}\"; Flags: ignoreversi
; 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:\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,12 +118,10 @@ Source: "*.*"; DestDir: "{app}\www\dolibarr"; Flags: ignoreversion; Excludes: ".
; Config files
Source: "build\exe\doliwamp\dolibarr.conf.install"; DestDir: "{app}\alias"; 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;
@ -236,12 +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';
apacheVersion := '2.4.51';
phpVersion := '7.3.33' ;
mysqlVersion := '10.6.5';
smtpServer := 'localhost';
apachePort := '80';
@ -375,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.
@ -594,6 +582,17 @@ begin
end;
end;
if browser = 'iexplore.exe' then
begin
if FileExists (pfPath+'/Microsoft/Edge/Application/msedge.exe') then
begin
if MsgBox(CustomMessage('MicrosoftEdgeDetected'),mbConfirmation,MB_YESNO) = IDYES then
begin
browser := pfPath+'/Microsoft/Edge/Application/msedge.exe';
end;
end;
end;
if browser = 'iexplore.exe' then
begin
if FileExists (pfPath+'/Internet Explorer/iexplore.exe') then
@ -1027,7 +1026,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

@ -55,14 +55,24 @@ if (empty($argv[1])) {
$i=0;
$result=array();
while ($i < $argc) {
if (! empty($argv[$i])) {
parse_str($argv[$i]); // set all params $release, $includecustom, $includeconstant, $buildzip ...
if (!empty($argv[$i])) {
parse_str($argv[$i], $result); // set all params $release, $includecustom, $includeconstant, $buildzip ...
}
if (preg_match('/includeconstant=/', $argv[$i])) {
$tmp=explode(':', $includeconstant, 3); // $includeconstant has been set with previous parse_str()
if (!empty($result["release"])) {
$release = $result["release"];
}
if (!empty($result["includecustom"])) {
$includecustom = $result["includecustom"];
}
if (!empty($result["includeconstant"])) {
$includeconstants[$i] = $result["includeconstant"];
}
if (preg_match('/includeconstant=/', strval($argv[$i]))) {
$tmp=explode(':', $result['includeconstant'], 3); // $includeconstant has been set with previous parse_str()
if (count($tmp) != 3) {
print "Error: Bad parameter includeconstant=".$includeconstant."\n";
print "Error: Bad parameter includeconstant=".$result['includeconstant'] ."\n";
exit -1;
}
$includeconstants[$tmp[0]][$tmp[1]] = $tmp[2];
@ -71,7 +81,7 @@ while ($i < $argc) {
}
if (empty($release)) {
print "Error: Missing release paramater\n";
print "Error: Missing release parameter\n";
print "Usage: ".$script_file." release=autostable|auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
exit -1;
}

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`;
@ -612,7 +621,6 @@ if ($nboftargetok) {
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/nnnick/chartjs/scripts`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/nnnick/chartjs/src`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/nnnick/chartjs/test`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/nusoap/lib/Mail`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/nusoap/samples`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/php-iban/docs`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/sabre/sabre/*/tests`;
@ -623,7 +631,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`;
@ -670,7 +678,7 @@ if ($nboftargetok) {
mkdir($DESTI.'/standard');
if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; }
}
print "Remove target $FILENAMETGZ.tgz...\n";
unlink("$NEWDESTI/$FILENAMETGZ.tgz");
@ -1056,7 +1064,8 @@ if ($nboftargetok) {
$ret=`mv $BUILDROOT/*_all.deb "$NEWDESTI/"`;
$ret=`mv $BUILDROOT/*.dsc "$NEWDESTI/"`;
$ret=`mv $BUILDROOT/*.orig.tar.gz "$NEWDESTI/"`;
$ret=`mv $BUILDROOT/*.debian.tar.xz "$NEWDESTI/"`;
#$ret=`mv $BUILDROOT/*.debian.tar.xz "$NEWDESTI/"`; # xz file is generated when build/debian/sources/option
$ret=`mv $BUILDROOT/*.debian.tar.gz "$NEWDESTI/"`;
$ret=`mv $BUILDROOT/*.changes "$NEWDESTI/"`;
next;
}
@ -1073,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;
}
@ -1114,7 +1147,8 @@ if ($nboftargetok) {
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}_all.deb"=>'Dolibarr installer for Debian-Ubuntu (DoliDeb)',
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}_amd64.changes"=>'none', # none means it won't be published on SF
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}.dsc"=>'none', # none means it won't be published on SF
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}.debian.tar.xz"=>'none', # none means it won't be published on SF
#"$DESTI/package_debian-ubuntu/${FILENAMEDEB}.debian.tar.xz"=>'none', # none means it won't be published on SF
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}.debian.tar.gz"=>'none', # none means it won't be published on SF
"$DESTI/package_debian-ubuntu/${FILENAMEDEBSHORT}.orig.tar.gz"=>'none', # none means it won't be published on SF
"$DESTI/package_windows/$FILENAMEEXEDOLIWAMP.exe"=>'Dolibarr installer for Windows (DoliWamp)',
"$DESTI/standard/$FILENAMETGZ.tgz"=>'Dolibarr ERP-CRM',
@ -1241,7 +1275,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

@ -293,6 +293,7 @@ foreach my $PROJECT (@PROJECTLIST) {
}
print "Clean $BUILDROOT\n";
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.cache`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.git`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.project`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.settings`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/index.php`;

View File

@ -1,7 +1,46 @@
----- 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 from Linux (solution seems broken since Ubuntu 20.04):
> 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.6_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 *****
Prerequisites to build autoexe DoliWamp package from Windows:
> Install Perl for Windwos (https://strawberryperl.com/)
> Install isetup-5.5.8.exe (https://www.jrsoftware.org)
> Install WampServer-3.2.*-64.exe (Apache 2.4.51, PHP 7.3.33, MariaDB 10.6.5 for example. Version must match the values found into doliwamp.iss)
> Install GIT for Windows (https://git-scm.com/ => You must choose option "Add Git bash profile", "Git commit as-is")
> Install Dolibarr verions:
git clone https://github.com/dolibarr/dolibarr
> Add the path of PHP (C:\wamp64\bin\php\php7.3.33) and InnoSetup (C:\Program Files (x86)\Inno Setup 5) into the %PATH% of Windows.
> Create a config file c:\dolibarr\dolibarr\htdocs\conf\conf.php with content
<?php
$dolibarr_main_document_root="c:\dolibarr\dolibarr\htdocs";
$dolibarr_main_url_root='http://localhost';
***** Actions to do a BETA *****
This files describe steps made by Dolibarr packaging team to make a

View File

@ -25,7 +25,7 @@ BuildArch: noarch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Group: Applications/Productivity
Requires: httpd, php >= 5.3.0, php-cli, php-gd, php-ldap, php-imap, php-mysqli, php-adodb, php-nusoap, dejavu-sans-fonts
Requires: httpd, php >= 5.3.0, php-cli, php-gd, php-ldap, php-imap, php-mysqli, php-nusoap, dejavu-sans-fonts
Requires: mysql-server, mysql
#BuildRequires: desktop-file-utils
@ -104,7 +104,6 @@ cui hai bisogno ed essere facile da usare.
%{__cp} -pr htdocs $RPM_BUILD_ROOT%{_datadir}/%{name}
%{__cp} -pr scripts $RPM_BUILD_ROOT%{_datadir}/%{name}
%{__rm} -rf $RPM_BUILD_ROOT%{_datadir}/%{name}/htdocs/includes/ckeditor/_source
%{__rm} -rf $RPM_BUILD_ROOT%{_datadir}/%{name}/htdocs/includes/adodbtime
%{__rm} -rf $RPM_BUILD_ROOT%{_datadir}/%{name}/htdocs/includes/nusoap
%{__rm} -rf $RPM_BUILD_ROOT%{_datadir}/%{name}/htdocs/includes/fonts
@ -165,6 +164,7 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/barcode
%_datadir/dolibarr/htdocs/blockedlog
%_datadir/dolibarr/htdocs/bookmarks
%_datadir/dolibarr/htdocs/bookcal
%_datadir/dolibarr/htdocs/bom
%_datadir/dolibarr/htdocs/categories
%_datadir/dolibarr/htdocs/collab
@ -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
@ -273,7 +274,6 @@ if [ -s $config ] && grep -q "File generated by" $config
then
# File already exist. We add params not found.
echo Add new params to overwrite path to use shared libraries/fonts
grep -q -c "dolibarr_lib_ADODB_PATH" $config || [ ! -d "/usr/share/php/adodb" ] || echo "<?php \$dolibarr_lib_ADODB_PATH='/usr/share/php/adodb'; ?>" >> $config
grep -q -c "dolibarr_lib_FPDI_PATH" $config || [ ! -d "/usr/share/php/fpdi" ] || echo "<?php \$dolibarr_lib_FPDI_PATH='/usr/share/php/fpdi'; ?>" >> $config
#grep -q -c "dolibarr_lib_GEOIP_PATH" $config || echo "<?php \$dolibarr_lib_GEOIP_PATH=''; ?>" >> $config
grep -q -c "dolibarr_lib_NUSOAP_PATH" $config || [ ! -d "/usr/share/php/nusoap" ] || echo "<?php \$dolibarr_lib_NUSOAP_PATH='/usr/share/php/nusoap'; ?>" >> $config

View File

@ -46,7 +46,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-build
%if 0%{?fedora} || 0%{?rhel_version} || 0%{?centos_version}
Group: Applications/Productivity
Requires: httpd, php >= 5.3.0, php-cli, php-gd, php-ldap, php-imap, php-mysqli, php-adodb, php-nusoap, dejavu-sans-fonts, php-mbstring, php-xml
Requires: httpd, php >= 5.3.0, php-cli, php-gd, php-ldap, php-imap, php-mysqli, php-nusoap, dejavu-sans-fonts, php-mbstring, php-xml
Requires: mysql-server, mysql
BuildRequires: desktop-file-utils
%else
@ -54,11 +54,11 @@ 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
Requires: apache2, apache2-mod_php5, php5 >= 5.3.0, php5-gd, php5-ldap, php5-imap, php5-mysql, php5-openssl, dejavu
Requires: apache2, apache2-mod_php, php >= 5.3.0, php-gd, php-ldap, php-imap, php-mysql, php-openssl, dejavu
Requires: mysql-community-server, mysql-community-server-client
BuildRequires: update-desktop-files fdupes
%else
@ -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
@ -169,7 +169,6 @@ cui hai bisogno ed essere facile da usare.
%{__cp} -pr scripts $RPM_BUILD_ROOT%{_datadir}/%{name}
%{__rm} -rf $RPM_BUILD_ROOT%{_datadir}/%{name}/htdocs/includes/ckeditor/_source
%if 0%{?fedora} || 0%{?rhel_version} || 0%{?centos_version}
%{__rm} -rf $RPM_BUILD_ROOT%{_datadir}/%{name}/htdocs/includes/adodbtime
%{__rm} -rf $RPM_BUILD_ROOT%{_datadir}/%{name}/htdocs/includes/nusoap
%{__rm} -rf $RPM_BUILD_ROOT%{_datadir}/%{name}/htdocs/includes/fonts
%else
@ -246,6 +245,7 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/barcode
%_datadir/dolibarr/htdocs/blockedlog
%_datadir/dolibarr/htdocs/bookmarks
%_datadir/dolibarr/htdocs/bookcal
%_datadir/dolibarr/htdocs/bom
%_datadir/dolibarr/htdocs/categories
%_datadir/dolibarr/htdocs/collab
@ -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
@ -424,7 +425,6 @@ if [ -s $config ] && grep -q "File generated by" $config
then
# File already exist. We add params not found.
echo Add new params to overwrite path to use shared libraries/fonts
grep -q -c "dolibarr_lib_ADODB_PATH" $config || [ ! -d "/usr/share/php/adodb" ] || echo "<?php \$dolibarr_lib_ADODB_PATH='/usr/share/php/adodb'; ?>" >> $config
grep -q -c "dolibarr_lib_FPDI_PATH" $config || [ ! -d "/usr/share/php/fpdi" ] || echo "<?php \$dolibarr_lib_FPDI_PATH='/usr/share/php/fpdi'; ?>" >> $config
#grep -q -c "dolibarr_lib_GEOIP_PATH" $config || echo "<?php \$dolibarr_lib_GEOIP_PATH=''; ?>" >> $config
grep -q -c "dolibarr_lib_NUSOAP_PATH" $config || [ ! -d "/usr/share/php/nusoap" ] || echo "<?php \$dolibarr_lib_NUSOAP_PATH='/usr/share/php/nusoap'; ?>" >> $config

View File

@ -162,6 +162,7 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/barcode
%_datadir/dolibarr/htdocs/blockedlog
%_datadir/dolibarr/htdocs/bookmarks
%_datadir/dolibarr/htdocs/bookcal
%_datadir/dolibarr/htdocs/bom
%_datadir/dolibarr/htdocs/categories
%_datadir/dolibarr/htdocs/collab
@ -224,6 +225,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
@ -270,7 +272,6 @@ if [ -s $config ] && grep -q "File generated by" $config
then
# File already exist. We add params not found.
echo Add new params to overwrite path to use shared libraries/fonts
grep -q -c "dolibarr_lib_ADODB_PATH" $config || [ ! -d "/usr/share/php/adodb" ] || echo "<?php \$dolibarr_lib_ADODB_PATH='/usr/share/php/adodb'; ?>" >> $config
grep -q -c "dolibarr_lib_FPDI_PATH" $config || [ ! -d "/usr/share/php/fpdi" ] || echo "<?php \$dolibarr_lib_FPDI_PATH='/usr/share/php/fpdi'; ?>" >> $config
#grep -q -c "dolibarr_lib_GEOIP_PATH" $config || echo "<?php \$dolibarr_lib_GEOIP_PATH=''; ?>" >> $config
grep -q -c "dolibarr_lib_NUSOAP_PATH" $config || [ ! -d "/usr/share/php/nusoap" ] || echo "<?php \$dolibarr_lib_NUSOAP_PATH='/usr/share/php/nusoap'; ?>" >> $config

View File

@ -25,7 +25,7 @@ BuildArch: noarch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Group: Productivity/Office/Management
Requires: apache2, apache2-mod_php5, php5 >= 5.3.0, php5-gd, php5-ldap, php5-imap, php5-mysql, php5-openssl, dejavu
Requires: apache2, apache2-mod_php, php >= 5.3.0, php-gd, php-ldap, php-imap, php-mysql, php-openssl, dejavu
Requires: mysql-community-server, mysql-community-server-client
%if 0%{?suse_version}
BuildRequires: update-desktop-files fdupes
@ -67,8 +67,7 @@ Programmo web, progettato per poter fornire solo ciò di
cui hai bisogno ed essere facile da usare.
#---- prep
#---- prepo
%prep
%setup -q
%patch0 -p0 -b .patch
@ -173,6 +172,7 @@ done >>%{name}.lang
%_datadir/dolibarr/htdocs/barcode
%_datadir/dolibarr/htdocs/blockedlog
%_datadir/dolibarr/htdocs/bookmarks
%_datadir/dolibarr/htdocs/bookcal
%_datadir/dolibarr/htdocs/bom
%_datadir/dolibarr/htdocs/categories
%_datadir/dolibarr/htdocs/collab
@ -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
@ -281,7 +282,6 @@ if [ -s $config ] && grep -q "File generated by" $config
then
# File already exist. We add params not found.
echo Add new params to overwrite path to use shared libraries/fonts
grep -q -c "dolibarr_lib_ADODB_PATH" $config || [ ! -d "/usr/share/php/adodb" ] || echo "<?php \$dolibarr_lib_ADODB_PATH='/usr/share/php/adodb'; ?>" >> $config
grep -q -c "dolibarr_lib_FPDI_PATH" $config || [ ! -d "/usr/share/php/fpdi" ] || echo "<?php \$dolibarr_lib_FPDI_PATH='/usr/share/php/fpdi'; ?>" >> $config
#grep -q -c "dolibarr_lib_GEOIP_PATH" $config || echo "<?php \$dolibarr_lib_GEOIP_PATH=''; ?>" >> $config
grep -q -c "dolibarr_lib_NUSOAP_PATH" $config || [ ! -d "/usr/share/php/nusoap" ] || echo "<?php \$dolibarr_lib_NUSOAP_PATH='/usr/share/php/nusoap'; ?>" >> $config

View File

@ -20,7 +20,6 @@ $force_install_lockinstall='444';
$force_install_distrib='rpmfedora';
// Value to overwrite path to use shared libraries/fonts instead of embedded one
$force_dolibarr_lib_ADODB_PATH='/usr/share/php/adodb';
//$force_dolibarr_lib_FPDI_PATH='/usr/share/php/fpdi';
//$force_dolibarr_lib_GEOIP_PATH='';
$force_dolibarr_lib_NUSOAP_PATH='/usr/share/php/nusoap';

View File

@ -20,7 +20,6 @@ $force_install_lockinstall='444';
$force_install_distrib='rpmmandriva';
// Value to overwrite path to use shared libraries/fonts instead of embedded one
$force_dolibarr_lib_ADODB_PATH='/usr/share/php/adodb';
//$force_dolibarr_lib_FPDI_PATH='/usr/share/php/fpdi';
//$force_dolibarr_lib_GEOIP_PATH='';
$force_dolibarr_lib_NUSOAP_PATH='/usr/share/php/nusoap';

View File

@ -20,7 +20,6 @@ $force_install_lockinstall='444';
$force_install_distrib='rpmopensuse';
// Value to overwrite path to use shared libraries/fonts instead of embedded one
//$force_dolibarr_lib_ADODB_PATH='/usr/share/php/adodb';
//$force_dolibarr_lib_FPDI_PATH='/usr/share/php/fpdi';
//$force_dolibarr_lib_GEOIP_PATH='';
//$force_dolibarr_lib_NUSOAP_PATH='/usr/share/php/nusoap';

View File

@ -275,7 +275,17 @@ 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]))
* Add CommentParser.php line 406 & 407 to remove a warning on api request in php 8.1
empty($value[0]) ? null :
empty($value[1]) ? null :
+With swagger 2 provided into /explorer:
----------------------------------------

View File

@ -1,28 +1,29 @@
# ldapsearch_sample1.txt
# ldapsearch is into package ldap-utils on debian.
#
# Use this sample to search into a ldap
# Use this samples to test a ldap_bind or to make a search into a ldap
#
# Anonymous access
# ldapsearch -h hostname -p 389
# ldapsearch -h hostname -p 389
#
# Login access (using a Bind DN)
# ldapsearch -h hostname -p 389 -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password
# ldapsearch -H ldap://hostname:389 -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password
# ldapsearch -d1 -H ldap://hostname:389 -x -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password
# ldapsearch -H ldap://hostname:389 -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password
# Such access must succeed to use LDAP as login module.
# ldapsearch -h hostname -p 389 -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password
# ldapsearch -H ldap://hostname:389 -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password
# ldapsearch -d1 -H ldap://hostname:389 -x -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password
# ldapsearch -H ldap://hostname:389 -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password
#
# Login access in SSL (using a Bind DN)
# ldapsearch -H ldaps://hostnamme:636 -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password -b "cn=users,dc=ldap,dc=test,dc=local
# ldapsearch -H ldaps://hostnamme:636 -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password -b "cn=users,dc=ldap,dc=test,dc=local"
# If it fails, you may try to use "hostname" that is real name of certificate.
# You must also check that /etc/ldap/ldap.conf contains the line TLS_CACERT /etc/ssl/certs/ca-certificates.crt
# What to search
# ldapsearch -h hostname -p 389 -x -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password -b "cn=users,dc=ldap,dc=test,dc=local"
# ldapsearch -h hostname -p 389 -x -D "cn=manager,o=somecompany.com" -w password -b "ou=people,dc=teclib,dc=infra"
# ldapsearch -h hostname -p 389 -x -D "cn=manager,o=somecompany.com" -w password -b "o=somecompany.com" "(objectclass=*)"
# ldapsearch -h hostname -p 389 -x -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password -b "cn=users,dc=ldap,dc=test,dc=local"
# ldapsearch -h hostname -p 389 -x -D "cn=manager,o=somecompany.com" -w password -b "ou=people,dc=teclib,dc=infra"
# ldapsearch -h hostname -p 389 -x -D "cn=manager,o=somecompany.com" -w password -b "o=somecompany.com" "(objectclass=*)"
#
# Example to test a ldap search:
# ldapsearch -h hostname -p 389 -x -z 5 -b 'OU=Collaborateurs,OU=Utilisateurs,OU=MyCompany,DC=bocal,DC=lan' -D 'CN=UserAdmin,OU=Informatique,OU=Utilisateurs,OU=MyCompany,DC=bocal,DC=lan' -w password
# ldapsearch -h hostname -p 389 -x -z 5 -b 'OU=Collaborateurs,OU=Utilisateurs,OU=MyCompany,DC=bocal,DC=lan' -D 'CN=UserAdmin,OU=Informatique,OU=Utilisateurs,OU=MyCompany,DC=bocal,DC=lan' -w password

View File

@ -10,7 +10,7 @@ const subscribeHook = (z, bundle) => {
action: bundle.inputData.action
};
const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
const url = bundle.authData.url + '/api/index.php/zapier/hook';
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
@ -32,7 +32,7 @@ const unsubscribeHook = (z, bundle) => {
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
url: bundle.authData.url + '/api/index.php/zapier/hook/' + bundle.subscribeData.id,
method: 'DELETE',
};
@ -84,7 +84,7 @@ const getFallbackRealAction = (z, bundle) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const module = bundle.inputData.module;
// const options = {
// url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/actions',
// url: bundle.authData.url + '/api/index.php/zapier/getactionschoices/actions',
// };
// return z.request(options).then((response) => JSON.parse(response.content));

View File

@ -10,7 +10,7 @@ const subscribeHook = (z, bundle) => {
action: bundle.inputData.action
};
const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
const url = bundle.authData.url + '/api/index.php/zapier/hook';
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
@ -32,7 +32,7 @@ const unsubscribeHook = (z, bundle) => {
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
url: bundle.authData.url + '/api/index.php/zapier/hook/' + bundle.subscribeData.id,
method: 'DELETE',
};
@ -76,7 +76,7 @@ const getFallbackRealContact = (z, bundle) => {
// const getModulesChoices = (z/*, bundle*/) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const options = {
// url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices',
// url: bundle.authData.url + '/api/index.php/zapier/getmoduleschoices',
// };
// return z.request(options).then((response) => JSON.parse(response.content));
@ -94,7 +94,7 @@ const getFallbackRealContact = (z, bundle) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const module = bundle.inputData.module;
// const options = {
// url: url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`,
// url: url: bundle.authData.url + '/api/index.php/zapier/getactionschoices/thirparty`,
// };
// return z.request(options).then((response) => JSON.parse(response.content));

View File

@ -10,7 +10,7 @@ const subscribeHook = (z, bundle) => {
action: bundle.inputData.action
};
const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
const url = bundle.authData.url + '/api/index.php/zapier/hook';
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
@ -32,7 +32,7 @@ const unsubscribeHook = (z, bundle) => {
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
url: bundle.authData.url + '/api/index.php/zapier/hook/' + bundle.subscribeData.id,
method: 'DELETE',
};
@ -76,7 +76,7 @@ const getFallbackRealMember = (z, bundle) => {
// const getModulesChoices = (z/*, bundle*/) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const options = {
// url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices',
// url: bundle.authData.url + '/api/index.php/zapier/getmoduleschoices',
// };
// return z.request(options).then((response) => JSON.parse(response.content));
@ -94,7 +94,7 @@ const getFallbackRealMember = (z, bundle) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const module = bundle.inputData.module;
// const options = {
// url: url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`,
// url: url: bundle.authData.url + '/api/index.php/zapier/getactionschoices/thirparty`,
// };
// return z.request(options).then((response) => JSON.parse(response.content));

View File

@ -10,7 +10,7 @@ const subscribeHook = (z, bundle) => {
action: bundle.inputData.action
};
const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
const url = bundle.authData.url + '/api/index.php/zapier/hook';
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
@ -32,7 +32,7 @@ const unsubscribeHook = (z, bundle) => {
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
url: bundle.authData.url + '/api/index.php/zapier/hook/' + bundle.subscribeData.id,
method: 'DELETE',
};
@ -74,7 +74,7 @@ const getFallbackRealOrder = (z, bundle) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const module = bundle.inputData.module;
// const options = {
// url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/orders',
// url: bundle.authData.url + '/api/index.php/zapier/getactionschoices/orders',
// };
// return z.request(options).then((response) => JSON.parse(response.content));

View File

@ -10,7 +10,7 @@ const subscribeHook = (z, bundle) => {
action: bundle.inputData.action
};
const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
const url = bundle.authData.url + '/api/index.php/zapier/hook';
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
@ -32,7 +32,7 @@ const unsubscribeHook = (z, bundle) => {
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
url: bundle.authData.url + '/api/index.php/zapier/hook/' + bundle.subscribeData.id,
method: 'DELETE',
};
@ -83,7 +83,7 @@ const getFallbackRealThirdparty = (z, bundle) => {
// const getModulesChoices = (z/*, bundle*/) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const options = {
// url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices',
// url: bundle.authData.url + '/api/index.php/zapier/getmoduleschoices',
// };
// return z.request(options).then((response) => JSON.parse(response.content));
@ -102,7 +102,7 @@ const getFallbackRealThirdparty = (z, bundle) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const module = bundle.inputData.module;
// const options = {
// url: url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`,
// url: url: bundle.authData.url + '/api/index.php/zapier/getactionschoices/thirparty`,
// };
// return z.request(options).then((response) => JSON.parse(response.content));

View File

@ -10,7 +10,7 @@ const subscribeHook = (z, bundle) => {
action: bundle.inputData.action
};
const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
const url = bundle.authData.url + '/api/index.php/zapier/hook';
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
@ -32,7 +32,7 @@ const unsubscribeHook = (z, bundle) => {
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
url: bundle.authData.url + '/api/index.php/zapier/hook/' + bundle.subscribeData.id,
method: 'DELETE',
};
@ -76,7 +76,7 @@ const getFallbackRealTicket = (z, bundle) => {
// const getModulesChoices = (z/*, bundle*/) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const options = {
// url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices',
// url: bundle.authData.url + '/api/index.php/zapier/getmoduleschoices',
// };
// return z.request(options).then((response) => JSON.parse(response.content));
@ -97,7 +97,7 @@ const getFallbackRealTicket = (z, bundle) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const module = bundle.inputData.module;
// const options = {
// url: url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`,
// url: url: bundle.authData.url + '/api/index.php/zapier/getactionschoices/thirparty`,
// };
// return z.request(options).then((response) => JSON.parse(response.content));

View File

@ -10,7 +10,7 @@ const subscribeHook = (z, bundle) => {
action: bundle.inputData.action
};
const url = bundle.authData.url + '/api/index.php/zapierapi/hook';
const url = bundle.authData.url + '/api/index.php/zapier/hook';
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
@ -32,7 +32,7 @@ const unsubscribeHook = (z, bundle) => {
// You can build requests and our client will helpfully inject all the variables
// you need to complete. You can also register middleware to control this.
const options = {
url: bundle.authData.url + '/api/index.php/zapierapi/hook/' + bundle.subscribeData.id,
url: bundle.authData.url + '/api/index.php/zapier/hook/' + bundle.subscribeData.id,
method: 'DELETE',
};
@ -73,7 +73,7 @@ const getFallbackRealUser = (z, bundle) => {
// const getModulesChoices = (z/*, bundle*/) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const options = {
// url: bundle.authData.url + '/api/index.php/zapierapi/getmoduleschoices',
// url: bundle.authData.url + '/api/index.php/zapier/getmoduleschoices',
// };
// return z.request(options).then((response) => JSON.parse(response.content));
@ -93,7 +93,7 @@ const getFallbackRealUser = (z, bundle) => {
// // For the test poll, you should get some real data, to aid the setup process.
// const module = bundle.inputData.module;
// const options = {
// url: url: bundle.authData.url + '/api/index.php/zapierapi/getactionschoices/thirparty`,
// url: url: bundle.authData.url + '/api/index.php/zapier/getactionschoices/thirparty`,
// };
// return z.request(options).then((response) => JSON.parse(response.content));

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

@ -12,3 +12,11 @@ Le client règle rapidement et on lui accorde un escompte de 3% (120 € * 3% =
411xxx 3,60 € TTC
Et ça marche à linverse avec un fournisseur sauf que lon est en 775000 au lieu de 665000 pour escompte obtenus.
Un compte comptable de Tiers vente = Acount Receivable
Un compte comptable de Tiers achat = Acount Payable

Binary file not shown.

View File

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

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

@ -1,9 +1,17 @@
<VirtualHost *:80>
#php_admin_value sendmail_path "/usr/sbin/sendmail -t -i"
#php_admin_value mail.force_extra_parameters "-f postmaster@mydomain.com"
php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f postmaster@mydomain.com"
php_admin_value open_basedir /tmp/:/home/.../htdocs:/home/.../dolibarr_documents:
#php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f postmaster@mydomain.com"
php_admin_value open_basedir /tmp/:/home/.../htdocs:/home/.../dolibarr_documents:
# Add this to use a custom apparmor profile when using apache php handler
<IfModule mod_apparmor.c>
AADefaultHatName sellyoursaas-instances
</IfModule>
ServerName myvirtualalias
ServerAlias myvirtualalias
@ -28,8 +36,8 @@
#AuthUserFile /etc/apache2/.htpasswd
#require valid-user
</Directory>
# Leaving /public and /api, /dav, .well_known but also wrappers for document and viewimage accessible to everyone
# Leaving /public and /api, /dav, .well_known but also wrappers for document, viewimage and public json/img accessible to everyone
<Directory /home/admin/wwwroot/dolibarr/htdocs/public/>
AuthType None
Require all granted
@ -82,9 +90,9 @@
# /usr/share/doc/apache2.2-common/README.Debian.gz for more info.
# If both key and certificate are stored in the same file, only the
# SSLCertificateFile directive is needed.
SSLCertificateFile /etc/letsencrypt/live/www.mydomain.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.mydomain.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/www.mydomain.com/chain.pem
#SSLCertificateFile /etc/letsencrypt/live/www.mydomain.com/cert.pem
#SSLCertificateKeyFile /etc/letsencrypt/live/www.mydomain.com/privkey.pem
#SSLCertificateChainFile /etc/letsencrypt/live/www.mydomain.com/chain.pem
#RewriteEngine on
#RewriteCond %{SERVER_PORT} ^80$

View File

@ -15,9 +15,10 @@
<exclude-pattern type="relative">htdocs/install/doctemplates/websites</exclude-pattern>
<exclude-pattern type="relative">htdocs/conf.php</exclude-pattern>
<exclude-pattern type="relative">*/nltechno*</exclude-pattern>
<exclude-pattern type="relative">*/htdocs/includes</exclude-pattern>
<exclude-pattern type="relative">source</exclude-pattern>
<exclude-pattern type="relative">.git</exclude-pattern>
<exclude-pattern>htdocs/includes</exclude-pattern>
<exclude-pattern>htdocs/install/doctemplates/websites</exclude-pattern>
<!-- List of all tests -->
@ -135,7 +136,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

@ -0,0 +1,19 @@
# Fail2Ban configuration file
#
# Regexp to detect forbidden access on pages (public or not) so we can add mitigation on IP making too much
# access to your a Dolibarr instance.
[Definition]
# To test, you can inject this example into log
# echo `myvirtualhost.com:443 1.2.3.4 - - [15/Dec/2022:09:57:47 +0000] "GET /public/abc" 403 123 "-" "Mozilla" >> /var/log/apache2/access.log
#
# then
# fail2ban-client status web-accesslog-limit403
#
# To test rule file on a existing log file
# fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/web-accesslog-limit403.conf
failregex = <HOST> - - .*HTTP/[0-9]+(.[0-9]+)?" 403
ignoreregex =

View File

@ -0,0 +1,19 @@
# Fail2Ban configuration file
#
# Regexp to detect access on public pages so we can add mitigation on IP making too much
# access to your a Dolibarr instance.
[Definition]
# To test, you can inject this example into log
# echo `date +'%Y-%m-%d %H:%M:%S'`" INFO 1.2.3.4 --- Access to GET /public/clicktodial/cidlookup.php" >> /mypath/documents/dolibarr.log
#
# then
# fail2ban-client status web-dolibarr-limitpublic
#
# To test rule file on a existing log file
# fail2ban-regex /mypath/documents/dolibarr.log /etc/fail2ban/filter.d/web-dolibarr-limitpublic.conf
failregex = ^ [A-Z\s]+ <HOST>\s+--- Access to .*/public/
ignoreregex =

View File

@ -1,8 +1,7 @@
# Fail2Ban configuration file
#
# Regexp to catch known spambots and software alike. Please verify
# that it is your intent to block IPs which were driven by
# above mentioned bots.
# Regexp to detect try to check a couple login/password so we can add mitigation
# on IP making too much tries.
[Definition]
@ -11,7 +10,7 @@
# echo `date +'%Y-%m-%d %H:%M:%S'`" INFO 1.2.3.4 functions_dolibarr::check_user_password_abcd Authentication KO" >> /mypath/documents/dolibarr.log
#
# then
# fail2ban-client status web-dol-bruteforce
# fail2ban-client status web-dolibarr-rulesbruteforce
#
# To test rule file on a existing log file
# fail2ban-regex /mypath/documents/dolibarr.log /etc/fail2ban/filter.d/web-dolibarr-rulesbruteforce.conf

View File

@ -1,8 +1,7 @@
# Fail2Ban configuration file
#
# Regexp to catch known spambots and software alike. Please verify
# that it is your intent to block IPs which were driven by
# above mentioned bots.
# Regexp to detect access on passwordforgotten.php page so we can add mitigation on IP making too much
# access to this Dolibarr page.
[Definition]
@ -11,7 +10,7 @@
# echo `date +'%Y-%m-%d %H:%M:%S'`" INFO 1.2.3.4 --- Access to GET /passwordforgotten.php - action=buildnewpassword, massaction=" >> /mypath/documents/dolibarr.log
#
# then
# fail2ban-client status web-dol-passforgotten
# fail2ban-client status web-dolibarr-rulespassforgotten
#
# To test rule file on a existing log file
# fail2ban-regex /mypath/documents/dolibarr.log /etc/fail2ban/filter.d/web-dolibarr-rulespassforgotten.conf

View File

@ -8,21 +8,35 @@
enabled = true
port = http,https
filter = web-dolibarr-rulespassforgotten
logpath = >> /mypath/documents/documents/dolibarr.log
logpath = /mypath/documents/documents/dolibarr.log
action = %(action_mw)s
bantime = 4320000 ; 50 days
findtime = 86400 ; 1 day
maxretry = 10
[web-dol-bruteforce]
; rule against bruteforce hacking (login + api)
enabled = true
port = http,https
filter = web-dolibarr-rulesbruteforce
logpath = >> /mypath/documents/documents/dolibarr.log
logpath = /mypath/documents/documents/dolibarr.log
action = %(action_mw)s
bantime = 86400 ; 1 day
findtime = 3600 ; 1 hour
maxretry = 10
[web-dol-limitpublic]
; rule to add rate limit on some public pages
enabled = true
port = http,https
filter = web-dolibarr-limitpublic
logpath = /mypath/documents/documents/dolibarr.log
action = %(action_mw)s
bantime = 86400 ; 1 day
findtime = 86400 ; 1 day
maxretry = 500

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

@ -0,0 +1,14 @@
QODANA TUTO
-----------
This README explains how to use qodana to generate static analytics reports on the code
Install docker
Install qodana
To run inspection on CLI
cd ~/git/dirtoscan
sudo qodana scan --show-report

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

@ -1,5 +1,8 @@
#!/bin/sh
#
# Count number of different contributors and number of commits for a given year.
#
if [ "x$1" = "x" ]; then
echo "Usage: $0 YEAR"
exit

View File

@ -1,6 +1,10 @@
#/bin/bash
Releases=("3.8" "3.9" "4.0" "5.0" "6.0" " 7.0" "develop")
Dates=("2013-01-01", "2014-01-01", "2015-01-01", "2016-07-01", "2017-02-01", "2017-07-01", "2018-02-01", "2050-01-01")
#
# Count number of commits per user and per versions (using date for version detection)
#
Releases=("16.0" "develop")
Dates=("2022-01-01" "2022-08-31" "2050-01-01")
let "counter = 1"
for i in "${Releases[@]}"

View File

@ -0,0 +1,16 @@
#/bin/bash
#
# Count number of lines modified per user for a given branch
#
if [ "x$2" = "x" ]; then
echo "Usage: $0 tagnamestart|START tagnameend|HEAD"
exit
fi
echo "git log $1..$2 --shortstat | grep ... | perl ... > /tmp/github_lines_perusers.tmp"
git log $1..$2 --shortstat | grep -e 'Author:' -e 'Date:' -e ' changed' -e ' insertion' -e ' deletion' | perl -n -e '/^(.*)$/; $line = $1; if ($line =~ /(changed|insertion|deletion)/) { $line =~ s/[^0-9\s]//g; my @arr=split /\s+/, $line; $tot=0; for (1..@arr) { $tot += $arr[$_]; }; print $tot."\n"; } else { print $line."\n"; };' > /tmp/github_lines_perusers.tmp
cat /tmp/github_lines_perusers.tmp | awk 'BEGIN { FS="\n"; print "user and nb of lines"; lastuser=""; } { if ($1 ~ /Author:/) { lastuser=$1 }; if ($1 ~ /^[0-9]+$/) { aaa[lastuser]+=$1; } } END { for (var in aaa) print var," ",aaa[var]; } '

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,9 +121,11 @@ 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 '/documents/' | 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/'"
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)
#IMAGES=$(find $INPUT -regextype posix-extended -regex '.*\.(jpg|jpeg|png)' | grep -v '/gource/' | grep -v '/includes/' | grep -v '/custom/')
if [ "$QUIET" == "0" ]; then
echo --- Optimizing $INPUT ---
echo
@ -135,11 +138,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,5 +1,4 @@
<?php
/*spl_autoload_register(function ($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');
@ -46,20 +47,21 @@ $search_label = GETPOST('search_label', 'alpha');
$search_labelshort = GETPOST('search_labelshort', 'alpha');
$search_accountparent = GETPOST('search_accountparent', 'alpha');
$search_pcgtype = GETPOST('search_pcgtype', 'alpha');
$search_import_key = GETPOST('search_import_key', 'alpha');
$toselect = GETPOST('toselect', 'array');
$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit;
$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();
}
@ -82,21 +84,27 @@ if (!$sortorder) {
}
$arrayfields = array(
'aa.account_number'=>array('label'=>$langs->trans("AccountNumber"), 'checked'=>1),
'aa.label'=>array('label'=>$langs->trans("Label"), 'checked'=>1),
'aa.labelshort'=>array('label'=>$langs->trans("LabelToShow"), 'checked'=>1),
'aa.account_parent'=>array('label'=>$langs->trans("Accountparent"), 'checked'=>1),
'aa.pcg_type'=>array('label'=>$langs->trans("Pcgtype"), 'checked'=>1, 'help'=>'PcgtypeDesc'),
'aa.reconcilable'=>array('label'=>$langs->trans("Reconcilable"), 'checked'=>1),
'aa.active'=>array('label'=>$langs->trans("Activated"), 'checked'=>1)
'aa.account_number'=>array('label'=>"AccountNumber", 'checked'=>1),
'aa.label'=>array('label'=>"Label", 'checked'=>1),
'aa.labelshort'=>array('label'=>"LabelToShow", 'checked'=>1),
'aa.account_parent'=>array('label'=>"Accountparent", 'checked'=>1),
'aa.pcg_type'=>array('label'=>"Pcgtype", 'checked'=>1, 'help'=>'PcgtypeDesc'),
'categories'=>array('label'=>"AccountingCategories", 'checked'=>-1, 'help'=>'AccountingCategoriesDesc'),
'aa.reconcilable'=>array('label'=>"Reconcilable", 'checked'=>1),
'aa.active'=>array('label'=>"Activated", 'checked'=>1),
'aa.import_key'=>array('label'=>"ImportId", 'checked'=>-1)
);
if ($conf->global->MAIN_FEATURES_LEVEL < 2) {
unset($arrayfields['categories']);
unset($arrayfields['aa.reconcilable']);
}
$accounting = new AccountingAccount($db);
// Initialize technical object to manage hooks. Note that conf->hooks_modules contains array
$hookmanager->initHooks(array('accountancyadminaccount'));
/*
* Actions
@ -109,8 +117,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');
}
@ -222,15 +230,12 @@ if ($action == 'delete') {
$pcgver = $conf->global->CHARTOFACCOUNTS;
$sql = "SELECT aa.rowid, aa.fk_pcg_version, aa.pcg_type, aa.account_number, aa.account_parent , aa.label, aa.labelshort, aa.reconcilable, aa.active, ";
$sql = "SELECT aa.rowid, aa.fk_pcg_version, aa.pcg_type, aa.account_number, aa.account_parent, aa.label, aa.labelshort, aa.fk_accounting_category,";
$sql .= " aa.reconcilable, aa.active, aa.import_key,";
$sql .= " a2.rowid as rowid2, a2.label as label2, a2.account_number as account_number2";
$sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as aa";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version AND aa.entity = ".$conf->entity;
if ($db->type == 'pgsql') {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as a2 ON a2.rowid = aa.account_parent AND a2.entity = ".$conf->entity;
} else {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as a2 ON a2.rowid = aa.account_parent AND a2.entity = ".$conf->entity;
}
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version AND aa.entity = ".((int) $conf->entity);
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as a2 ON a2.rowid = aa.account_parent AND a2.entity = ".((int) $conf->entity);
$sql .= " WHERE asy.rowid = ".((int) $pcgver);
//print $sql;
if (strlen(trim($search_account))) {
@ -294,7 +299,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'))) {
@ -333,6 +338,9 @@ if ($resql) {
if ($search_pcgtype) {
$param .= '&search_pcgtype='.urlencode($search_pcgtype);
}
if ($optioncss != '') {
$param .= '&search_import_key='.urlencode($search_import_key);
}
if ($optioncss != '') {
$param .= '&optioncss='.urlencode($optioncss);
}
@ -350,6 +358,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.'">';
@ -393,9 +403,14 @@ if ($resql) {
}
print "</select>";
print ajax_combobox("chartofaccounts");
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 '<input type="'.(empty($conf->use_javascript_ajax) ? 'submit' : 'button').'" class="button button-edit small" 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;
@ -425,11 +440,20 @@ if ($resql) {
}
if (!empty($arrayfields['aa.account_parent']['checked'])) {
print '<td class="liste_titre">';
print $formaccounting->select_account($search_accountparent, 'search_accountparent', 2);
print $formaccounting->select_account($search_accountparent, 'search_accountparent', 2, array(), 0, 0, 'maxwidth150');
print '</td>';
}
// Predefined group
if (!empty($arrayfields['aa.pcg_type']['checked'])) {
print '<td class="liste_titre"><input type="text" class="flat width100" name="search_pcgtype" value="'.$search_pcgtype.'"></td>';
print '<td class="liste_titre"><input type="text" class="flat width75" name="search_pcgtype" value="'.$search_pcgtype.'"></td>';
}
// Custom groups
if (!empty($arrayfields['categories']['checked'])) {
print '<td class="liste_titre"></td>';
}
// Import key
if (!empty($arrayfields['aa.import_key']['checked'])) {
print '<td class="liste_titre"><input type="text" class="flat width75" name="search_import_key" value="'.$search_import_key.'"></td>';
}
if ($conf->global->MAIN_FEATURES_LEVEL >= 2) {
if (!empty($arrayfields['aa.reconcilable']['checked'])) {
@ -460,6 +484,12 @@ if ($resql) {
if (!empty($arrayfields['aa.pcg_type']['checked'])) {
print_liste_field_titre($arrayfields['aa.pcg_type']['label'], $_SERVER["PHP_SELF"], 'aa.pcg_type,aa.account_number', '', $param, '', $sortfield, $sortorder, '', $arrayfields['aa.pcg_type']['help'], 1);
}
if (!empty($arrayfields['categories']['checked'])) {
print_liste_field_titre($arrayfields['categories']['label'], $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, '', $arrayfields['categories']['help'], 1);
}
if (!empty($arrayfields['aa.import_key']['checked'])) {
print_liste_field_titre($arrayfields['aa.import_key']['label'], $_SERVER["PHP_SELF"], 'aa.import_key', '', $param, '', $sortfield, $sortorder, '', $arrayfields['aa.import_key']['help'], 1);
}
if ($conf->global->MAIN_FEATURES_LEVEL >= 2) {
if (!empty($arrayfields['aa.reconcilable']['checked'])) {
print_liste_field_titre($arrayfields['aa.reconcilable']['label'], $_SERVER["PHP_SELF"], 'aa.reconcilable', '', $param, '', $sortfield, $sortorder);
@ -494,7 +524,7 @@ if ($resql) {
// Account label
if (!empty($arrayfields['aa.label']['checked'])) {
print "<td>";
print $obj->label;
print dol_escape_htmltag($obj->label);
print "</td>\n";
if (!$i) {
$totalarray['nbfield']++;
@ -504,7 +534,7 @@ if ($resql) {
// Account label to show (label short)
if (!empty($arrayfields['aa.labelshort']['checked'])) {
print "<td>";
print $obj->labelshort;
print dol_escape_htmltag($obj->labelshort);
print "</td>\n";
if (!$i) {
$totalarray['nbfield']++;
@ -538,10 +568,30 @@ if ($resql) {
}
}
// Chart of accounts type
// Predefined group (deprecated)
if (!empty($arrayfields['aa.pcg_type']['checked'])) {
print "<td>";
print $obj->pcg_type;
print dol_escape_htmltag($obj->pcg_type);
print "</td>\n";
if (!$i) {
$totalarray['nbfield']++;
}
}
// Custom accounts
if (!empty($arrayfields['categories']['checked'])) {
print "<td>";
// TODO Get all custom groups labels the account is in
print dol_escape_htmltag($obj->fk_accounting_category);
print "</td>\n";
if (!$i) {
$totalarray['nbfield']++;
}
}
// Import id
if (!empty($arrayfields['aa.import_key']['checked'])) {
print "<td>";
print dol_escape_htmltag($obj->import_key);
print "</td>\n";
if (!$i) {
$totalarray['nbfield']++;
@ -588,7 +638,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();
@ -639,7 +640,8 @@ if ($id) {
foreach ($fieldlist as $field => $value) {
$showfield = 1;
$class = "left";
$valuetoshow = $obj->{$fieldlist[$field]};
$tmpvar = $fieldlist[$field];
$valuetoshow = $obj->$tmpvar;
if ($value == 'type_template') {
$valuetoshow = isset($elementList[$valuetoshow]) ? $elementList[$valuetoshow] : $valuetoshow;
}
@ -674,7 +676,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');
@ -84,7 +85,7 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) {
// Clean code
// To manage zero or not at the end of the accounting account
if ($conf->global->ACCOUNTING_MANAGE_ZERO == 1) {
if (!empty($conf->global->ACCOUNTING_MANAGE_ZERO)) {
$account_number = $account_number;
} else {
$account_number = clean_account($account_number);
@ -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');
@ -147,7 +148,7 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) {
// Clean code
// To manage zero or not at the end of the accounting account
if (isset($conf->global->ACCOUNTING_MANAGE_ZERO) && $conf->global->ACCOUNTING_MANAGE_ZERO == 1) {
if (!empty($conf->global->ACCOUNTING_MANAGE_ZERO)) {
$account_number = $account_number;
} else {
$account_number = clean_account($account_number);
@ -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)) {
@ -278,7 +282,7 @@ if ($action == 'create') {
print $form->textwithpicto($langs->trans("AccountingCategory"), $langs->transnoentitiesnoconv("AccountingAccountGroupsDesc"));
print '</td>';
print '<td>';
$formaccounting->select_accounting_category($object->account_category, 'account_category', 1, 0, 1);
print $formaccounting->select_accounting_category($object->account_category, 'account_category', 1, 0, 1);
print '</td></tr>';
print '</table>';
@ -325,7 +329,8 @@ if ($action == 'create') {
// Account parent
print '<tr><td>'.$langs->trans("Accountparent").'</td>';
print '<td>';
print $formaccounting->select_account($object->account_parent, 'account_parent', 1);
// Note: We accept disabled account as parent account so we can build a hierarchy and use only childs
print $formaccounting->select_account($object->account_parent, 'account_parent', 1, array(), 0, 0, 'minwidth100 maxwidth300 maxwidthonsmartphone', 1, '');
print '</td></tr>';
// Chart of accounts type
@ -354,7 +359,7 @@ if ($action == 'create') {
print $form->textwithpicto($langs->trans("AccountingCategory"), $langs->transnoentitiesnoconv("AccountingAccountGroupsDesc"));
print '</td>';
print '<td>';
$formaccounting->select_accounting_category($object->account_category, 'account_category', 1);
print $formaccounting->select_accounting_category($object->account_category, 'account_category', 1);
print '</td></tr>';
print '</table>';
@ -416,17 +421,15 @@ 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)) {
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>';
}
// Delete
$permissiontodelete = $user->hasRight('accounting', 'chartofaccount');
print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', $permissiontodelete);
print '</div>';
}

View File

@ -1,6 +1,7 @@
<?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>
* Copyright (C) 2022 Laurent Destailleur <eldy@users.sourceforge.net>
*
* 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 +23,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';
@ -30,7 +32,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"));
$langs->loadLangs(array("bills", "accountancy", "compta"));
$id = GETPOST('id', 'int');
$cancel = GETPOST('cancel', 'alpha');
@ -43,8 +45,28 @@ if ($cat_id == 0) {
$cat_id = null;
}
// Load variable for pagination
$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'aZ09comma');
$sortorder = GETPOST('sortorder', 'aZ09comma');
$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int');
if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
// If $page is not defined, or '' or -1 or if we click on clear filters
$page = 0;
}
$offset = $limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
if (empty($sortfield)) {
$sortfield = 'account_number';
}
if (empty($sortorder)) {
$sortorder = 'ASC';
}
// Security check
if (empty($user->rights->accounting->chartofaccount)) {
if (!$user->hasRight('accounting', 'chartofaccount')) {
accessforbidden();
}
@ -109,52 +131,49 @@ print '<table class="border centpercent">';
// Select the category
print '<tr><td class="titlefield">'.$langs->trans("AccountingCategory").'</td>';
print '<td>';
$formaccounting->select_accounting_category($cat_id, 'account_category', 1, 0, 0, 1);
print '<input type="submit" class="button" value="'.$langs->trans("Select").'">';
print $formaccounting->select_accounting_category($cat_id, 'account_category', 1, 0, 0, 0);
print '<input type="submit" class="button small" value="'.$langs->trans("Select").'">';
print '</td></tr>';
print '</table>';
print dol_get_fiche_end();
// Select the accounts
if (!empty($cat_id)) {
$return = $accountingcategory->getAccountsWithNoCategory($cat_id);
if ($return < 0) {
setEventMessages(null, $accountingcategory->errors, 'errors');
}
print '<tr><td>'.$langs->trans("AddAccountFromBookKeepingWithNoCategories").'</td>';
print '<td>';
print '<br>';
$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) {
print $form->multiselectarray('cpt_bk', $arraykeyvalue, GETPOST('cpt_bk', 'array'), null, null, null, null, "90%");
print '<br>';
/*print '<select class="flat minwidth200" size="8" name="cpt_bk[]" multiple>';
foreach ( $accountingcategory->lines_cptbk as $cpt ) {
print '<option value="' . length_accountg($cpt->numero_compte) . '">' . length_accountg($cpt->numero_compte) . ' (' . $cpt->label_compte . ' ' . $cpt->doc_ref . ')</option>';
}
print '</select><br>';
print ajax_combobox('cpt_bk');
*/
print '<input type="submit" class="button button-add" id="" class="action-delete" value="'.$langs->trans("Add").'"> ';
print img_picto($langs->trans("AccountingAccount"), 'accounting_account', 'class="pictofixedwith"');
print $form->multiselectarray('cpt_bk', $arraykeyvalue, GETPOST('cpt_bk', 'array'), null, null, '', 0, "80%", '', '', $langs->transnoentitiesnoconv("AddAccountFromBookKeepingWithNoCategories"));
print '<input type="submit" class="button button-add small" id="" class="action-delete" value="'.$langs->trans("Add").'"> ';
}
print '</td></tr>';
}
print '</table>';
print dol_get_fiche_end();
print '</form>';
if ($action == 'display' || $action == 'delete') {
print "<table class='noborder' width='100%'>\n";
if ((empty($action) || $action == 'display' || $action == 'delete') && $cat_id > 0) {
$param = 'account_category='.((int) $cat_id);
print '<br>';
print '<table class="noborder centpercent">'."\n";
print '<tr class="liste_titre">';
print '<td class="liste_titre">'.$langs->trans("AccountAccounting")."</td>";
print '<td class="liste_titre" colspan="2">'.$langs->trans("Label")."</td>";
print "</tr>\n";
print getTitleFieldOfList('AccountAccounting', 0, $_SERVER['PHP_SELF'], 'account_number', '', $param, '', $sortfield, $sortorder, '')."\n";
print getTitleFieldOfList('Label', 0, $_SERVER['PHP_SELF'], 'label', '', $param, '', $sortfield, $sortorder, '')."\n";
print getTitleFieldOfList('', 0, $_SERVER['PHP_SELF'], '', '', $param, '', $sortfield, $sortorder, '')."\n";
print '</tr>'."\n";
if (!empty($cat_id)) {
$return = $accountingcategory->display($cat_id); // This load ->lines_display
@ -163,6 +182,8 @@ if ($action == 'display' || $action == 'delete') {
}
if (is_array($accountingcategory->lines_display) && count($accountingcategory->lines_display) > 0) {
$accountingcategory->lines_display = dol_sort_array($accountingcategory->lines_display, $sortfield, $sortorder, -1, 0, 1);
foreach ($accountingcategory->lines_display as $cpt) {
print '<tr class="oddeven">';
print '<td>'.length_accountg($cpt->account_number).'</td>';
@ -175,6 +196,8 @@ if ($action == 'display' || $action == 'delete') {
print "</td>";
print "</tr>\n";
}
} else {
print '<tr><td colspan="3"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
}
}

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();
@ -189,7 +190,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors');
}
}
if (!is_numeric(GETPOST('position', 'alpha'))) {
if (GETPOST('position') && !is_numeric(GETPOST('position', 'alpha'))) {
$langs->loadLangs(array("errors"));
$ok = 0;
setEventMessages($langs->transnoentities('ErrorFieldMustBeANumeric', $langs->transnoentities("Position")), null, 'errors');
@ -443,15 +444,37 @@ if ($search_country_id > 0) {
if ($sortfield == 'country') {
$sortfield = 'country_code';
}
if (empty($sortfield)) {
$sortfield = 'position';
}
$sql .= $db->order($sortfield, $sortorder);
$sql .= $db->plimit($listlimit + 1, $offset);
//print $sql;
$fieldlist = explode(',', $tabfield[$id]);
$param = '&id='.$id;
if ($search_country_id > 0) {
$param .= '&search_country_id='.urlencode($search_country_id);
}
$paramwithsearch = $param;
if ($sortorder) {
$paramwithsearch .= '&sortorder='.urlencode($sortorder);
}
if ($sortfield) {
$paramwithsearch .= '&sortfield='.urlencode($sortfield);
}
if (GETPOST('from', 'alpha')) {
$paramwithsearch .= '&from='.urlencode(GETPOST('from', 'alpha'));
}
print '<form action="'.$_SERVER['PHP_SELF'].'?id='.$id.'" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="from" value="'.dol_escape_htmltag(GETPOST('from', 'alpha')).'">';
print '<input type="hidden" name="sortfield" value="'.dol_escape_htmltag($sortfield).'">';
print '<input type="hidden" name="sortorder" value="'.dol_escape_htmltag($sortorder).'">';
print '<div class="div-table-responsive">';
print '<table class="noborder centpercent">';
@ -570,20 +593,6 @@ if ($resql) {
$num = $db->num_rows($resql);
$i = 0;
$param = '&id='.$id;
if ($search_country_id > 0) {
$param .= '&search_country_id='.urlencode($search_country_id);
}
$paramwithsearch = $param;
if ($sortorder) {
$paramwithsearch .= '&sortorder='.$sortorder;
}
if ($sortfield) {
$paramwithsearch .= '&sortfield='.$sortfield;
}
if (GETPOST('from', 'alpha')) {
$paramwithsearch .= '&from='.GETPOST('from', 'alpha');
}
// There is several pages
if ($num > $listlimit) {
print '<tr class="none"><td class="right" colspan="'.(3 + count($fieldlist)).'">';
@ -604,7 +613,7 @@ if ($resql) {
if ($showfield) {
if ($value == 'country') {
print '<td class="liste_titre">';
print $form->select_country($search_country_id, 'search_country_id', '', 28, 'maxwidth200 maxwidthonsmartphone');
print $form->select_country($search_country_id, 'search_country_id', '', 28, 'maxwidth150 maxwidthonsmartphone');
print '</td>';
$filterfound++;
} else {
@ -724,11 +733,11 @@ if ($resql) {
print '<td></td>';
print '<td></td>';
print '<td class="center">';
print '<div name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'"></div>';
print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="rowid" value="'.$rowid.'">';
print '<input type="submit" class="button button-edit" name="actionmodify" value="'.$langs->trans("Modify").'">';
print '<div name="'.(!empty($obj->rowid) ? $obj->rowid : $obj->code).'"></div>';
print '<input type="submit" class="button button-cancel" name="actioncancel" value="'.$langs->trans("Cancel").'">';
print '<input type="submit" class="button button-edit smallpaddingimp" name="actionmodify" value="'.$langs->trans("Modify").'">';
print '<input type="submit" class="button button-cancel smallpaddingimp" name="actioncancel" value="'.$langs->trans("Cancel").'">';
print '</td>';
print '<td></td>';
} else {
@ -742,7 +751,8 @@ if ($resql) {
foreach ($fieldlist as $field => $value) {
$showfield = 1;
$class = "left";
$valuetoshow = $obj->{$fieldlist[$field]};
$tmpvar = $fieldlist[$field];
$valuetoshow = $obj->$tmpvar;
if ($value == 'category_type') {
$valuetoshow = yn($valuetoshow);
} elseif ($valuetoshow == 'all') {
@ -821,7 +831,7 @@ if ($resql) {
}
// Link to setup the group
print '<td class="center">';
print '<td>';
if (empty($obj->formula)) {
print '<a href="'.DOL_URL_ROOT.'/accountancy/admin/categories.php?action=display&save_lastsearch_values=1&account_category='.$obj->rowid.'">';
print $langs->trans("ListOfAccounts");
@ -875,7 +885,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 +895,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, 'maxwidth150 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, 'maxwidth150 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,24 +81,26 @@ $list_account[] = '---Others---';
$list_account[] = 'ACCOUNTING_VAT_BUY_ACCOUNT';
$list_account[] = 'ACCOUNTING_VAT_SOLD_ACCOUNT';
$list_account[] = 'ACCOUNTING_VAT_PAY_ACCOUNT';
if (!empty($conf->banque->enabled)) {
if (isModEnabled('banque')) {
$list_account[] = 'ACCOUNTING_ACCOUNT_TRANSFER_CASH';
}
if (!empty($conf->don->enabled)) {
if (!empty($conf->global->INVOICE_USE_RETAINED_WARRANTY)) {
$list_account[] = 'ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY';
}
if (isModEnabled('don')) {
$list_account[] = 'DONATION_ACCOUNTINGACCOUNT';
}
if (!empty($conf->adherent->enabled)) {
if (isModEnabled('adherent')) {
$list_account[] = 'ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT';
}
if (!empty($conf->loan->enabled)) {
if (isModEnabled('loan')) {
$list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_CAPITAL';
$list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INTEREST';
$list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INSURANCE';
}
$list_account[] = 'ACCOUNTING_ACCOUNT_SUSPENSE';
if (!empty($conf->societe->enabled)) {
if (isModEnabled('societe')) {
$list_account[] = '---Deposits---';
$list_account[] = 'ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT';
}
/*
@ -106,7 +108,7 @@ if (!empty($conf->societe->enabled)) {
*/
if ($action == 'update') {
$error = 0;
// Process $list_account_main
foreach ($list_account_main as $constname) {
$constvalue = GETPOST($constname, 'alpha');
@ -114,7 +116,7 @@ if ($action == 'update') {
$error++;
}
}
// Process $list_account
foreach ($list_account as $constname) {
$reg = array();
if (preg_match('/---(.*)---/', $constname, $reg)) { // This is a separator
@ -128,6 +130,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 {
@ -135,7 +150,7 @@ if ($action == 'update') {
}
}
if ($action == 'setdisableauxiliaryaccountoncustomerdeposit') {
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)) {
@ -149,6 +164,20 @@ if ($action == 'setdisableauxiliaryaccountoncustomerdeposit') {
}
}
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
@ -195,7 +224,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>';
}
@ -246,15 +276,55 @@ foreach ($list_account as $key) {
}
}
if (!empty($conf->societe->enabled)) {
// 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 (!empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT)) {
print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setdisableauxiliaryaccountoncustomerdeposit&value=0">';
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=setdisableauxiliaryaccountoncustomerdeposit&value=1">';
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>';
}
@ -264,7 +334,7 @@ if (!empty($conf->societe->enabled)) {
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();
}
@ -211,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>';
}
}
@ -239,7 +239,7 @@ if (!$conf->use_javascript_ajax) {
} 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);
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';
@ -52,7 +53,7 @@ $langs->loadLangs(array("admin", "compta"));
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->fiscalyear->write)) { // If we can read accounting records, we should be able to see fiscal year.
if (!$user->hasRight('accounting', 'fiscalyear', 'write')) { // If we can read accounting records, we should be able to see fiscal year.
accessforbidden();
}
@ -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';
@ -34,7 +35,7 @@ $langs->loadLangs(array("admin", "compta"));
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->fiscalyear->write)) {
if (!$user->hasRight('accounting', 'fiscalyear', 'write')) {
accessforbidden();
}
@ -299,12 +300,12 @@ 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>';
// print '<a class="butActionDelete" href="' . $_SERVER["PHP_SELF"] . '?action=delete&token='.newToken().'&id=' . $id . '">' . $langs->trans('Delete') . '</a>';
//print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', $permissiontodelete);
print '</div>';
}

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';
@ -33,7 +34,7 @@ $langs->loadLangs(array("admin", "compta"));
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->fiscalyear->write)) {
if (!$user->hasRight('accounting', 'fiscalyear', 'write')) {
accessforbidden();
}

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();
}
@ -246,6 +247,34 @@ if ($action == 'setdisablebindingonexpensereports') {
}
}
if ($action == 'setenablelettering') {
$setenablelettering = GETPOST('value', 'int');
$res = dolibarr_set_const($db, "ACCOUNTING_ENABLE_LETTERING", $setenablelettering, '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 == 'setenableautolettering') {
$setenableautolettering = GETPOST('value', 'int');
$res = dolibarr_set_const($db, "ACCOUNTING_ENABLE_AUTOLETTERING", $setenableautolettering, 'yesno', 0, '', $conf->entity);
if (!($res > 0)) {
$error++;
}
if (!$error) {
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
} else {
setEventMessages($langs->trans("Error"), null, 'mesgs');
}
}
/*
* View
@ -265,6 +294,9 @@ if (!$user->admin) {
if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
print '<div class="info">' . $langs->trans("ConstantIsOn", "FACTURE_DEPOSITS_ARE_JUST_PAYMENTS") . '</div>';
}
if (!empty($conf->global->FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS)) {
print '<div class="info">' . $langs->trans("ConstantIsOn", "FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS") . '</div>';
}
if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) {
print '<div class="info">' . $langs->trans("ConstantIsOn", "ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY") . '</div>';
}
@ -358,7 +390,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 +441,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));
print $form->selectarray($key, $array, (isset($conf->global->ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER) ? $conf->global->ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER : 0), 0, 0, 0, '', 0, 0, 0, '', 'onrightofpage');
} 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>';
@ -460,6 +492,43 @@ if (!empty($conf->global->ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS)) {
}
print '</tr>';
print '</table>';
print '<br>';
// Lettering params
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td colspan="2">'.$langs->trans('Options').' '.$langs->trans('Lettering').'</td>';
print "</tr>\n";
print '<tr class="oddeven">';
print '<td>'.$langs->trans("ACCOUNTING_ENABLE_LETTERING").'</td>';
if (!empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) {
print '<td class="right"><a class="reposition" href="'.$_SERVER['PHP_SELF'].'?token='.newToken().'&action=setenablelettering&value=0">';
print img_picto($langs->trans("Activated"), 'switch_on');
print '</a></td>';
} else {
print '<td class="right"><a class="reposition" href="'.$_SERVER['PHP_SELF'].'?token='.newToken().'&action=setenablelettering&value=1">';
print img_picto($langs->trans("Disabled"), 'switch_off');
print '</a></td>';
}
print '</tr>';
if (!empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) {
print '<tr class="oddeven">';
print '<td>' . $langs->trans("ACCOUNTING_ENABLE_AUTOLETTERING") . '</td>';
if (!empty($conf->global->ACCOUNTING_ENABLE_AUTOLETTERING)) {
print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setenableautolettering&value=0">';
print img_picto($langs->trans("Activated"), 'switch_on');
print '</a></td>';
} else {
print '<td class="right"><a class="reposition" href="' . $_SERVER['PHP_SELF'] . '?token=' . newToken() . '&action=setenableautolettering&value=1">';
print img_picto($langs->trans("Disabled"), 'switch_off');
print '</a></td>';
}
print '</tr>';
}
print '</table>';
print '<div class="center"><input type="submit" class="button button-edit" name="button" value="'.$langs->trans('Modify').'"></div>';

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();
@ -584,7 +587,8 @@ if ($id) {
foreach ($fieldlist as $field => $value) {
$showfield = 1;
$class = "left";
$valuetoshow = $obj->{$fieldlist[$field]};
$tmpvar = $fieldlist[$field];
$valuetoshow = $obj->$tmpvar;
if ($valuetoshow == 'all') {
$valuetoshow = $langs->trans('All');
} elseif ($fieldlist[$field] == 'nature' && $tabname[$id] == MAIN_DB_PREFIX.'accounting_journal') {
@ -608,12 +612,6 @@ if ($id) {
if (($obj->code == '0' || $obj->code == '' || preg_match('/unknown/i', $obj->code))) {
$iserasable = 0;
$canbedisabled = 0;
} elseif ($obj->code == 'RECEP') {
$iserasable = 0;
$canbedisabled = 0;
} elseif ($obj->code == 'EF0') {
$iserasable = 0;
$canbedisabled = 0;
}
}

View File

@ -34,7 +34,7 @@ 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 (!empty($conf->categorie->enabled)) {
if (isModEnabled('categorie')) {
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
}
@ -42,10 +42,10 @@ if (!empty($conf->categorie->enabled)) {
$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)) {
if (!$user->hasRight('accounting', 'bind', 'write')) {
accessforbidden();
}
@ -522,7 +522,7 @@ if ($resql) {
// Filter on categories
$moreforfilter = '';
if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) {
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);
@ -533,7 +533,7 @@ if ($resql) {
}
//Show/hide child products. Hidden by default
if (!empty($conf->variants->enabled) && !empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) {
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>';

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();
}
@ -407,7 +408,7 @@ if ($resql) {
$s .= '<a class="vendor-back" style="padding-left: 6px; padding-right: 6px" title="'.$langs->trans("Supplier").'" href="'.DOL_URL_ROOT.'/fourn/card.php?socid='.$obj->rowid.'">'.$langs->trans("Supplier").'</a>';
} elseif ($obj->type == 3) {
// User
$s .= '<a class="user-back" style="padding-left: 6px; padding-right: 6px" title="'.$langs->trans("Employee").'" href="'.DOL_URL_ROOT.'/user/card.php?id='.$obj->id.'">'.$langs->trans("Employee").'</a>';
$s .= '<a class="user-back" style="padding-left: 6px; padding-right: 6px" title="'.$langs->trans("Employee").'" href="'.DOL_URL_ROOT.'/user/card.php?id='.$obj->rowid.'">'.$langs->trans("Employee").'</a>';
}
print $s;
print '</td>';

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,13 +144,13 @@ if (!empty($search_ledger_code)) {
}
}
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->mouvements->lire)) {
if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
accessforbidden();
}
@ -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');
@ -236,10 +239,17 @@ if ($action != 'export_csv') {
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="page" value="'.$page.'">';
$parameters = array();
$reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
}
$button = empty($hookmanager->resPrint) ? '' : $hookmanager->resPrint;
if (empty($reshook)) {
$button = '<input type="button" id="exportcsvbutton" name="exportcsvbutton" class="butAction" value="'.$langs->trans("Export").' ('.$conf->global->ACCOUNTING_EXPORT_FORMAT.')" />';
$button .= '<input type="button" id="exportcsvbutton" name="exportcsvbutton" class="butAction" value="'.$langs->trans("Export").' ('.$conf->global->ACCOUNTING_EXPORT_FORMAT.')" />';
print '<script type="text/javascript">
jQuery(document).ready(function() {
@ -494,6 +504,10 @@ if ($action != 'export_csv') {
print "<td></td>\n";
print '</tr>';
$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
print "</table>";
print '</form>';
}

View File

@ -1,9 +1,10 @@
<?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>
* Copyright (C) 2022 Waël Almoman <info@almoman.com>
*
* 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
@ -25,6 +26,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';
@ -43,7 +45,7 @@ $cancel = GETPOST('cancel', 'aZ09');
$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
$id = GETPOST('id', 'int'); // id of record
$mode = GETPOST('mode', 'aZ09'); // '' or '_tmp'
$mode = $mode = $action == 'create' ? "_tmp" : GETPOST('mode', 'aZ09'); // '' or '_tmp'
$piece_num = GETPOST("piece_num", 'int'); // id of transaction (several lines share the same transaction id)
$accountingaccount = new AccountingAccount($db);
@ -53,10 +55,15 @@ $accountingaccount_number = GETPOST('accountingaccount_number', 'alphanohtml');
$accountingaccount->fetch(null, $accountingaccount_number, true);
$accountingaccount_label = $accountingaccount->label;
$journal_code = GETPOST('code_journal', 'alpha');
$journal_code = GETPOST('code_journal', 'alpha') ? GETPOST('code_journal', 'alpha') : "NULL";
$accountingjournal->fetch(null, $journal_code);
$journal_label = $accountingjournal->label;
$next_num_mvt = (int) GETPOST('next_num_mvt', 'alpha');
$doc_ref = (string) GETPOST('doc_ref', 'alpha');
$doc_date = (string) GETPOST('doc_date', 'alpha');
$doc_date = $doc_date = dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int'));
$subledger_account = GETPOST('subledger_account', 'alphanohtml');
if ($subledger_account == -1) {
$subledger_account = null;
@ -71,6 +78,10 @@ $save = GETPOST('save', 'alpha');
if (!empty($save)) {
$action = 'add';
}
$valid = GETPOST('validate', 'alpha');
if (!empty($valid)) {
$action = 'valid';
}
$update = GETPOST('update', 'alpha');
if (!empty($update)) {
$action = 'confirm_update';
@ -79,13 +90,13 @@ if (!empty($update)) {
$object = new BookKeeping($db);
// Security check
if (empty($conf->accounting->enabled)) {
if (!isModEnabled('accounting')) {
accessforbidden();
}
if ($user->socid > 0) {
accessforbidden();
}
if (empty($user->rights->accounting->mouvements->lire)) {
if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
accessforbidden();
}
@ -155,64 +166,79 @@ if ($action == "confirm_update") {
}
}
}
} elseif ($action == "add") {
} elseif ($action == 'add' || $action == 'valid') {
$error = 0;
if ((floatval($debit) != 0.0) && (floatval($credit) != 0.0)) {
$error++;
setEventMessages($langs->trans('ErrorDebitCredit'), null, 'errors');
$action = '';
}
if (empty($accountingaccount_number) || $accountingaccount_number == '-1') {
$error++;
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("AccountAccountingShort")), null, 'errors');
$action = '';
if (array_sum($debit) != array_sum($credit)) {
$action = 'add';
}
if (!$error) {
$object = new BookKeeping($db);
foreach ($accountingaccount_number as $key => $value) {
$accountingaccount->fetch(null, $accountingaccount_number[$key], true);
$accountingaccount_label[$key] = $accountingaccount->label[$key];
$object->numero_compte = $accountingaccount_number;
$object->subledger_account = $subledger_account;
$object->subledger_label = $subledger_label;
$object->label_compte = $accountingaccount_label;
$object->label_operation = $label_operation;
$object->debit = $debit;
$object->credit = $credit;
$object->doc_date = (string) GETPOST('doc_date', 'alpha');
$object->doc_type = (string) GETPOST('doc_type', 'alpha');
$object->piece_num = $piece_num;
$object->doc_ref = (string) GETPOST('doc_ref', 'alpha');
$object->code_journal = $journal_code;
$object->journal_label = $journal_label;
$object->fk_doc = GETPOSTINT('fk_doc');
$object->fk_docdet = GETPOSTINT('fk_docdet');
if (floatval($debit) != 0.0) {
$object->montant = $debit; // deprecated
$object->amount = $debit;
$object->sens = 'D';
// if one added row is empty remove it before continue
if ($key < 1 && (empty($accountingaccount_number[$key]) || $accountingaccount_number[$key] == '-1') || (floatval($debit[$key]) == 0.0) && (floatval($credit[$key]) == 0.0)) {
continue;
}
if (floatval($credit) != 0.0) {
$object->montant = $credit; // deprecated
$object->amount = $credit;
$object->sens = 'C';
}
$result = $object->createStd($user, false, $mode);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
} else {
if ($mode != '_tmp') {
setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
}
$debit = 0;
$credit = 0;
if ((floatval($debit[$key]) != 0.0) && (floatval($credit[$key]) != 0.0)) {
$error++;
setEventMessages($langs->trans('ErrorDebitCredit'), null, 'errors');
$action = '';
}
if (empty($accountingaccount_number[$key]) || $accountingaccount_number[$key] == '-1') {
$error++;
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("AccountAccountingShort")), null, 'errors');
$action = '';
}
if (!$error) {
$object = new BookKeeping($db);
$object->numero_compte = $accountingaccount_number[$key];
$object->subledger_account = $subledger_account[$key];
$object->subledger_label = $subledger_label[$key];
$object->label_compte = $accountingaccount_label[$key];
$object->label_operation = $label_operation[$key];
$object->debit = price2num($debit[$key]);
$object->credit = price2num($credit[$key]);
$object->doc_date = $doc_date;
$object->doc_type = (string) GETPOST('doc_type', 'alpha');
$object->piece_num = $piece_num;
$object->doc_ref = $doc_ref;
$object->code_journal = $journal_code;
$object->journal_label = $journal_label;
$object->fk_doc = GETPOSTINT('fk_doc');
$object->fk_docdet = GETPOSTINT('fk_docdet');
if (floatval($debit[$key]) != 0.0) {
$object->montant = $object->debit; // deprecated
$object->amount = $object->debit;
$object->sens = 'D';
}
if (floatval($credit[$key]) != 0.0) {
$object->montant = $object->credit; // deprecated
$object->amount = $object->credit;
$object->sens = 'C';
}
$result = $object->createStd($user, false, $mode);
if ($result < 0) {
$error++;
setEventMessages($object->error, $object->errors, 'errors');
}
}
}
if (empty($error)) {
if ($mode != '_tmp') {
setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
}
$debit = 0;
$credit = 0;
$action = $action == 'add' ? '' : $action ; // stay in valid mode when not adding line
}
} elseif ($action == "confirm_delete") {
$object = new BookKeeping($db);
@ -229,17 +255,28 @@ if ($action == "confirm_update") {
}
}
$action = '';
} elseif ($action == "confirm_create") {
} elseif ($action == 'create') {
$error = 0;
$object = new BookKeeping($db);
$next_num_mvt = !empty($next_num_mvt) ? $next_num_mvt : $object->getNextNumMvt('_tmp');
$doc_ref = !empty($doc_ref) ? $doc_ref : $next_num_mvt;
if (empty($doc_date)) {
$tmp_date = dol_getdate(dol_now());
$_POST['doc_dateday'] = $tmp_date['mday'];
$_POST['doc_datemonth'] = $tmp_date['mon'];
$_POST['doc_dateyear'] = $tmp_date['year'];
unset($tmp_date);
}
if (!$journal_code || $journal_code == '-1') {
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Journal")), null, 'errors');
$action = 'create';
$error++;
}
if (!GETPOST('doc_ref', 'alpha')) {
if (empty($doc_ref)) {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Piece")), null, 'errors');
$action = 'create';
$error++;
@ -251,8 +288,8 @@ if ($action == "confirm_update") {
$object->credit = 0;
$object->doc_date = $date_start = dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int'));
$object->doc_type = GETPOST('doc_type', 'alpha');
$object->piece_num = GETPOST('next_num_mvt', 'alpha');
$object->doc_ref = GETPOST('doc_ref', 'alpha');
$object->piece_num = $next_num_mvt;
$object->doc_ref = $doc_ref;
$object->code_journal = $journal_code;
$object->journal_label = $journal_label;
$object->fk_doc = 0;
@ -301,7 +338,7 @@ if ($action == 'setjournal') {
}
if ($action == 'setdocref') {
$refdoc = GETPOST('doc_ref', 'alpha');
$refdoc = $doc_ref;
$result = $object->updateByMvt($piece_num, 'doc_ref', $refdoc, $mode);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
@ -332,7 +369,9 @@ if ($action == 'valid') {
$html = new Form($db);
$formaccounting = new FormAccounting($db);
llxHeader('', $langs->trans("CreateMvts"));
$title = $langs->trans($mode =="_tmp" ? "CreateMvts": "UpdateMvts");
llxHeader('', $title);
// Confirmation to delete the command
if ($action == 'delete') {
@ -340,28 +379,37 @@ if ($action == 'delete') {
print $formconfirm;
}
if ($action == 'create') {
print load_fiche_titre($langs->trans("CreateMvts"));
$object = new BookKeeping($db);
$next_num_mvt = $object->getNextNumMvt('_tmp');
$object = new BookKeeping($db);
$result = $object->fetchPerMvt($piece_num, $mode);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
if (empty($next_num_mvt)) {
dol_print_error('', 'Failed to get next piece number');
if (!empty($object->piece_num)) {
$backlink = '<a href="'.DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?restore_lastsearch_values=1">'.$langs->trans('BackToList').'</a>';
print load_fiche_titre($langs->trans($mode =="_tmp" ? "CreateMvts": "UpdateMvts"), $backlink);
print '<form action="'.$_SERVER["PHP_SELF"].'?piece_num='.$object->piece_num.'" method="post">'; if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'" />';
}
$head = array();
$h = 0;
$head[$h][0] = $_SERVER['PHP_SELF'].'?piece_num='.$object->piece_num.($mode ? '&mode='.$mode : '');
$head[$h][1] = $langs->trans("Transaction");
$head[$h][2] = 'transaction';
$h++;
print '<form action="'.$_SERVER["PHP_SELF"].'" name="create_mvt" method="POST">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
}
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="confirm_create">'."\n";
print '<input type="hidden" name="next_num_mvt" value="'.$next_num_mvt.'">'."\n";
print '<input type="hidden" name="mode" value="_tmp">'."\n";
print dol_get_fiche_head($head, 'transaction', '', -1);
print dol_get_fiche_head();
//dol_banner_tab($object, '', $backlink);
print '<table class="border centpercent">';
print '<div class="fichecenter">';
print '<div class="fichehalfleft">';
print '<div class="underbanner clearboth"></div>';
print '<table class="border tableforfield" width="100%">';
/*print '<tr>';
print '<td class="titlefieldcreate fieldrequired">' . $langs->trans("NumPiece") . '</td>';
@ -371,7 +419,7 @@ if ($action == 'create') {
print '<tr>';
print '<td class="titlefieldcreate fieldrequired">'.$langs->trans("Docdate").'</td>';
print '<td>';
print $html->selectDate('', 'doc_date', '', '', '', "create_mvt", 1, 1);
print $html->selectDate($doc_date, 'doc_date', '', '', '', "create_mvt", 1, 1);
print '</td>';
print '</tr>';
@ -382,164 +430,43 @@ if ($action == 'create') {
print '<tr>';
print '<td class="fieldrequired">'.$langs->trans("Piece").'</td>';
print '<td><input type="text" class="minwidth200" name="doc_ref" value="'.GETPOST('doc_ref', 'alpha').'"></td>';
print '<td><input type="text" class="minwidth200" name="doc_ref" value="'.$doc_ref.'" /></td>';
print '</tr>';
/*
print '<tr>';
print '<td>' . $langs->trans("Doctype") . '</td>';
print '<td><input type="text" class="minwidth200 name="doc_type" value=""/></td>';
print '<td><input type="text" class="minwidth200 name="doc_type" value="" /></td>';
print '</tr>';
*/
print '</table>';
print dol_get_fiche_end();
print '</div>';
print $form->buttonsSaveCancel("Create");
print '<div class="fichehalfright">';
print '</form>';
} else {
$object = new BookKeeping($db);
$result = $object->fetchPerMvt($piece_num, $mode);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
print '<div class="underbanner clearboth"></div>';
print '<table class="border tableforfield centpercent">';
// Doc type
if (!empty($object->doc_type)) {
print '<tr>';
print '<td class="titlefield">'.$langs->trans("Doctype").'</td>';
print '<td>'.$object->doc_type.'</td>';
print '</tr>';
}
if (!empty($object->piece_num)) {
$backlink = '<a href="'.DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?restore_lastsearch_values=1">'.$langs->trans('BackToList').'</a>';
print load_fiche_titre($langs->trans("UpdateMvts"), $backlink);
$head = array();
$h = 0;
$head[$h][0] = $_SERVER['PHP_SELF'].'?piece_num='.$object->piece_num.($mode ? '&mode='.$mode : '');
$head[$h][1] = $langs->trans("Transaction");
$head[$h][2] = 'transaction';
$h++;
print dol_get_fiche_head($head, 'transaction', '', -1);
//dol_banner_tab($object, '', $backlink);
print '<div class="fichecenter">';
print '<div class="fichehalfleft">';
print '<div class="underbanner clearboth"></div>';
print '<table class="border tableforfield" width="100%">';
// Account movement
print '<tr>';
print '<td class="titlefield">'.$langs->trans("NumMvts").'</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 centpercent"><tr><td>';
print $langs->trans('Docdate');
print '</td>';
if ($action != 'editdate') {
print '<td class="right"><a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editdate&token='.newToken().'&piece_num='.urlencode($object->piece_num).'&mode='.urlencode($mode).'">'.img_edit($langs->transnoentitiesnoconv('SetDate'), 1).'</a></td>';
}
print '</tr></table>';
print '</td><td colspan="3">';
if ($action == 'editdate') {
print '<form name="setdate" action="'.$_SERVER["PHP_SELF"].'?piece_num='.$object->piece_num.'" method="post">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
}
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="setdate">';
print '<input type="hidden" name="mode" value="'.$mode.'">';
print $form->selectDate($object->doc_date ? $object->doc_date : - 1, 'doc_date', '', '', '', "setdate");
print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
print '</form>';
} else {
print $object->doc_date ? dol_print_date($object->doc_date, 'day') : '&nbsp;';
}
print '</td>';
print '</tr>';
// Journal
print '<tr><td>';
print '<table class="nobordernopadding" width="100%"><tr><td>';
print $langs->trans('Codejournal');
print '</td>';
if ($action != 'editjournal') {
print '<td class="right"><a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editjournal&token='.newToken().'&piece_num='.urlencode($object->piece_num).'&mode='.urlencode($mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a></td>';
}
print '</tr></table>';
print '</td><td>';
if ($action == 'editjournal') {
print '<form name="setjournal" action="'.$_SERVER["PHP_SELF"].'?piece_num='.$object->piece_num.'" method="post">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
}
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="setjournal">';
print '<input type="hidden" name="mode" value="'.$mode.'">';
print $formaccounting->select_journal($object->code_journal, 'code_journal', 0, 0, array(), 1, 1);
print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
print '</form>';
} else {
print $object->code_journal;
}
print '</td>';
print '</tr>';
// Ref document
print '<tr><td>';
print '<table class="nobordernopadding" width="100%"><tr><td>';
print $langs->trans('Piece');
print '</td>';
if ($action != 'editdocref') {
print '<td class="right"><a class="editfielda reposition" href="'.$_SERVER["PHP_SELF"].'?action=editdocref&token='.newToken().'&piece_num='.urlencode($object->piece_num).'&mode='.urlencode($mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).'</a></td>';
}
print '</tr></table>';
print '</td><td>';
if ($action == 'editdocref') {
print '<form name="setdocref" action="'.$_SERVER["PHP_SELF"].'?piece_num='.$object->piece_num.'" method="post">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
}
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="setdocref">';
print '<input type="hidden" name="mode" value="'.$mode.'">';
print '<input type="text" size="20" name="doc_ref" value="'.dol_escape_htmltag($object->doc_ref).'">';
print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
print '</form>';
} else {
print $object->doc_ref;
}
print '</td>';
print '</tr>';
print '</table>';
print '</div>';
print '<div class="fichehalfright">';
print '<div class="underbanner clearboth"></div>';
print '<table class="border tableforfield centpercent">';
// Doc type
if (!empty($object->doc_type)) {
print '<tr>';
print '<td class="titlefield">'.$langs->trans("Doctype").'</td>';
print '<td>'.$object->doc_type.'</td>';
print '</tr>';
}
// Date document creation
print '<tr>';
print '<td class="titlefield">'.$langs->trans("DateCreation").'</td>';
print '<td>';
print $object->date_creation ? dol_print_date($object->date_creation, 'day') : '&nbsp;';
print '</td>';
print '</tr>';
// Date document creation
print '<tr>';
print '<td class="titlefield">'.$langs->trans("DateCreation").'</td>';
print '<td>';
print $object->date_creation ? dol_print_date($object->date_creation, 'day') : '&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>';
@ -555,117 +482,166 @@ if ($action == 'create') {
print $object->date_validation ? dol_print_date($object->date_validation, 'dayhour') : '&nbsp;';
print '</td>';
print '</tr>';
// Validate
/*
print '<tr>';
print '<td class="titlefield">' . $langs->trans("Status") . '</td>';
print '<td>';
if (empty($object->validated)) {
print '<a class="reposition" href="' . $_SERVER["PHP_SELF"] . '?piece_num=' . $line->id . '&action=enable&token='.newToken().'">';
print img_picto($langs->trans("Disabled"), 'switch_off');
print '</a>';
} else {
print '<a class="reposition" href="' . $_SERVER["PHP_SELF"] . '?piece_num=' . $line->id . '&action=disable&token='.newToken().'">';
print img_picto($langs->trans("Activated"), 'switch_on');
print '</a>';
}
print '</td>';
print '</tr>';
*/
}
// Validate
/*
print '<tr>';
print '<td class="titlefield">' . $langs->trans("Status") . '</td>';
print '<td>';
if (empty($object->validated)) {
print '<a class="reposition" href="' . $_SERVER["PHP_SELF"] . '?piece_num=' . $line->id . '&action=enable&token='.newToken().'">';
print img_picto($langs->trans("Disabled"), 'switch_off');
print '</a>';
} else {
print '<a class="reposition" href="' . $_SERVER["PHP_SELF"] . '?piece_num=' . $line->id . '&action=disable&token='.newToken().'">';
print img_picto($langs->trans("Activated"), 'switch_on');
print '</a>';
}
print '</td>';
print '</tr>';
*/
// check data
/*
print '<tr>';
print '<td class="titlefield">' . $langs->trans("Control") . '</td>';
if ($object->doc_type == 'customer_invoice')
{
$sqlmid = 'SELECT rowid as ref';
$sqlmid .= " FROM ".MAIN_DB_PREFIX."facture as fac";
$sqlmid .= " WHERE fac.rowid=" . ((int) $object->fk_doc);
dol_syslog("accountancy/bookkeeping/card.php::sqlmid=" . $sqlmid, LOG_DEBUG);
$resultmid = $db->query($sqlmid);
if ($resultmid) {
$objmid = $db->fetch_object($resultmid);
$invoicestatic = new Facture($db);
$invoicestatic->fetch($objmid->ref);
$ref=$langs->trans("Invoice").' '.$invoicestatic->getNomUrl(1);
}
else dol_print_error($db);
}
print '<td>' . $ref .'</td>';
print '</tr>';
*/
print "</table>\n";
print '</div>';
print dol_get_fiche_end();
print '<div style="clear:both"></div>';
print '<br>';
$result = $object->fetchAllPerMvt($piece_num, $mode); // This load $object->linesmvt
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
/*
print '<tr>';
print '<td class="titlefield">' . $langs->trans("Control") . '</td>';
if ($object->doc_type == 'customer_invoice') {
$sqlmid = 'SELECT rowid as ref';
$sqlmid .= " FROM ".MAIN_DB_PREFIX."facture as fac";
$sqlmid .= " WHERE fac.rowid=" . ((int) $object->fk_doc);
dol_syslog("accountancy/bookkeeping/card.php::sqlmid=" . $sqlmid, LOG_DEBUG);
$resultmid = $db->query($sqlmid);
if ($resultmid) {
$objmid = $db->fetch_object($resultmid);
$invoicestatic = new Facture($db);
$invoicestatic->fetch($objmid->ref);
$ref=$langs->trans("Invoice").' '.$invoicestatic->getNomUrl(1);
} else {
print load_fiche_titre($langs->trans("ListeMvts"), '', '');
dol_print_error($db);
}
}
print '<td>' . $ref .'</td>';
print '</tr>';
*/
print "</table>\n";
print '<form action="'.$_SERVER["PHP_SELF"].'?piece_num='.$object->piece_num.'" method="post">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
print dol_get_fiche_end();
print '<div style="clear:both"></div>';
print '<br>';
$result = $object->fetchAllPerMvt($piece_num, $mode); // This load $object->linesmvt
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
} else {
// List of movements
print load_fiche_titre($langs->trans("ListeMvts"), '', '');
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'" />';
}
print '<input type="hidden" name="token" value="'.newToken().'" />';
print '<input type="hidden" name="doc_type" value="'.$object->doc_type.'" />'."\n";
print '<input type="hidden" name="fk_doc" value="'.$object->fk_doc.'" />'."\n";
print '<input type="hidden" name="fk_docdet" value="'.$object->fk_docdet.'" />'."\n";
print '<input type="hidden" name="mode" value="'.$mode.'" />'."\n";
if (count($object->linesmvt) > 0) {
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
$total_debit = 0;
$total_credit = 0;
// 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 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>';
}
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="doc_date" value="'.$object->doc_date.'">'."\n";
print '<input type="hidden" name="doc_type" value="'.$object->doc_type.'">'."\n";
print '<input type="hidden" name="doc_ref" value="'.$object->doc_ref.'">'."\n";
print '<input type="hidden" name="code_journal" value="'.$object->code_journal.'">'."\n";
print '<input type="hidden" name="fk_doc" value="'.$object->fk_doc.'">'."\n";
print '<input type="hidden" name="fk_docdet" value="'.$object->fk_docdet.'">'."\n";
print '<input type="hidden" name="mode" value="'.$mode.'">'."\n";
if (count($object->linesmvt) > 0) {
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
$total_debit = 0;
$total_credit = 0;
print_liste_field_titre("AccountAccountingShort");
print_liste_field_titre("SubledgerAccount");
print_liste_field_titre("LabelOperation");
print_liste_field_titre("AccountingDebit", "", "", "", "", 'class="right"');
print_liste_field_titre("AccountingCredit", "", "", "", "", 'class="right"');
if (empty($object->date_validation)) {
print_liste_field_titre("Action", "", "", "", "", 'width="60"', "", "", 'center ');
} else {
print_liste_field_titre("");
}
print '<tr class="liste_titre">';
print "</tr>\n";
print_liste_field_titre("AccountAccountingShort");
print_liste_field_titre("SubledgerAccount");
print_liste_field_titre("LabelOperation");
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"');
} else {
print_liste_field_titre("");
}
// In _tmp mode the first line is empty so we remove it
if ($mode == "_tmp") {
array_shift($object->linesmvt);
}
print "</tr>\n";
// Add an empty line at the end to be able to add transaction
$line = new BookKeepingLine();
$object->linesmvt[] = $line;
// 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;
// Add a second line empty line if there is not yet
if (empty($object->linesmvt[1])) {
$line = new BookKeepingLine();
$object->linesmvt[] = $line;
}
$count_line = count($object->linesmvt);
$num_line = 0;
foreach ($object->linesmvt as $key => $line) {
$num_line++;
print '<tr class="oddeven" data-lineid="'.((int) $line->id).'">';
$total_debit += $line->debit;
$total_credit += $line->credit;
if ($action == 'update' && $line->id == $id) {
print '<!-- td columns in edit mode -->';
print '<td>';
print $formaccounting->select_account((GETPOSTISSET("accountingaccount_number") ? GETPOST("accountingaccount_number", "alpha") : $line->numero_compte), '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((GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account), 'subledger_account', 1, 'maxwidth250', '', 'subledger_label');
} else {
print '<input type="text" class="maxwidth150" name="subledger_account" value="'.(GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account).'" placeholder="'.dol_escape_htmltag($langs->trans("SubledgerAccount")).'" />';
}
}
foreach ($object->linesmvt as $line) {
print '<tr class="oddeven">';
$total_debit += $line->debit;
$total_credit += $line->credit;
if ($action == 'update' && $line->id == $id) {
print '<!-- td columns in edit mode -->';
// Add also input for subledger label
print '<br><input type="text" class="maxwidth150" name="subledger_label" value="'.(GETPOSTISSET("subledger_label") ? GETPOST("subledger_label", "alpha") : $line->subledger_label).'" placeholder="'.dol_escape_htmltag($langs->trans("SubledgerAccountLabel")).'" />';
print '</td>';
print '<td><input type="text" class="minwidth200" name="label_operation" value="'.(GETPOSTISSET("label_operation") ? GETPOST("label_operation", "alpha") : $line->label_operation).'" /></td>';
print '<td class="right"><input type="text" size="6" class="right" name="debit" value="'.(GETPOSTISSET("debit") ? GETPOST("debit", "alpha") : price($line->debit)).'" /></td>';
print '<td class="right"><input type="text" size="6" class="right" name="credit" value="'.(GETPOSTISSET("credit") ? GETPOST("credit", "alpha") : price($line->credit)).'" /></td>';
print '<td>';
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((GETPOSTISSET("accountingaccount_number") ? GETPOST("accountingaccount_number", "alpha") : $line->numero_compte), 'accountingaccount_number', 1, array(), 1, 1, '');
print $formaccounting->select_account((is_array($accountingaccount_number) ? $accountingaccount_number[$key] : $accountingaccount_number ), 'accountingaccount_number['.$key.']', 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:
@ -673,126 +649,102 @@ if ($action == 'create') {
// 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((GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account), 'subledger_account', 1, 'maxwidth250', '', 'subledger_label');
print $formaccounting->select_auxaccount((is_array($subledger_account) ? $subledger_account[$key] : $subledger_account ), 'subledger_account['.$key.']', 1, 'maxwidth250', '', 'subledger_label');
} else {
print '<input type="text" class="maxwidth150" name="subledger_account" value="'.(GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account).'" placeholder="'.dol_escape_htmltag($langs->trans("SubledgerAccount")).'">';
print '<input type="text" class="maxwidth150" name="subledger_account['.$key.']" value="' . (is_array($subledger_account) ? $subledger_account[$key] : $subledger_account ) . '" placeholder="' . dol_escape_htmltag($langs->trans("SubledgerAccount")) . '" />';
}
// Add also input for subledger label
print '<br><input type="text" class="maxwidth150" name="subledger_label" value="'.(GETPOSTISSET("subledger_label") ? GETPOST("subledger_label", "alpha") : $line->subledger_label).'" placeholder="'.dol_escape_htmltag($langs->trans("SubledgerAccountLabel")).'">';
print '<br><input type="text" class="maxwidth150" name="subledger_label['.$key.']" value="' . (is_array($subledger_label) ? $subledger_label[$key] : $subledger_label ) . '" placeholder="' . dol_escape_htmltag($langs->trans("SubledgerAccountLabel")) . '" />';
print '</td>';
print '<td><input type="text" class="minwidth200" name="label_operation" value="'.(GETPOSTISSET("label_operation") ? GETPOST("label_operation", "alpha") : $line->label_operation).'"></td>';
print '<td class="right"><input type="text" size="6" class="right" name="debit" value="'.(GETPOSTISSET("debit") ? GETPOST("debit", "alpha") : price($line->debit)).'"></td>';
print '<td class="right"><input type="text" size="6" class="right" name="credit" value="'.(GETPOSTISSET("credit") ? GETPOST("credit", "alpha") : price($line->credit)).'"></td>';
print '<td>';
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>';
print '<input type="submit" class="button" name="save" value="' . $langs->trans("Add") . '">';
print '</td>';
}
} else {
print '<!-- td columns in display mode -->';
$resultfetch = $accountingaccount->fetch(null, $line->numero_compte, true);
print '<td>';
if ($resultfetch > 0) {
print $accountingaccount->getNomUrl(0, 1, 1, '', 0);
print '<td><input type="text" class="minwidth200" name="label_operation['.$key.']" value="' . (is_array($label_operation) ? $label_operation[$key] : $label_operation ) . '"/></td>';
print '<td class="right"><input type="text" size="6" class="right" name="debit['.$key.']" value="' . (is_array($debit) ? $debit[$key] : $debit ) . '" /></td>';
print '<td class="right"><input type="text" size="6" class="right" name="credit['.$key.']" value="' . (is_array($credit) ? $credit[$key] : $credit ) . '" /></td>';
// Add button should not appear twice
if ($num_line === $count_line) {
print '<td><input type="submit" class="button small" name="save" value="' . $langs->trans("Add") . '" /></td>';
} else {
print $line->numero_compte.' <span class="warning">('.$langs->trans("AccountRemovedFromCurrentChartOfAccount").')</span>';
print '<td class="right"></td>';
}
print '</td>';
print '<td>'.length_accounta($line->subledger_account);
if ($line->subledger_label) {
print ' - <span class="opacitymedium">'.$line->subledger_label.'</span>';
}
print '</td>';
print '<td>'.$line->label_operation.'</td>';
print '<td class="right nowraponall amount">'.price($line->debit).'</td>';
print '<td class="right nowraponall amount">'.price($line->credit).'</td>';
print '<td class="center nowraponall">';
if (empty($line->date_export) && empty($line->date_validation)) {
print '<a class="editfielda reposition" href="' . $_SERVER["PHP_SELF"] . '?action=update&id=' . $line->id . '&piece_num=' . urlencode($line->piece_num) . '&mode=' . urlencode($mode) . '&token=' . urlencode(newToken()) . '">';
print img_edit('', 0, 'class="marginrightonly"');
print '</a> &nbsp;';
} else {
print '<a class="editfielda nohover cursornotallowed reposition disabled" href="#" title="'.dol_escape_htmltag($langs->trans("ForbiddenTransactionAlreadyExported")).'">';
print img_edit($langs->trans("ForbiddenTransactionAlreadyExported"), 0, 'class="marginrightonly"');
print '</a> &nbsp;';
}
if (empty($line->date_validation)) {
$actiontodelete = 'delete';
if ($mode == '_tmp' || $action != 'delmouv') {
$actiontodelete = 'confirm_delete';
}
print '<a href="' . $_SERVER["PHP_SELF"] . '?action=' . $actiontodelete . '&id=' . $line->id . '&piece_num=' . urlencode($line->piece_num) . '&mode=' . urlencode($mode) . '&token=' . urlencode(newToken()) . '">';
print img_delete();
print '</a>';
} else {
print '<a class="editfielda nohover cursornotallowed disabled" href="#" title="'.dol_escape_htmltag($langs->trans("ForbiddenTransactionAlreadyExported")).'">';
print img_delete($langs->trans("ForbiddenTransactionAlreadyValidated"));
print '</a>';
}
print '</td>';
}
print "</tr>\n";
}
$total_debit = price2num($total_debit, 'MT');
$total_credit = price2num($total_credit, 'MT');
if ($total_debit != $total_credit) {
setEventMessages(null, array($langs->trans('MvtNotCorrectlyBalanced', $total_debit, $total_credit)), 'warnings');
}
print '</table>';
print '</div>';
if ($mode == '_tmp' && $action == '') {
print '<br>';
print '<div class="center">';
if ($total_debit == $total_credit) {
print '<a class="button" href="'.$_SERVER["PHP_SELF"].'?piece_num='.$object->piece_num.'&action=valid">'.$langs->trans("ValidTransaction").'</a>';
} else {
print '<!-- td columns in display mode -->';
$resultfetch = $accountingaccount->fetch(null, $line->numero_compte, true);
print '<td>';
if ($resultfetch > 0) {
print $accountingaccount->getNomUrl(0, 1, 1, '', 0);
} else {
print '<input type="submit" class="button" disabled="disabled" href="#" title="'.dol_escape_htmltag($langs->trans("MvtNotCorrectlyBalanced", $debit, $credit)).'" value="'.dol_escape_htmltag($langs->trans("ValidTransaction")).'">';
print $line->numero_compte.' <span class="warning">('.$langs->trans("AccountRemovedFromCurrentChartOfAccount").')</span>';
}
print '</td>';
print '<td>'.length_accounta($line->subledger_account);
if ($line->subledger_label) {
print ' - <span class="opacitymedium">'.$line->subledger_label.'</span>';
}
print '</td>';
print '<td>'.$line->label_operation.'</td>';
print '<td class="right nowraponall amount">'.($line->debit != 0 ? price($line->debit) : '').'</td>';
print '<td class="right nowraponall amount">'.($line->credit != 0 ? price($line->credit) : '').'</td>';
print '<td class="center nowraponall">';
if (empty($line->date_export) && empty($line->date_validation)) {
print '<a class="editfielda reposition" href="' . $_SERVER["PHP_SELF"] . '?action=update&id=' . $line->id . '&piece_num=' . urlencode($line->piece_num) . '&mode=' . urlencode($mode) . '&token=' . urlencode(newToken()) . '">';
print img_edit('', 0, 'class="marginrightonly"');
print '</a> &nbsp;';
} else {
print '<a class="editfielda nohover cursornotallowed reposition disabled" href="#" title="'.dol_escape_htmltag($langs->trans("ForbiddenTransactionAlreadyExported")).'">';
print img_edit($langs->trans("ForbiddenTransactionAlreadyExported"), 0, 'class="marginrightonly"');
print '</a> &nbsp;';
}
print ' &nbsp; ';
print '<a class="button button-cancel" href="'.DOL_URL_ROOT.'/accountancy/bookkeeping/list.php">'.$langs->trans("Cancel").'</a>';
if (empty($line->date_validation)) {
$actiontodelete = 'delete';
if ($mode == '_tmp' || $action != 'delmouv') {
$actiontodelete = 'confirm_delete';
}
print "</div>";
print '<a href="' . $_SERVER["PHP_SELF"] . '?action=' . $actiontodelete . '&id=' . $line->id . '&piece_num=' . urlencode($line->piece_num) . '&mode=' . urlencode($mode) . '&token=' . urlencode(newToken()) . '">';
print img_delete();
print '</a>';
} else {
print '<a class="editfielda nohover cursornotallowed disabled" href="#" title="'.dol_escape_htmltag($langs->trans("ForbiddenTransactionAlreadyExported")).'">';
print img_delete($langs->trans("ForbiddenTransactionAlreadyValidated"));
print '</a>';
}
print '</td>';
}
print "</tr>\n";
}
print '</form>';
$total_debit = price2num($total_debit, 'MT');
$total_credit = price2num($total_credit, 'MT');
if ($total_debit != $total_credit) {
setEventMessages(null, array($langs->trans('MvtNotCorrectlyBalanced', $total_debit, $total_credit)), 'warnings');
}
print '</table>';
print '</div>';
if ($mode == '_tmp' && $action == '') {
print '<br>';
print '<div class="center">';
if ($total_debit == $total_credit) {
print '<input type="submit" class="button" name="validate" value="' . $langs->trans("ValidTransaction") . '" />';
} else {
print '<input type="submit" class="button" disabled="disabled" href="#" title="'.dol_escape_htmltag($langs->trans("MvtNotCorrectlyBalanced", $debit, $credit)).'" value="'.dol_escape_htmltag($langs->trans("ValidTransaction")).'" />';
}
print ' &nbsp; ';
print '<a class="button button-cancel" href="'.DOL_URL_ROOT.'/accountancy/bookkeeping/list.php">'.$langs->trans("Cancel").'</a>';
print "</div>";
}
}
} else {
print load_fiche_titre($langs->trans("NoRecords"));
print '</form>';
}
} else {
print load_fiche_titre($langs->trans("NoRecords"));
}
print dol_get_fiche_end();

View File

@ -1,9 +1,11 @@
<?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) 2022 Lionel Vessiller <lvessiller@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>
* Copyright (C) 2022 Progiseize <a.bisotti@progiseize.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
@ -25,6 +27,7 @@
* \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';
@ -101,7 +104,9 @@ if (GETPOST("button_export_file_x") || GETPOST("button_export_file.x") || GETPOS
$action = 'export_file';
}
$search_accountancy_code = GETPOST("search_accountancy_code");
$search_account_category = GETPOST('search_account_category', 'int');
$search_accountancy_code = GETPOST("search_accountancy_code", 'alpha');
$search_accountancy_code_start = GETPOST('search_accountancy_code_start', 'alpha');
if ($search_accountancy_code_start == - 1) {
$search_accountancy_code_start = '';
@ -132,6 +137,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;
@ -153,7 +159,7 @@ $hookmanager->initHooks(array('bookkeepinglist'));
$formaccounting = new FormAccounting($db);
$form = new Form($db);
if (!in_array($action, array('export_file', 'delmouv', 'delmouvconfirm')) && !GETPOSTISSET('begin') && !GETPOSTISSET('formfilteraction') && GETPOST('page', 'int') == '' && !GETPOST('noreset', 'int') && $user->rights->accounting->mouvements->export) {
if (!in_array($action, array('export_file', 'delmouv', 'delmouvconfirm')) && !GETPOSTISSET('begin') && !GETPOSTISSET('formfilteraction') && GETPOST('page', 'int') == '' && !GETPOST('noreset', 'int') && $user->hasRight('accounting', 'mouvements', 'export')) {
if (empty($search_date_start) && empty($search_date_end) && !GETPOSTISSET('restore_lastsearch_values') && !GETPOST('search_accountancy_code_start')) {
$query = "SELECT date_start, date_end from ".MAIN_DB_PREFIX."accounting_fiscalyear ";
$query .= " where date_start < '".$db->idate(dol_now())."' and date_end > '".$db->idate(dol_now())."' limit 1";
@ -190,13 +196,13 @@ $arrayfields = array(
't.numero_compte'=>array('label'=>$langs->trans("AccountAccountingShort"), 'checked'=>1),
't.subledger_account'=>array('label'=>$langs->trans("SubledgerAccount"), '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.debit'=>array('label'=>$langs->trans("AccountingDebit"), 'checked'=>1),
't.credit'=>array('label'=>$langs->trans("AccountingCredit"), 'checked'=>1),
't.lettering_code'=>array('label'=>$langs->trans("LetteringCode"), 'checked'=>1),
'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),
);
@ -206,20 +212,20 @@ if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) {
$accountancyexport = new AccountancyExport($db);
$listofformat = $accountancyexport->getType();
$formatexportset = $conf->global->ACCOUNTING_EXPORT_MODELCSV;
$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) {
accessforbidden();
}
if (empty($user->rights->accounting->mouvements->lire)) {
if (!$user->hasRight('accounting', 'mouvements', 'lire')) {
accessforbidden();
}
@ -233,7 +239,7 @@ $param = '';
if (GETPOST('cancel', 'alpha')) {
$action = 'list'; $massaction = '';
}
if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'preunlettering' && $massaction != 'predeletebookkeepingwriting') {
if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'preunletteringauto' && $massaction != 'preunletteringmanual' && $massaction != 'predeletebookkeepingwriting') {
$massaction = '';
}
@ -251,6 +257,7 @@ if (empty($reshook)) {
$search_doc_type = '';
$search_doc_ref = '';
$search_doc_date = '';
$search_account_category = '';
$search_accountancy_code = '';
$search_accountancy_code_start = '';
$search_accountancy_code_end = '';
@ -333,6 +340,20 @@ if (empty($reshook)) {
$filter['t.doc_ref'] = $search_doc_ref;
$param .= '&search_doc_ref='.urlencode($search_doc_ref);
}
if ($search_account_category != '-1' && !empty($search_account_category)) {
require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancycategory.class.php';
$accountingcategory = new AccountancyCategory($db);
$listofaccountsforgroup = $accountingcategory->getCptsCat(0, 'fk_accounting_category = '.((int) $search_account_category));
$listofaccountsforgroup2 = array();
if (is_array($listofaccountsforgroup)) {
foreach ($listofaccountsforgroup as $tmpval) {
$listofaccountsforgroup2[] = "'".$db->escape($tmpval['id'])."'";
}
}
$filter['t.search_accounting_code_in'] = join(',', $listofaccountsforgroup2);
$param .= '&search_account_category='.urlencode($search_account_category);
}
if (!empty($search_accountancy_code)) {
$filter['t.numero_compte'] = $search_accountancy_code;
$param .= '&search_accountancy_code='.urlencode($search_accountancy_code);
@ -345,6 +366,10 @@ if (empty($reshook)) {
$filter['t.numero_compte<='] = $search_accountancy_code_end;
$param .= '&search_accountancy_code_end='.urlencode($search_accountancy_code_end);
}
if (!empty($search_accountancy_aux_code)) {
$filter['t.subledger_account'] = $search_accountancy_aux_code;
$param .= '&search_accountancy_aux_code='.urlencode($search_accountancy_aux_code);
}
if (!empty($search_accountancy_aux_code_start)) {
$filter['t.subledger_account>='] = $search_accountancy_aux_code_start;
$param .= '&search_accountancy_aux_code_start='.urlencode($search_accountancy_aux_code_start);
@ -432,7 +457,7 @@ if (empty($reshook)) {
$param .= '&search_import_key='.urlencode($search_import_key);
}
//if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouvements->supprimer_tous) {
//if ($action == 'delbookkeepingyearconfirm' && !$user->hasRight('accounting', 'mouvements', 'supprimer_tous')) {
// $delmonth = GETPOST('delmonth', 'int');
// $delyear = GETPOST('delyear', 'int');
// if ($delyear == -1) {
@ -478,50 +503,67 @@ if (empty($reshook)) {
// Mass actions
$objectclass = 'Bookkeeping';
$objectlabel = 'Bookkeeping';
$permissiontoread = $user->rights->societe->lire;
$permissiontodelete = $user->rights->societe->supprimer;
$permissiontoread = $user->hasRight('societe', 'lire');
$permissiontodelete = $user->hasRight('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) {
if (!$error && $action == 'deletebookkeepingwriting' && $confirm == "yes" && $user->hasRight('accounting', 'mouvements', 'supprimer')) {
$db->begin();
if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING')) {
$lettering = new Lettering($db);
$nb_lettering = $lettering->bookkeepingLetteringAll($toselect, true);
if ($nb_lettering < 0) {
setEventMessages('', $lettering->errors, 'errors');
$error++;
}
}
$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 {
if (!$error) {
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;
}
} 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) {
$db->commit();
// 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');
} else {
setEventMessages($langs->trans("NoRecordDeleted"), null, 'mesgs');
}
header("Location: ".$_SERVER["PHP_SELF"]."?noreset=1".($param ? '&'.$param : ''));
exit;
} else {
$db->rollback();
}
}
// others mass actions
if (!$error && getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && $user->rights->accounting->mouvements->creer) {
if ($massaction == 'lettering') {
if (!$error && getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && $user->hasRight('accounting', 'mouvements', 'creer')) {
if ($massaction == 'letteringauto') {
$lettering = new Lettering($db);
$nb_lettering = $lettering->bookkeepingLetteringAll($toselect);
if ($nb_lettering < 0) {
@ -542,7 +584,17 @@ if (empty($reshook)) {
header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param);
exit();
}
} elseif ($action == 'unlettering' && $confirm == "yes") {
} elseif ($massaction == 'letteringmanual') {
$lettering = new Lettering($db);
$result = $lettering->updateLettering($toselect);
if ($result < 0) {
setEventMessages('', $lettering->errors, 'errors');
} else {
setEventMessages($langs->trans('AccountancyOneLetteringModifiedSuccessfully'), array(), 'mesgs');
header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param);
exit();
}
} elseif ($action == 'unletteringauto' && $confirm == "yes") {
$lettering = new Lettering($db);
$nb_lettering = $lettering->bookkeepingLetteringAll($toselect, true);
if ($nb_lettering < 0) {
@ -563,6 +615,16 @@ if (empty($reshook)) {
header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param);
exit();
}
} elseif ($action == 'unletteringmanual' && $confirm == "yes") {
$lettering = new Lettering($db);
$nb_lettering = $lettering->deleteLettering($toselect);
if ($result < 0) {
setEventMessages('', $lettering->errors, 'errors');
} else {
setEventMessages($langs->trans('AccountancyOneUnletteringModifiedSuccessfully'), array(), 'mesgs');
header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param);
exit();
}
}
}
}
@ -599,6 +661,9 @@ $sql .= " t.tms as date_modification,";
$sql .= " t.date_export,";
$sql .= " t.date_validated as date_validation,";
$sql .= " t.import_key";
$sqlfields = $sql; // $sql fields to remove for count total
$sql .= ' FROM '.MAIN_DB_PREFIX.$object->table_element.' as t';
// Manage filter
$sqlwhere = array();
@ -629,7 +694,13 @@ if (count($filter) > 0) {
} elseif ($key == 't.reconciled_option') {
$sqlwhere[] = 't.lettering_code IS NULL';
} elseif ($key == 't.code_journal' && !empty($value)) {
$sqlwhere[] = natural_search("t.code_journal", join(',', $value), 3, 1);
if (is_array($value)) {
$sqlwhere[] = natural_search("t.code_journal", join(',', $value), 3, 1);
} else {
$sqlwhere[] = natural_search("t.code_journal", $value, 3, 1);
}
} elseif ($key == 't.search_accounting_code_in' && !empty($value)) {
$sqlwhere[] = 't.numero_compte IN ('.$db->sanitize($value, 1).')';
} else {
$sqlwhere[] = natural_search($key, $value, 0, 1);
}
@ -642,71 +713,89 @@ if (empty($conf->global->ACCOUNTING_REEXPORT)) {
if (count($sqlwhere) > 0) {
$sql .= ' AND '.implode(' AND ', $sqlwhere);
}
if (!empty($sortfield)) {
$sql .= $db->order($sortfield, $sortorder);
}
//print $sql;
// Export into a file with format defined into setup (FEC, CSV, ...)
// Must be after definition of $sql
if ($action == 'export_fileconfirm' && $user->rights->accounting->mouvements->export) {
// TODO Replace the fetchAll to get all ->line followed by call to ->export(). It consumew too much memory on large export. Replace this with the query($sql) and loop on each line to export them.
if ($action == 'export_fileconfirm' && $user->hasRight('accounting', 'mouvements', 'export')) {
// TODO Replace the fetchAll to get all ->line followed by call to ->export(). It consumes too much memory on large export.
// Replace this with the query($sql) and loop on each line to export them.
$result = $object->fetchAll($sortorder, $sortfield, 0, 0, $filter, 'AND', (empty($conf->global->ACCOUNTING_REEXPORT) ? 0 : 1));
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
} else {
// Export files
// Export files then exit
$accountancyexport = new AccountancyExport($db);
$accountancyexport->export($object->lines, $formatexportset);
$notexportlettering = GETPOST('notexportlettering', 'alpha');
if (!empty($notexportlettering)) {
if (is_array($object->lines)) {
foreach ($object->lines as $k => $movement) {
unset($object->lines[$k]->lettering_code);
unset($object->lines[$k]->date_lettering);
}
}
}
$notifiedexportdate = GETPOST('notifiedexportdate', 'alpha');
$notifiedvalidationdate = GETPOST('notifiedvalidationdate', 'alpha');
$withAttachment = !empty(trim(GETPOST('notifiedexportfull', 'alphanohtml'))) ? 1 : 0;
if (!empty($accountancyexport->errors)) {
setEventMessages('', $accountancyexport->errors, 'errors');
} elseif (!empty($notifiedexportdate) || !empty($notifiedvalidationdate)) {
// Specify as export : update field date_export or date_validated
$error = 0;
$db->begin();
// Output data on screen or download
$result = $accountancyexport->export($object->lines, $formatexportset, $withAttachment);
if (is_array($object->lines)) {
foreach ($object->lines as $movement) {
$now = dol_now();
$error = 0;
if ($result < 0) {
$error++;
} else {
if (!empty($notifiedexportdate) || !empty($notifiedvalidationdate)) {
if (is_array($object->lines)) {
// Specify as export : update field date_export or date_validated
$db->begin();
$sql = " UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping";
$sql .= " SET";
if (!empty($notifiedexportdate) && !empty($notifiedvalidationdate)) {
$sql .= " date_export = '".$db->idate($now)."'";
$sql .= ", date_validated = '".$db->idate($now)."'";
} elseif (!empty($notifiedexportdate)) {
$sql .= " date_export = '".$db->idate($now)."'";
} elseif (!empty($notifiedvalidationdate)) {
$sql .= " date_validated = '".$db->idate($now)."'";
foreach ($object->lines as $movement) {
$now = dol_now();
$sql = " UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping";
$sql .= " SET";
if (!empty($notifiedexportdate) && !empty($notifiedvalidationdate)) {
$sql .= " date_export = '".$db->idate($now)."'";
$sql .= ", date_validated = '".$db->idate($now)."'";
} elseif (!empty($notifiedexportdate)) {
$sql .= " date_export = '".$db->idate($now)."'";
} elseif (!empty($notifiedvalidationdate)) {
$sql .= " date_validated = '".$db->idate($now)."'";
}
$sql .= " WHERE rowid = ".((int) $movement->id);
dol_syslog("/accountancy/bookkeeping/list.php Function export_file Specify movements as exported", LOG_DEBUG);
$result = $db->query($sql);
if (!$result) {
$error++;
break;
}
}
$sql .= " WHERE rowid = ".((int) $movement->id);
dol_syslog("/accountancy/bookkeeping/list.php Function export_file Specify movements as exported", LOG_DEBUG);
$result = $db->query($sql);
if (!$result) {
if (!$error) {
$db->commit();
} else {
$error++;
break;
$accountancyexport->errors[] = $langs->trans('NotAllExportedMovementsCouldBeRecordedAsExportedOrValidated');
$db->rollback();
}
}
}
if (!$error) {
$db->commit();
// setEventMessages($langs->trans("AllExportedMovementsWereRecordedAsExportedOrValidated"), null, 'mesgs');
} else {
$error++;
$db->rollback();
setEventMessages($langs->trans("NotAllExportedMovementsCouldBeRecordedAsExportedOrValidated"), null, 'errors');
}
}
exit;
if ($error) {
setEventMessages('', $accountancyexport->errors, 'errors');
header('Location: '.$_SERVER['PHP_SELF']);
}
exit(); // download or show errors
}
}
@ -723,28 +812,38 @@ $title_page = $langs->trans("Operations").' - '.$langs->trans("Journals");
// Count total nb of records
$nbtotalofrecords = '';
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
$resql = $db->query($sql);
$nbtotalofrecords = $db->num_rows($resql);
if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0
/* The fast and low memory method to get and count full list converts the sql into a sql count */
$sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
$sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
$resql = $db->query($sqlforcount);
if ($resql) {
$objforcount = $db->fetch_object($resql);
$nbtotalofrecords = $objforcount->nbtotalofrecords;
} else {
dol_print_error($db);
}
if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
$page = 0;
$offset = 0;
}
$db->free($resql);
}
// if total of record found is smaller than limit, no need to do paging and to restart another select with limits set.
if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) {
$num = $nbtotalofrecords;
} else {
// Complete request and execute it with limit
$sql .= $db->order($sortfield, $sortorder);
if ($limit) {
$sql .= $db->plimit($limit + 1, $offset);
$resql = $db->query($sql);
if (!$resql) {
dol_print_error($db);
exit;
}
$num = $db->num_rows($resql);
}
$resql = $db->query($sql);
if (!$resql) {
dol_print_error($db);
exit;
}
$num = $db->num_rows($resql);
$arrayofselected = is_array($toselect) ? $toselect : array();
// Output page
@ -757,6 +856,19 @@ $formconfirm = '';
if ($action == 'export_file') {
$form_question = array();
if (getDolGlobalInt("ACCOUNTING_ENABLE_LETTERING")) {
// If 1, we check by default.
$checked = !empty($conf->global->ACCOUNTING_DEFAULT_NOT_EXPORT_LETTERING) ? 'true' : 'false';
$form_question['notexportlettering'] = array(
'name' => 'notexportlettering',
'type' => 'checkbox',
'label' => $langs->trans('NotExportLettering'),
'value' => $checked,
);
$form_question['separator'] = array('name'=>'separator', 'type'=>'separator');
}
// If 1 or not set, we check by default.
$checked = (!isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE));
$form_question['notifiedexportdate'] = array(
@ -766,20 +878,32 @@ if ($action == 'export_file') {
'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,
);
$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 (!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['separator3'] = array('name'=>'separator3', 'type'=>'separator');
}
// add documents in an archive for accountancy export (Quadratus)
if (getDolGlobalString('ACCOUNTING_EXPORT_MODELCSV') == AccountancyExport::$EXPORT_TYPE_QUADRATUS) {
$form_question['notifiedexportfull'] = array(
'name' => 'notifiedexportfull',
'type' => 'checkbox',
'label' => $langs->trans('NotifiedExportFull'),
'value' => 'false',
);
}
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', $langs->trans('ConfirmExportFile'), 'export_fileconfirm', $form_question, '', 1, 400, 600);
}
//if ($action == 'delbookkeepingyear') {
@ -836,16 +960,16 @@ if ($limit > 0 && $limit != $conf->liste_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');
$arrayofmassactions['letteringauto'] = img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans('LetteringAuto');
$arrayofmassactions['preunletteringauto'] = img_picto('', 'uncheck', 'class="pictofixedwidth"') . $langs->trans('UnletteringAuto');
$arrayofmassactions['letteringmanual'] = img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans('LetteringManual');
$arrayofmassactions['preunletteringmanual'] = img_picto('', 'uncheck', 'class="pictofixedwidth"') . $langs->trans('UnletteringManual');
}
*/
if ($user->rights->accounting->mouvements->supprimer) {
if ($user->hasRight('accounting', 'mouvements', 'supprimer')) {
$arrayofmassactions['predeletebookkeepingwriting'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
}
if (GETPOST('nomassaction', 'int') || in_array($massaction, array('preunlettering', 'predeletebookkeepingwriting'))) {
if (GETPOST('nomassaction', 'int') || in_array($massaction, array('preunletteringauto', 'preunletteringmanual', 'predeletebookkeepingwriting'))) {
$arrayofmassactions = array();
}
$massactionbutton = $form->selectMassAction($massaction, $arrayofmassactions);
@ -857,8 +981,8 @@ if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.urlencode($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).'">';
print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
if (count($filter)) {
@ -867,19 +991,25 @@ if (count($filter)) {
$buttonLabel = $langs->trans("ExportList");
}
$parameters = array();
$parameters = array('param' => $param);
$reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
}
$newcardbutton = empty($hookmanager->resPrint) ? '' : $hookmanager->resPrint;
if (empty($reshook)) {
// Button re-export
if (!empty($conf->global->ACCOUNTING_REEXPORT)) {
$newcardbutton = '<a class="valignmiddle" href="'.$_SERVER['PHP_SELF'].'?action=setreexport&token='.newToken().'&value=0'.($param ? '&'.$param : '').'">'.img_picto($langs->trans("Activated"), 'switch_on').'</a> ';
$newcardbutton .= '<a class="valignmiddle" href="'.$_SERVER['PHP_SELF'].'?action=setreexport&token='.newToken().'&value=0'.($param ? '&'.$param : '').'">'.img_picto($langs->trans("Activated"), 'switch_on').'</a> ';
} else {
$newcardbutton = '<a class="valignmiddle" href="'.$_SERVER['PHP_SELF'].'?action=setreexport&token='.newToken().'&value=1'.($param ? '&'.$param : '').'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a> ';
$newcardbutton .= '<a class="valignmiddle" href="'.$_SERVER['PHP_SELF'].'?action=setreexport&token='.newToken().'&value=1'.($param ? '&'.$param : '').'">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a> ';
}
$newcardbutton .= '<span class="valignmiddle marginrightonly">'.$langs->trans("IncludeDocsAlreadyExported").'</span>';
if (!empty($user->rights->accounting->mouvements->export)) {
$newcardbutton .= dolGetButtonTitle($buttonLabel, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', 'fa fa-file-export paddingleft', $_SERVER["PHP_SELF"].'?action=export_file'.($param ? '&'.$param : ''), $user->rights->accounting->mouvements->export);
if ($user->hasRight('accounting', 'mouvements', 'export')) {
$newcardbutton .= dolGetButtonTitle($buttonLabel, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', 'fa fa-file-export paddingleft', $_SERVER["PHP_SELF"].'?action=export_file&token='.newToken().($param ? '&'.$param : ''), $user->hasRight('accounting', 'mouvements', 'export'));
}
$newcardbutton .= dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected'));
@ -890,13 +1020,15 @@ if (empty($reshook)) {
if (!empty($socid)) {
$url .= '&socid='.$socid;
}
$newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', $url, '', $user->rights->accounting->mouvements->creer);
$newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', $url, '', $user->hasRight('accounting', 'mouvements', 'creer'));
}
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);
if ($massaction == 'preunletteringauto') {
print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassUnletteringAuto"), $langs->trans("ConfirmMassUnletteringQuestion", count($toselect)), "unletteringauto", null, '', 0, 200, 500, 1);
} elseif ($massaction == 'preunletteringmanual') {
print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassUnletteringManual"), $langs->trans("ConfirmMassUnletteringQuestion", count($toselect)), "unletteringmanual", 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);
}
@ -913,20 +1045,38 @@ if ($massactionbutton && $contextpage != 'poslist') {
$selectedfields .= $form->showCheckAddButtons('checkforselect', 1);
}
$moreforfilter = '';
$moreforfilter .= '<div class="divsearchfield">';
$moreforfilter .= $langs->trans('AccountingCategory').': ';
$moreforfilter .= '<div class="nowrap inline-block">';
$moreforfilter .= $formaccounting->select_accounting_category($search_account_category, 'search_account_category', 1, 0, 0, 0);
$moreforfilter .= '</div>';
$moreforfilter .= '</div>';
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // 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">';
// Action column
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
print '<td class="liste_titre center">';
$searchpicto = $form->showFilterButtons('left');
print $searchpicto;
print '</td>';
}
// 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>';
@ -934,7 +1084,7 @@ if (!empty($arrayfields['t.piece_num']['checked'])) {
// 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, 'small maxwidth150');
print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1, 'small maxwidth75');
print '</td>';
}
// Date document
@ -977,14 +1127,14 @@ if (!empty($arrayfields['t.subledger_account']['checked'])) {
print $formaccounting->select_auxaccount($search_accountancy_aux_code_end, 'search_accountancy_aux_code_end', $langs->trans('to'), 'maxwidth250', 'subledgeraccount');
print '</div>';
} else {
print '<input type="text" class="maxwidth75" name="search_accountancy_aux_code" value="'.$search_accountancy_aux_code.'">';
print '<input type="text" class="maxwidth75" name="search_accountancy_aux_code" value="'.dol_escape_htmltag($search_accountancy_aux_code).'">';
}
print '</td>';
}
// Label operation
if (!empty($arrayfields['t.label_operation']['checked'])) {
print '<td class="liste_titre">';
print '<input type="text" size="7" class="flat" name="search_mvt_label" value="'.$search_mvt_label.'"/>';
print '<input type="text" size="7" class="flat" name="search_mvt_label" value="'.dol_escape_htmltag($search_mvt_label).'"/>';
print '</td>';
}
// Debit
@ -1002,7 +1152,7 @@ if (!empty($arrayfields['t.credit']['checked'])) {
// 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 '<input type="text" size="3" class="flat" name="search_lettering_code" value="'.dol_escape_htmltag($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>';
}
@ -1062,13 +1212,18 @@ if (!empty($arrayfields['t.import_key']['checked'])) {
print '</td>';
}
// Action column
print '<td class="liste_titre center">';
$searchpicto = $form->showFilterButtons();
print $searchpicto;
print '</td>';
if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
print '<td class="liste_titre center">';
$searchpicto = $form->showFilterButtons();
print $searchpicto;
print '</td>';
}
print "</tr>\n";
print '<tr class="liste_titre">';
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
}
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);
}
@ -1110,15 +1265,17 @@ if (!empty($arrayfields['t.tms']['checked'])) {
print_liste_field_titre($arrayfields['t.tms']['label'], $_SERVER['PHP_SELF'], "t.tms", "", $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 ');
print_liste_field_titre($arrayfields['t.date_export']['label'], $_SERVER['PHP_SELF'], "t.date_export,t.doc_date", "", $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 ');
print_liste_field_titre($arrayfields['t.date_validated']['label'], $_SERVER['PHP_SELF'], "t.date_validated,t.doc_date", "", $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 ');
if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ');
}
print "</tr>\n";
@ -1128,6 +1285,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)) {
@ -1166,6 +1330,18 @@ while ($i < min($num, $limit)) {
$total_credit += $line->credit;
print '<tr class="oddeven">';
// Action column
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_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>';
}
// Piece number
if (!empty($arrayfields['t.piece_num']['checked'])) {
@ -1370,15 +1546,17 @@ while ($i < min($num, $limit)) {
}
// 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;
if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_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 '<input id="cb'.$line->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$line->id.'"'.($selected ? ' checked="checked"' : '').' />';
print '</td>';
}
print '</td>';
if (!$i) {
$totalarray['nbfield']++;
@ -1392,6 +1570,20 @@ while ($i < min($num, $limit)) {
// Show total line
include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php';
// If no record found
if ($num == 0) {
$colspan = 1;
foreach ($arrayfields as $key => $val) {
if (!empty($val['checked'])) {
$colspan++;
}
}
print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
}
$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql);
$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
print $hookmanager->resPrint;
print "</table>";
print '</div>';
@ -1407,4 +1599,5 @@ print '</form>';
// End of page
llxFooter();
$db->close();

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