Merge branch 'Dolibarr:develop' into NEW-Disable_bad_reputation_product_price

This commit is contained in:
IC-Nicolas 2023-03-24 14:15:02 +01:00 committed by GitHub
commit 440cdd259b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
501 changed files with 15222 additions and 10232 deletions

1
.gitignore vendored
View File

@ -57,3 +57,4 @@ yarn.lock
package-lock.json
doc/install.lock
/.asciidoctorconfig.adoc

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="7.0">
<component name="PhpProjectSharedConfiguration" php_language_level="7.0" />
<project version="7.1">
<component name="PhpProjectSharedConfiguration" php_language_level="7.1" />
</project>

View File

@ -72,10 +72,6 @@ jobs:
if: type = pull_request OR type = push
php: '8.1'
env: DB=mysql
- stage: PHP Dev
if: type = push AND branch = develop
php: nightly
env: DB=mysql
- stage: PHP Dev
if: type = push AND branch = 17.0
php: nightly

View File

@ -31,7 +31,7 @@ NuSoap 0.9.5 LGPL 2.1+ Yes
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
PHPDebugBar 1.15.1 MIT License Yes Used only by the module "debugbar" for developers
PHPDebugBar 1.18.2 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 4.1.1 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP

307
ChangeLog
View File

@ -5,12 +5,13 @@ English Dolibarr ChangeLog
***** ChangeLog for 18.0.0 compared to 17.0.0 *****
NEW: PHP 8.2 compatibility:
NEW: PHP 8.2 compatibility.
WARNING:
Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
* Minimal PHP version is now PHP 7.1 instead of PHP 7.0
* The deprecated method "escapeunderscore()" of database handlers has been removed. You must use "escapeforlike()" instead.
* The method "nb_expedition()" has been renamed into "countNbOfShipments()"
* Revert default type of hooks. Default is now 'addreplace' hooks (and exception become 'output' hooks, that become deprecated).
@ -18,222 +19,206 @@ Following changes may create regressions for some external modules, but were nec
* The type 'text' in ->fields property dos not accept html content anymore. Use the type 'html' for that.
***** ChangeLog for 17.0.1 compared to 17.0.0 *****
TODO
***** 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: #19680 Add option PRODUCT_ALLOW_EXTERNAL_DOWNLOAD to automatically have uploaded files shared publicly by a link
NEW: #21780 Add pid field to Cronjob class and store PID on job execution
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: #21780 Add pid field to Cronjob class and store PID on job execution
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 add image for event_array
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: #22048 Added notes to productlot module
NEW: #22298 Bank - Add salaries & vat in the tab of planned entries of a bank account
NEW: #22328 OAuth admin
NEW: #22424 online signature for contracts
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: #22735 Massaction to assign users on projects
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 button "Test collect" in email collector
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 IMAP port setting on email collector module
NEW: Adding JAPAN Chart-of-Account and regions/departments
NEW: Adding NIF verification for Algeria
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 new global variable for keeping the previous signature information on proposal (case of reopening a proposal)
NEW: Add objectLink on shipment
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: 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 when adding new product lines on invoices, orders, proposals, ...
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 on 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 doc template of contracts is not mandatory
NEW: Default values in extrafields are no more limited to 255 char.
NEW: display currency in takepos menu
NEW: Enable online signature for interventions
NEW: extrafield price with currency
NEW: filter on reception dates (from / to) in cheque paiement card
NEW: Members: default_lang for members
NEW: Members: Table of membership types
NEW: Members: add free membership amounts at the membership type level
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: Website: Add counters for public access of pages on a website
NEW: If we select another view list mode, we keep it
NEW: Init module bookcal
NEW: Encrypt all sensitive constants in llx_const using dolEncrypt/dolDecrypt
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 Position (Rank) on Contract Lines
NEW: Manage VAT on all lines on purchases cycle
NEW: Page to show 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: private and public note columns on user, thirdparty and contact lists
NEW: Public counters feature
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: Project - author field become an available column on lists
NEW: Reception - Add a from/to on search on date field
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: Can skip accept/refuse steps 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: 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: Show delivery mode on PDF for proposals
NEW: Add the target to select attendees of event for emailings
NEW: add redirect on action confirm addconsumedline and addproduceline
NEW: Add the referrer-policy to "same-origin" by default on all public pages.
NEW: Add trigger to record the event of sending an email from a project #20912
NEW: Allow download link option in module configuration (propal, order, invoice, supplier proposal)
NEW: Can enter the unit price including the VAT
NEW: Can invoice task time per different services
NEW: Can set a commercial discount by entering amount including VAT
NEW: Can set start and end dates and comment on button "Activate all services"
NEW: show date delivery planned on orders linked to company and product
NEW: filter on reception dates (from / to) in cheque paiement card
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 - Invoice export : add accounting affectation
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: Agenda - start a simple support of recurrent events on agenda
NEW: Bank - add salaries & VAT in tab planned entries
NEW: Bank - on a bank reconciled line, we can modify the bank receipt
NEW: Contracts - add a method doAutoRenewContracts that can be used as a cron task
NEW: Contracts - default template of contract is not mandatory
NEW: Contracts - Manage Position (Rank) on Contract Lines
NEW: EMail - can copy/paste images into emails sent
NEW: EMail - can edit label of an emailing even once sent
NEW: EMail - can join several files by default on email form
NEW: EMail - can send an email on scheduled job error
NEW: EMail - on a form to send an email, we show all emails of all contacts of object
NEW: EMail - add the SMTP header References on ticket email created by email
NEW: EMail - add substitution key __SENDEREMAIL_SIGNATURE__
NEW: EMail - experimental SMTP using PhpImap allowing OAuth2 authentication (need to add option MAIN_IMAP_USE_PHPIMAP)
NEW: EMail-Collector - add IMAP port setting
NEW: EMail-Collector - add a button "Test collect"
NEW: Event-Organization - add date event (!= date project) and location on event organization
NEW: Expedition - add objectLink on expedition
NEW: Export - Add " as enclosure by default for CSV export. Keep removing CR/LF.
NEW: Extrafields - add badge in admin extrafields setup
NEW: Extrafields - can edit property css, cssview, csslist on extrafields
NEW: Extrafields - default values in extrafields are not more limited to 255 char.
NEW: Extrafields - field price with currency
NEW: Extrafields - support IP type to store IP addresses
NEW: Finance - VAT - Admin - Add information on deadline day for submission of VAT declaration
NEW: Interventions - enable online signature for interventions
NEW: Invoice - add french mention on PDF when VAT debit option is on
NEW: Members - default_lang for members
NEW: Members - table of membership types
NEW: Members - add free membership amounts at the membership type level
NEW: OAuth - possibility to select scopes with checkbox for OAuth tokens
NEW: OAuth - saved token of OAUTH module are now encrypted into llx_oauth_token
NEW: Orders - resize parent company column in order list
NEW: Products - Categories - label on products categories filter
NEW: Products - Supplier price - autofill default supplier VAT
NEW: Products - Supplier price - can sort and preselected best supplier price
NEW: Projects - add author on list
NEW: Projects - add thirdparty column to the time list (projet/tasks/time.php)
NEW: Proposals - show delivery mode on PDF for proposals
NEW: Proposals - skip accept/refuse process for proposals (option PROPAL_SKIP_ACCEPT_REFUSE)
NEW: Reception - add a from/to on search on date field
NEW: Stock - page for mass stock transfer can be used with no source stock
NEW: Stock - product categories filter on inventory list
NEW: Stock - show product label on inventory
NEW: Stock - manage virtual stock at a future date
NEW: Stock Inventory - add filter "Product subject to lot/Serial" in stock per lot/serial
NEW: Stock Inventory - can use products categories to make inventory
NEW: Supplier Order List - add column private and public note
NEW: TakePOS - add margin infos to TakePOS invoice lines
NEW: TakePOS - add price to product box in TakePOS
NEW: TakePOS - add setup parameters, can setup terminal name
NEW: TakePOS - different product list on smartphone
NEW: TakePOS - display currency in TakePOS menu
NEW: TakePOS - Header Scroll in TakePOS
NEW: TakePOS - Receipt preview in TakePOS setup
NEW: TakePOS - support of Stripe Terminal with TakePOS
NEW: Thirdparty - manage no email with thirdparties (better for GDPR)
NEW: Thirdparty - set thirdparty type with company modify trigger
NEW: Tickets - change filter type on tickets list into a multiselect combo
NEW: Tickets - add oldcopy to Ticket so triggers intercepting TICKET_MODIFY have access to old values of the updated properties
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
General:
NEW: Actions: Bulk action to remove a category in list/search website pages
NEW: Cronjobs: can set a monthly frequency (or multiple) in cron tasks
NEW: Database: Encrypt all sensitive constants in llx_const
NEW: Database: Add performance index (name for company and contact) and llx_bank_url(url_id)
NEW: Database: Introduce dolEncrypt and dolDecrypt to be able to encrypt data in db
NEW: GUI: If we select another view list mode, we keep it
NEW: GUI: the link "add to bookmark" is always on top in the bookmark popup
NEW: GUI: Picto for shared link is clickable
NEW: GUI: add picto property on sub-module for password generation
NEW: GUI: show also scheduled task never finished in scheduled task widget
NEW: GUI: show badge with number of extrafields in setup
NEW: GUI: show category tree in sellist and chkbxlst for common object
NEW: GUI: show picto and color into combo for selection of tags
NEW: GUI: show sell-by and eat-by dates only if not empty
NEW: GUI: show SellBy/EatBy dates for each batch product in shipment card
NEW: GUI/Permissions: expand/collapse permissions on user permission page
NEW: Permissions: add a new advanced permission "read price"
NEW: Print: add show "Sales rep" option for PDF
NEW: Security: add fail2ban rules examples to limit access to /public pages
Option / Const for System:
NEW: FICHINTER_ALLOW_EXTERNAL_DOWNLOAD
NEW: MAIN_CHECKBOX_LEFT_COLUMN
NEW: MAIN_EMAIL_SUPPORT_ACK
NEW: MAIN_IMAP_USE_PHPIMAP
NEW: MAIN_SEARCH_CATEGORY_PRODUCT_ON_LISTS - const to show category customer filter
NEW: PRODUCT_ALLOW_EXTERNAL_DOWNLOAD
NEW: PRODUCTBATCH_SHOW_WAREHOUSE_ON_SHIPMENT - showing warehouse on PDF
NEW: PRODUIT_DESC_IN_FORM accept - desktop only or +smartphone
NEW: PROPAL_BYPASS_VALIDATED_STATUS
NEW: PROPAL_NEW_AS_SIGNED
NEW: PROPAL_SKIP_ACCEPT_REFUSE
NEW: TIMESPENT_ALWAYS_UPDATE_THM - when it's on we always check current thm of user to update it in task time line
Localisation:
NEW: adding JAPAN Chart-of-Account and regions/departments
NEW: adding NIF verification for Algeria
NEW: Can set background style with MAIN_LOGIN_BACKGROUND_STYLE
Modules
NEW: Experimental module Asset
NEW: Init module bookcal
NEW: Make module WebservicesClient deprecated. Use module WebHook instead.
For developers or integrators:
------------------------------
NEW: ModuleBuilder can generate code of class from an existing SQL table
NEW: ModuleBuilder can generate code for a class from an existing SQL table
NEW: #22370 Modulebuilder supports 'alwayseditable' (like extrafields)
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: All ajax pages have now a top_httphead()
API:
NEW: translation for contact type API, setup/ticket API, shipping method API
NEW: All ajax pages have now a header build with 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: translate for contact type API, setup/ticket API, shipping method API
NEW: support multilang in Civilities API
Hooks:
NEW: Actioncomm - add new hooks for actioncomm
NEW: Actioncomm - hook formConfirm on actioncomm card
NEW: Agenda - hook on agenda pages
NEW: Help - hook "changeHelpURL" to modify target of the help button
NEW: Product - add hook to show virtual stock details on product stock card
NEW: Product - add hook to modify supplier product html select
NEW: TakePOS - add hook to complete payment in TakePOS
NEW: Removed completely the need for the library adodbtime
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
NEW: Replace property fk_categories_product with categories_product in inventory class
NEW: Rewrite of SQL request. Removed the join on category table (for filter on category), replaced with a EXISTS/NOT
NEW: Add oldcopy to Ticket so triggers intercepting TICKET_MODIFY have access to old values of the updated properties
NEW: #19680 Add option PRODUCT_ALLOW_EXTERNAL_DOWNLOAD to automatically have uploaded files shared publicly by a link
NEW: Add option FICHINTER_ALLOW_EXTERNAL_DOWNLOAD
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
* The signature of method getNomUrl() of class ProductFournisseur has been modified to match the signature of method Product->getNomUrl()
* 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.
@ -245,7 +230,9 @@ Following changes may create regressions for some external modules, but were nec
* Making a global search is sending the parameter using always the name search_all (instead of sometimes sall and search_all)
* The property $url_last_version must be public if defined into module descriptor files;
***** ChangeLog for 16.0.5 compared to 16.0.4 *****
TODO
***** ChangeLog for 16.0.4 compared to 16.0.3 *****

View File

@ -2,7 +2,7 @@
![Downloads per day](https://img.shields.io/sourceforge/dw/dolibarr.svg)
![Build status](https://img.shields.io/travis/Dolibarr/dolibarr/develop.svg)
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%205.6-8892BF.svg?style=flat-square)](https://php.net/)
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.0-8892BF.svg?style=flat-square)](https://php.net/)
[![GitHub release](https://img.shields.io/github/v/release/Dolibarr/dolibarr)](https://github.com/Dolibarr/dolibarr)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5521/badge)](https://bestpractices.coreinfrastructure.org/projects/5521)

View File

@ -67,7 +67,7 @@ Scope is the web application (back office) and the APIs.
* Remote code execution (RCE)
* Local files access and manipulation (LFI, RFI, XXE, SSRF, XSPA)
* Code injections (HTML, JS, SQL, PHP, ...)
* Code injections (JS, SQL, PHP). HTML are covered only for fields that are not description, notes or comments fields (where rich content is allowed on purpose).
* Cross-Site Scripting (XSS), except from setup page of module "External web site" (allowing any content here, editable by admin user only, is accepted on purpose) and except into module "Web site" when permission to edit website content is allowed (injecting any data in this case is allowed too).
* Cross-Site Requests Forgery (CSRF) with real security impact (when using GET URLs, CSRF are qualified only for creating, updating or deleting data from pages restricted to admin users)
* Open redirect

View File

@ -1,28 +0,0 @@
README
------
Scripts in this directory can be used to reload or save a demo database.
Install of package "dialog" is required.
*** Init demo
The script initdemo.sh will erase current database with data into mysqldump_dolibarr_x.y.z.sql and copy files into documents_demo into officiel document directory.
Do a chmod 700 initdemo.sh
then run ./initdemo.sh to launch Graphic User Interface.
After loading the demo files, admin login may be:
- admin / admin
or
- admin / adminadmin
*** Save demo
The script savedemo.sh will save current database into a database dump file.
*** Update demo
The goal of script updatedemo.php is to update dates into the demo data so samples are up to date.

32
dev/initdemo/README.md Normal file
View File

@ -0,0 +1,32 @@
README
======
Scripts in this directory can be used to reload or save a demo database.
Install of package "dialog" is required.
Init demo
-------------
The script initdemo.sh will erase current database with data intodev/initdemo/mysqldump_dolibarr_x.y.z.sql and copy files into documents_demo into officiel document directory.
Do a chmod 700 initdemo.sh
then run ./initdemo.sh to launch Graphic User Interface.
After loading the demo files, admin login may be:
- admin / admin
or
- admin / adminadmin
Update demo
-------------
The goal of script dev/initdemo/updatedemo.php is to update dates into the demo data so samples are up to date.
Save demo
-------------
The script dev/initdemo.savedemo.sh will save current database into a database dump file.

File diff suppressed because one or more lines are too long

View File

@ -290,6 +290,7 @@ export list="
--ignore-table=$base.llx_monmodule_abcdef
--ignore-table=$base.llx_notes
--ignore-table=$base.llx_packages
--ignore-table=$base.llx_packages_extrafields
--ignore-table=$base.llx_pos_cash
--ignore-table=$base.llx_pos_control_cash
--ignore-table=$base.llx_pos_facture
@ -305,6 +306,19 @@ export list="
--ignore-table=$base.llx_residence
--ignore-table=$base.llx_residence_building
--ignore-table=$base.llx_residence_building_links
--ignore-table=$base.llx_scaninvoices_filestoimport
--ignore-table=$base.llx_scaninvoices_filestoimport_extrafields
--ignore-table=$base.llx_scaninvoices_settings
--ignore-table=$base.llx_scaninvoices_settings_extrafields
--ignore-table=$base.llx_sellyoursaas_blacklistcontent
--ignore-table=$base.llx_sellyoursaas_blacklistdir
--ignore-table=$base.llx_sellyoursaas_blacklistfrom
--ignore-table=$base.llx_sellyoursaas_blacklistip
--ignore-table=$base.llx_sellyoursaas_blacklistmail
--ignore-table=$base.llx_sellyoursaas_blacklistto
--ignore-table=$base.llx_sellyoursaas_deploymentserver
--ignore-table=$base.llx_sellyoursaas_stats
--ignore-table=$base.llx_sellyoursaas_whitelistip
--ignore-table=$base.llx_societe_rib2
--ignore-table=$base.llx_sellyoursaas_cancellation
--ignore-table=$base.llx_ticketsup

View File

@ -4,7 +4,6 @@
* 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
@ -45,7 +44,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 = $mode = $action == 'create' ? "_tmp" : GETPOST('mode', 'aZ09'); // '' or '_tmp'
$mode = 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);
@ -55,15 +54,10 @@ $accountingaccount_number = GETPOST('accountingaccount_number', 'alphanohtml');
$accountingaccount->fetch(null, $accountingaccount_number, true);
$accountingaccount_label = $accountingaccount->label;
$journal_code = GETPOST('code_journal', 'alpha') ? GETPOST('code_journal', 'alpha') : "NULL";
$journal_code = GETPOST('code_journal', 'alpha');
$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;
@ -78,10 +72,6 @@ $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';
@ -166,79 +156,64 @@ if ($action == "confirm_update") {
}
}
}
} elseif ($action == 'add' || $action == 'valid') {
} elseif ($action == "add") {
$error = 0;
if (array_sum($debit) != array_sum($credit)) {
$action = 'add';
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 = '';
}
foreach ($accountingaccount_number as $key => $value) {
$accountingaccount->fetch(null, $accountingaccount_number[$key], true);
$accountingaccount_label[$key] = $accountingaccount->label[$key];
if (!$error) {
$object = new BookKeeping($db);
// 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;
$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 ((floatval($debit[$key]) != 0.0) && (floatval($credit[$key]) != 0.0)) {
$error++;
setEventMessages($langs->trans('ErrorDebitCredit'), null, 'errors');
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;
$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);
@ -255,28 +230,17 @@ if ($action == "confirm_update") {
}
}
$action = '';
} elseif ($action == 'create') {
} elseif ($action == "confirm_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 (empty($doc_ref)) {
if (!GETPOST('doc_ref', 'alpha')) {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Piece")), null, 'errors');
$action = 'create';
$error++;
@ -288,8 +252,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 = $next_num_mvt;
$object->doc_ref = $doc_ref;
$object->piece_num = GETPOST('next_num_mvt', 'alpha');
$object->doc_ref = GETPOST('doc_ref', 'alpha');
$object->code_journal = $journal_code;
$object->journal_label = $journal_label;
$object->fk_doc = 0;
@ -338,7 +302,7 @@ if ($action == 'setjournal') {
}
if ($action == 'setdocref') {
$refdoc = $doc_ref;
$refdoc = GETPOST('doc_ref', 'alpha');
$result = $object->updateByMvt($piece_num, 'doc_ref', $refdoc, $mode);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
@ -369,7 +333,7 @@ if ($action == 'valid') {
$html = new Form($db);
$formaccounting = new FormAccounting($db);
$title = $langs->trans($mode =="_tmp" ? "CreateMvts": "UpdateMvts");
$title = $langs->trans("CreateMvts");
llxHeader('', $title);
@ -379,37 +343,28 @@ if ($action == 'delete') {
print $formconfirm;
}
if ($action == 'create') {
print load_fiche_titre($title);
$object = new BookKeeping($db);
$result = $object->fetchPerMvt($piece_num, $mode);
if ($result < 0) {
setEventMessages($object->error, $object->errors, 'errors');
}
$object = new BookKeeping($db);
$next_num_mvt = $object->getNextNumMvt('_tmp');
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.'" />';
if (empty($next_num_mvt)) {
dol_print_error('', 'Failed to get next piece number');
}
$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);
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";
//dol_banner_tab($object, '', $backlink);
print dol_get_fiche_head();
print '<div class="fichecenter">';
print '<div class="fichehalfleft">';
print '<div class="underbanner clearboth"></div>';
print '<table class="border tableforfield" width="100%">';
print '<table class="border centpercent">';
/*print '<tr>';
print '<td class="titlefieldcreate fieldrequired">' . $langs->trans("NumPiece") . '</td>';
@ -419,7 +374,7 @@ if (!empty($object->piece_num)) {
print '<tr>';
print '<td class="titlefieldcreate fieldrequired">'.$langs->trans("Docdate").'</td>';
print '<td>';
print $html->selectDate($doc_date, 'doc_date', '', '', '', "create_mvt", 1, 1);
print $html->selectDate('', 'doc_date', '', '', '', "create_mvt", 1, 1);
print '</td>';
print '</tr>';
@ -430,218 +385,298 @@ if (!empty($object->piece_num)) {
print '<tr>';
print '<td class="fieldrequired">'.$langs->trans("Piece").'</td>';
print '<td><input type="text" class="minwidth200" name="doc_ref" value="'.$doc_ref.'" /></td>';
print '<td><input type="text" class="minwidth200" name="doc_ref" value="'.GETPOST('doc_ref', 'alpha').'"></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 '</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>';
// 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>';
}
// 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 dol_get_fiche_end();
print '<div class="clearboth"></div>';
print $form->buttonsSaveCancel("Create");
print '<br>';
$result = $object->fetchAllPerMvt($piece_num, $mode); // This load $object->linesmvt
print '</form>';
} else {
$object = new BookKeeping($db);
$result = $object->fetchPerMvt($piece_num, $mode);
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.'" />';
if (!empty($object->piece_num)) {
$backlink = '<a href="'.DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?restore_lastsearch_values=1">'.$langs->trans('BackToList').'</a>';
if ($mode == '_tmp') {
print load_fiche_titre($langs->trans("CreateMvts"), $backlink);
} else {
print load_fiche_titre($langs->trans("UpdateMvts"), $backlink);
}
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";
$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++;
if (count($object->linesmvt) > 0) {
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print dol_get_fiche_head($head, 'transaction', '', -1);
$total_debit = 0;
$total_credit = 0;
//dol_banner_tab($object, '', $backlink);
// 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>';
print '<div class="fichecenter">';
print '<div class="fichehalfleft">';
// 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 '<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>';
print '<tr class="liste_titre">';
// 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>';
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 ');
// 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>';
// 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>';
}
// 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_liste_field_titre("");
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>';
*/
print "</tr>\n";
// In _tmp mode the first line is empty so we remove it
if ($mode == "_tmp") {
array_shift($object->linesmvt);
// 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";
// Add an empty line at the end to be able to add transaction
$line = new BookKeepingLine();
$object->linesmvt[] = $line;
print '</div>';
// Add a second line empty line if there is not yet
if (empty($object->linesmvt[1])) {
$line = new BookKeepingLine();
$object->linesmvt[] = $line;
print dol_get_fiche_end();
print '<div class="clearboth"></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"), '', '');
print '<form 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="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";
$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 (count($object->linesmvt) > 0) {
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
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")).'" />';
$total_debit = 0;
$total_credit = 0;
print '<tr class="liste_titre">';
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>\n";
// Add an empty line if there is not yet
if (!empty($object->linesmvt[0])) {
$tmpline = $object->linesmvt[0];
if (!empty($tmpline->numero_compte)) {
$line = new BookKeepingLine();
$object->linesmvt[] = $line;
}
// 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 -->';
}
foreach ($object->linesmvt as $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((is_array($accountingaccount_number) ? $accountingaccount_number[$key] : $accountingaccount_number ), 'accountingaccount_number['.$key.']', 1, array(), 1, 1, '');
print $formaccounting->select_account((GETPOSTISSET("accountingaccount_number") ? GETPOST("accountingaccount_number", "alpha") : $line->numero_compte), 'accountingaccount_number', 1, array(), 1, 1, 'minwidth200 maxwidth500');
print '</td>';
print '<td>';
// TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because:
@ -649,102 +684,124 @@ if (!empty($object->piece_num)) {
// 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((is_array($subledger_account) ? $subledger_account[$key] : $subledger_account ), 'subledger_account['.$key.']', 1, 'maxwidth250', '', 'subledger_label');
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['.$key.']" value="' . (is_array($subledger_account) ? $subledger_account[$key] : $subledger_account ) . '" placeholder="' . dol_escape_htmltag($langs->trans("SubledgerAccount")) . '" />';
print '<input type="text" class="maxwidth150" name="subledger_account" value="'.(GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account).'" placeholder="'.dol_escape_htmltag($langs->trans("SubledgerAccount")).'">';
}
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")) . '" />';
// 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['.$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>';
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, 'minwidth200 maxwidth500');
print '</td>';
print '<td>';
// TODO For the moment we keep a free input text instead of a combo. The select_auxaccount has problem because:
// It does not use the setup of "key pressed" to select a thirdparty and this hang browser on large databases.
// Also, it is not possible to use a value that is not in the list.
// Also, the label is not automatically filled when a value is selected.
if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) {
print $formaccounting->select_auxaccount('', 'subledger_account', 1, 'maxwidth250', '', 'subledger_label');
} else {
print '<input type="text" class="maxwidth150" name="subledger_account" value="" placeholder="' . dol_escape_htmltag($langs->trans("SubledgerAccount")) . '">';
}
print '<br><input type="text" class="maxwidth150" name="subledger_label" value="" placeholder="' . dol_escape_htmltag($langs->trans("SubledgerAccountLabel")) . '">';
print '</td>';
print '<td><input type="text" class="minwidth200" name="label_operation" value="' . $label_operation . '"/></td>';
print '<td class="right"><input type="text" size="6" class="right" name="debit" value=""/></td>';
print '<td class="right"><input type="text" size="6" class="right" name="credit" value=""/></td>';
print '<td class="center"><input type="submit" class="button small" name="save" value="' . $langs->trans("Add") . '"></td>';
}
} else {
print '<!-- td columns in display mode -->';
$resultfetch = $accountingaccount->fetch(null, $line->numero_compte, true);
print '<td>';
if ($resultfetch > 0) {
print $accountingaccount->getNomUrl(0, 1, 1, '', 0);
} else {
print '<td class="right"></td>';
print $line->numero_compte.' <span class="warning">('.$langs->trans("AccountRemovedFromCurrentChartOfAccount").')</span>';
}
}
} 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 $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>';
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;';
}
if (empty($line->date_validation)) {
$actiontodelete = 'delete';
if ($mode == '_tmp' || $action != 'delmouv') {
$actiontodelete = 'confirm_delete';
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 '<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>';
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 '<a class="editfielda nohover cursornotallowed disabled" href="#" title="'.dol_escape_htmltag($langs->trans("ForbiddenTransactionAlreadyExported")).'">';
print img_delete($langs->trans("ForbiddenTransactionAlreadyValidated"));
print '</a>';
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 '</td>';
print ' &nbsp; ';
print '<a class="button button-cancel" href="'.DOL_URL_ROOT.'/accountancy/bookkeeping/list.php">'.$langs->trans("Cancel").'</a>';
print "</div>";
}
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 '<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>";
}
print '</form>';
}
print '</form>';
} else {
print load_fiche_titre($langs->trans("NoRecords"));
}
} else {
print load_fiche_titre($langs->trans("NoRecords"));
}
print dol_get_fiche_end();

View File

@ -754,30 +754,33 @@ if ($action == 'export_fileconfirm' && $user->hasRight('accounting', 'mouvements
} else {
if (!empty($notifiedexportdate) || !empty($notifiedvalidationdate)) {
if (is_array($object->lines)) {
dol_syslog("/accountancy/bookkeeping/list.php Function export_file Specify movements as exported", LOG_DEBUG);
// Specify as export : update field date_export or date_validated
$db->begin();
// TODO Merge update for each line into one gloacl using rowid IN (list of movement ids)
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)."'";
$setfields = '';
if (!empty($notifiedexportdate) && empty($movement->date_export)) {
$setfields .= ($setfields ? "," : "")." date_export = '".$db->idate($now)."'";
}
if (!empty($notifiedvalidationdate) && empty($movement->date_validation)) {
$setfields .= ($setfields ? "," : "")." 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);
if ($setfields) {
$sql = " UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping";
$sql .= " SET ".$setfields;
$sql .= " WHERE rowid = ".((int) $movement->id);
$result = $db->query($sql);
if (!$result) {
$error++;
break;
$result = $db->query($sql);
if (!$result) {
$error++;
break;
}
}
}
@ -1014,17 +1017,17 @@ $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("ClickToHideAlreadyExportedLines"), 'switch_off', 'class="small size15x valignmiddle"');
$newcardbutton .= '<a class="valignmiddle" href="'.$_SERVER['PHP_SELF'].'?action=setreexport&token='.newToken().'&value=0'.($param ? '&'.$param : '').'&sortfield='.urlencode($sortfield).'&sortorder='.urlencode($sortorder).'">'.img_picto($langs->trans("ClickToHideAlreadyExportedLines"), 'switch_off', 'class="small size15x valignmiddle"');
$newcardbutton .= '<span class="valignmiddle marginrightonly paddingleft">'.$langs->trans("ClickToHideAlreadyExportedLines").'</span>';
$newcardbutton .= '</a>';
} else {
$newcardbutton .= '<a class="valignmiddle" href="'.$_SERVER['PHP_SELF'].'?action=setreexport&token='.newToken().'&value=1'.($param ? '&'.$param : '').'">'.img_picto($langs->trans("DocsAlreadyExportedAreExcluded"), 'switch_on', 'class="warning size15x valignmiddle"');
$newcardbutton .= '<a class="valignmiddle" href="'.$_SERVER['PHP_SELF'].'?action=setreexport&token='.newToken().'&value=1'.($param ? '&'.$param : '').'&sortfield='.urlencode($sortfield).'&sortorder='.urlencode($sortorder).'">'.img_picto($langs->trans("DocsAlreadyExportedAreExcluded"), 'switch_on', 'class="warning size15x valignmiddle"');
$newcardbutton .= '<span class="valignmiddle marginrightonly paddingleft">'.$langs->trans("DocsAlreadyExportedAreExcluded").'</span>';
$newcardbutton .= '</a>';
}
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($buttonLabel, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', 'fa fa-file-export paddingleft', $_SERVER["PHP_SELF"].'?action=export_file&token='.newToken().($param ? '&'.$param : '').'&sortfield='.urlencode($sortfield).'&sortorder='.urlencode($sortorder), $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'));
@ -1355,6 +1358,9 @@ while ($i < min($num, $limit)) {
print '<input id="cb'.$line->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$line->id.'"'.($selected ? ' checked="checked"' : '').' />';
}
print '</td>';
if (!$i) {
$totalarray['nbfield']++;
}
}
// Piece number
@ -1522,7 +1528,7 @@ while ($i < min($num, $limit)) {
// Creation operation date
if (!empty($arrayfields['t.date_creation']['checked'])) {
print '<td class="center">'.dol_print_date($line->date_creation, 'dayhour').'</td>';
print '<td class="center">'.dol_print_date($line->date_creation, 'dayhour', 'tzuserrel').'</td>';
if (!$i) {
$totalarray['nbfield']++;
}
@ -1530,7 +1536,7 @@ while ($i < min($num, $limit)) {
// Modification operation date
if (!empty($arrayfields['t.tms']['checked'])) {
print '<td class="center">'.dol_print_date($line->date_modification, 'dayhour').'</td>';
print '<td class="center">'.dol_print_date($line->date_modification, 'dayhour', 'tzuserrel').'</td>';
if (!$i) {
$totalarray['nbfield']++;
}
@ -1538,7 +1544,7 @@ while ($i < min($num, $limit)) {
// Exported operation date
if (!empty($arrayfields['t.date_export']['checked'])) {
print '<td class="center nowraponall">'.dol_print_date($line->date_export, 'dayhour').'</td>';
print '<td class="center nowraponall">'.dol_print_date($line->date_export, 'dayhour', 'tzuserrel').'</td>';
if (!$i) {
$totalarray['nbfield']++;
}
@ -1546,7 +1552,7 @@ while ($i < min($num, $limit)) {
// Validated operation date
if (!empty($arrayfields['t.date_validated']['checked'])) {
print '<td class="center nowraponall">'.dol_print_date($line->date_validation, 'dayhour').'</td>';
print '<td class="center nowraponall">'.dol_print_date($line->date_validation, 'dayhour', 'tzuserrel').'</td>';
if (!$i) {
$totalarray['nbfield']++;
}
@ -1570,11 +1576,11 @@ while ($i < min($num, $limit)) {
print '<input id="cb'.$line->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$line->id.'"'.($selected ? ' checked="checked"' : '').' />';
}
print '</td>';
if (!$i) {
$totalarray['nbfield']++;
}
}
if (!$i) {
$totalarray['nbfield']++;
}
print "</tr>\n";

View File

@ -951,6 +951,10 @@ while ($i < min($num, $limit)) {
if (!empty($arrayfields['t.date_export']['checked'])) { $colspanend++; }
if (!empty($arrayfields['t.date_validating']['checked'])) { $colspanend++; }
if (!empty($arrayfields['t.lettering_code']['checked'])) { $colspanend++; }
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
$colspan++;
$colspanend--;
}
// Is it a break ?
if ($accountg != $displayed_account_number || !isset($displayed_account_number)) {
@ -990,7 +994,9 @@ while ($i < min($num, $limit)) {
print '<td colspan="'.($totalarray['nbfield'] ? $totalarray['nbfield'] : count($arrayfields)+1).'" class="tdforbreak">';
if ($type == 'sub') {
if ($line->subledger_account != "" && $line->subledger_account != '-1') {
print $line->subledger_label . ' : ' . length_accounta($line->subledger_account);
print empty($line->subledger_label) ? '<span class="error">'.$langs->trans("Unknown").'</span>' : $line->subledger_label;
print ' : ';
print length_accounta($line->subledger_account);
} else {
// Should not happen: subledger account must be null or a non empty value
print '<span class="error">' . $langs->trans("Unknown");
@ -1033,6 +1039,9 @@ while ($i < min($num, $limit)) {
print '<input id="cb' . $line->id . '" class="flat checkforselect" type="checkbox" name="toselect[]" value="' . $line->id . '"' . ($selected ? ' checked="checked"' : '') . ' />';
}
print '</td>';
if (!$i) {
$totalarray['nbfield']++;
}
}
// Piece number
if (!empty($arrayfields['t.piece_num']['checked'])) {
@ -1216,9 +1225,9 @@ while ($i < min($num, $limit)) {
print '<input id="cb' . $line->id . '" class="flat checkforselect" type="checkbox" name="toselect[]" value="' . $line->id . '"' . ($selected ? ' checked="checked"' : '') . ' />';
}
print '</td>';
}
if (!$i) {
$totalarray['nbfield']++;
if (!$i) {
$totalarray['nbfield']++;
}
}
// Comptabilise le sous-total

View File

@ -646,7 +646,7 @@ class AccountancyCategory // extends CommonObject
}
$sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as t";
//if (in_array($this->db->type, array('mysql', 'mysqli'))) $sql.=' USE INDEX idx_accounting_bookkeeping_doc_date';
$sql .= " WHERE t.entity = ".$conf->entity;
$sql .= " WHERE t.entity = ".((int) $conf->entity);
if (is_array($cpt)) {
$sql .= " AND t.numero_compte IN (".$this->db->sanitize($listofaccount, 1).")";
} else {

View File

@ -37,7 +37,6 @@
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';

View File

@ -388,12 +388,6 @@ class AccountingJournal extends CommonObject
if (empty($type)) $type = 'view';
if (empty($in_bookkeeping)) $in_bookkeeping = 'notyet';
// Hook
if (!is_object($hookmanager)) {
include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
$hookmanager = new HookManager($this->db);
}
$data = array();
$hookmanager->initHooks(array('accountingjournaldao'));
@ -790,12 +784,6 @@ class AccountingJournal extends CommonObject
global $conf, $langs, $hookmanager;
require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php';
// Hook
if (!is_object($hookmanager)) {
include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
$hookmanager = new HookManager($this->db);
}
$error = 0;
$hookmanager->initHooks(array('accountingjournaldao'));
@ -940,11 +928,6 @@ class AccountingJournal extends CommonObject
$out = '';
// Hook
if (!is_object($hookmanager)) {
include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
$hookmanager = new HookManager($this->db);
}
$hookmanager->initHooks(array('accountingjournaldao'));
$parameters = array('journal_data' => &$journal_data, 'search_date_end' => &$search_date_end, 'sep' => &$sep, 'out' => &$out);
$reshook = $hookmanager->executeHooks('exportCsv', $parameters, $this); // Note that $action and $object may have been

View File

@ -2088,7 +2088,7 @@ class BookKeeping extends CommonObject
* FIXME: This function takes the parent of parent to get the root account !
*
* @param string $account Accounting account
* @return array Array with root account information (max 2 upper level)
* @return array|int Array with root account information (max 2 upper level), <0 if KO
*/
public function getRootAccount($account = null)
{

View File

@ -329,6 +329,7 @@ class Lettering extends BookKeeping
// Update request
$now = dol_now();
$affected_rows = 0;
if (!$error) {
$sql = "UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping SET";
@ -341,6 +342,8 @@ class Lettering extends BookKeeping
if (!$resql) {
$error++;
$this->errors[] = "Error ".$this->db->lasterror();
} else {
$affected_rows = $this->db->affected_rows($resql);
}
}
@ -352,7 +355,7 @@ class Lettering extends BookKeeping
}
return -1 * $error;
} else {
return 1;
return $affected_rows;
}
}
@ -387,7 +390,7 @@ class Lettering extends BookKeeping
}
return -1 * $error;
} else {
return 1;
return $this->db->affected_rows($resql);
}
}
@ -482,7 +485,7 @@ class Lettering extends BookKeeping
else $result = $this->updateLettering($bookkeeping_lines);
if ($result < 0) {
$group_error++;
} else {
} elseif ($result > 0) {
$nb_lettering++;
}
}

View File

@ -128,8 +128,8 @@ if ($action == 'validatehistory') {
// Now make the binding. Bind automatically only for product with a dedicated account that exists into chart of account, others need a manual bind
// Customer Invoice lines (must be same request than into page list.php for manual binding)
$sql = "SELECT f.rowid as facid, f.ref as ref, f.datef, f.type as ftype, f.fk_facture_source,";
$sql .= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,";
$sql = "SELECT f.rowid as facid, f.ref as ref, f.datef, f.type as ftype, f.situation_cycle_ref, f.fk_facture_source,";
$sql .= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation, l.product_type as type_l, l.situation_percent, l.tva_tx as tva_tx_line, l.vat_src_code,";
$sql .= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, p.tva_tx as tva_tx_prod,";
if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
$sql .= " ppe.accountancy_code_sell as code_sell, ppe.accountancy_code_sell_intra as code_sell_intra, ppe.accountancy_code_sell_export as code_sell_export,";
@ -312,6 +312,10 @@ print '<span class="opacitymedium">'.$langs->trans("DescVentilCustomer").'</span
print '<span class="opacitymedium hideonsmartphone">'.$langs->trans("DescVentilMore", $langs->transnoentitiesnoconv("ValidateHistory"), $langs->transnoentitiesnoconv("ToBind")).'<br>';
print '</span><br>';
if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) {
print info_admin($langs->trans("SorryThisModuleIsNotCompatibleWithTheExperimentalFeatureOfSituationInvoices"));
print "<br>";
}
$y = $year_current;
@ -386,6 +390,11 @@ if ($resql) {
$num = $db->num_rows($resql);
while ($row = $db->fetch_row($resql)) {
// TODO When INVOICE_USE_SITUATION = 1, values here are wrong. There is no compensation on bad stored amounts
//$situation_ratio = 1;
//if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) {
//}
print '<tr class="oddeven">';
print '<td>';
if ($row[0] == 'tobind') {
@ -519,6 +528,11 @@ if ($resql) {
$num = $db->num_rows($resql);
while ($row = $db->fetch_row($resql)) {
// TODO When INVOICE_USE_SITUATION = 1, values here are wrong. There is no compensation on bad stored amounts
//$situation_ratio = 1;
//if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) {
//}
print '<tr class="oddeven">';
print '<td>';
if ($row[0] == 'tobind') {
@ -630,7 +644,6 @@ if (getDolGlobalString('SHOW_TOTAL_OF_PREVIOUS_LISTS_IN_LIN_PAGE')) { // This pa
print "</table>\n";
print '</div>';
if (isModEnabled('margin')) {
print "<br>\n";
print '<div class="div-table-responsive-no-min">';
@ -644,22 +657,41 @@ if (getDolGlobalString('SHOW_TOTAL_OF_PREVIOUS_LISTS_IN_LIN_PAGE')) { // This pa
print '<td width="60" class="right">'.$langs->trans('MonthShort'.str_pad($j, 2, '0', STR_PAD_LEFT)).'</td>';
}
print '<td width="60" class="right"><b>'.$langs->trans("Total").'</b></td></tr>';
$sql = "SELECT '".$db->escape($langs->trans("Vide"))."' AS marge,";
for ($i = 1; $i <= 12; $i++) {
$j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) - 1;
if ($j > 12) {
$j -= 12;
}
$sql .= " SUM(".$db->ifsql("MONTH(f.datef)=".$j,
" (".$db->ifsql("fd.total_ht < 0",
" (-1 * (abs(fd.total_ht) - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100))))",
" (fd.total_ht - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100)))").")",
0).") AS month".str_pad($j, 2, '0', STR_PAD_LEFT).",";
}
$sql .= " SUM(".$db->ifsql("fd.total_ht < 0",
" (-1 * (abs(fd.total_ht) - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100))))",
" (fd.total_ht - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100)))").") as total";
if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) {
// With old situation invoice setup
$sql = "SELECT '".$db->escape($langs->trans("Vide"))."' AS marge,";
for ($i = 1; $i <= 12; $i++) {
$j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) - 1;
if ($j > 12) {
$j -= 12;
}
$sql .= " SUM(".$db->ifsql("MONTH(f.datef)=".$j,
" (".$db->ifsql("fd.total_ht < 0",
" (-1 * (abs(fd.total_ht) - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100))))", // TODO This is bugged, we must use the percent for the invoice and fd.situation_percent is cumulated percent !
" (fd.total_ht - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100)))").")",
0).") AS month".str_pad($j, 2, '0', STR_PAD_LEFT).",";
}
$sql .= " SUM(".$db->ifsql("fd.total_ht < 0",
" (-1 * (abs(fd.total_ht) - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100))))", // TODO This is bugged, we must use the percent for the invoice and fd.situation_percent is cumulated percent !
" (fd.total_ht - (fd.buy_price_ht * fd.qty * (fd.situation_percent / 100)))").") as total";
} else {
$sql = "SELECT '".$db->escape($langs->trans("Vide"))."' AS marge,";
for ($i = 1; $i <= 12; $i++) {
$j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) - 1;
if ($j > 12) {
$j -= 12;
}
$sql .= " SUM(".$db->ifsql("MONTH(f.datef)=".$j,
" (".$db->ifsql("fd.total_ht < 0",
" (-1 * (abs(fd.total_ht) - (fd.buy_price_ht * fd.qty)))",
" (fd.total_ht - (fd.buy_price_ht * fd.qty))").")",
0).") AS month".str_pad($j, 2, '0', STR_PAD_LEFT).",";
}
$sql .= " SUM(".$db->ifsql("fd.total_ht < 0",
" (-1 * (abs(fd.total_ht) - (fd.buy_price_ht * fd.qty)))",
" (fd.total_ht - (fd.buy_price_ht * fd.qty))").") as total";
}
$sql .= " FROM ".MAIN_DB_PREFIX."facturedet as fd";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON f.rowid = fd.fk_facture";
$sql .= " WHERE f.datef >= '".$db->idate($search_date_start)."'";

View File

@ -189,8 +189,8 @@ print '<script type="text/javascript">
/*
* Customer Invoice lines
*/
$sql = "SELECT f.rowid as facid, f.ref as ref, f.type as ftype, f.datef, f.ref_client,";
$sql .= " fd.rowid, fd.description, fd.product_type as line_type, fd.total_ht, fd.total_tva, fd.tva_tx, fd.vat_src_code, fd.total_ttc,";
$sql = "SELECT f.rowid as facid, f.ref as ref, f.type as ftype, f.situation_cycle_ref, f.datef, f.ref_client,";
$sql .= " fd.rowid, fd.description, fd.product_type as line_type, fd.total_ht, fd.total_tva, fd.tva_tx, fd.vat_src_code, fd.total_ttc, fd.situation_percent,";
$sql .= " s.rowid as socid, s.nom as name, s.code_client,";
if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) {
$sql .= " spe.accountancy_code_customer as code_compta_client,";
@ -502,8 +502,33 @@ if ($result) {
print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description);
print '</td>';
print '<td class="right nowraponall amount">'.price($objp->total_ht).'</td>';
// Amount
print '<td class="right nowraponall amount">';
// Create a compensation rate for old situation invoice feature.
$situation_ratio = 1;
if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) {
if ($objp->situation_cycle_ref) {
// Avoid divide by 0
if ($objp->situation_percent == 0) {
$situation_ratio = 0;
} else {
$line = new FactureLigne($db);
$line->fetch($objp->rowid);
// Situation invoices handling
$prev_progress = $line->get_prev_progress($objp->facid);
$situation_ratio = ($objp->situation_percent - $prev_progress) / $objp->situation_percent;
}
}
print price($objp->total_ht * $situation_ratio);
} else {
print price($objp->total_ht);
}
print '</td>';
// Vat rate
print '<td class="right">'.vatrate($objp->tva_tx.($objp->vat_src_code ? ' ('.$objp->vat_src_code.')' : '')).'</td>';
// Thirdparty

View File

@ -228,8 +228,8 @@ if (empty($chartaccountcode)) {
}
// Customer Invoice lines
$sql = "SELECT f.rowid as facid, f.ref, f.datef, f.type as ftype, f.fk_facture_source,";
$sql .= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,";
$sql = "SELECT f.rowid as facid, f.ref, f.datef, f.type as ftype, f.situation_cycle_ref, f.fk_facture_source,";
$sql .= " l.rowid, l.fk_product, l.description, l.total_ht, l.situation_percent, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,";
$sql .= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, p.tva_tx as tva_tx_prod,";
if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
$sql .= " ppe.accountancy_code_sell as code_sell, ppe.accountancy_code_sell_intra as code_sell_intra, ppe.accountancy_code_sell_export as code_sell_export,";
@ -655,8 +655,30 @@ if ($result) {
print $form->textwithtooltip(dol_trunc($text, $trunclength), $facture_static_det->desc);
print '</td>';
// Amount
print '<td class="right nowraponall amount">';
print price($objp->total_ht);
// Create a compensation rate for old situation invoice feature.
$situation_ratio = 1;
if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) {
if ($objp->situation_cycle_ref) {
// Avoid divide by 0
if ($objp->situation_percent == 0) {
$situation_ratio = 0;
} else {
$line = new FactureLigne($db);
$line->fetch($objp->rowid);
// Situation invoices handling
$prev_progress = $line->get_prev_progress($objp->facid);
$situation_ratio = ($objp->situation_percent - $prev_progress) / $objp->situation_percent;
}
}
print price($objp->total_ht * $situation_ratio);
} else {
print price($objp->total_ht);
}
print '</td>';
// Vat rate

View File

@ -112,7 +112,7 @@ if ($action == 'validatehistory') {
$sql1 = "SELECT erd.rowid, accnt.rowid as suggestedid";
$sql1 .= " FROM ".MAIN_DB_PREFIX."expensereport_det as erd";
$sql1 .= " LEFT JOIN ".MAIN_DB_PREFIX."c_type_fees as t ON erd.fk_c_type_fees = t.id";
$sql1 .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as accnt ON t.accountancy_code = accnt.account_number AND accnt.active = 1 AND accnt.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND accnt.entity =".((int) $conf->entity);
$sql1 .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as accnt ON t.accountancy_code = accnt.account_number AND accnt.active = 1 AND accnt.fk_pcg_version = '".$db->escape($chartaccountcode)."' AND accnt.entity =".((int) $conf->entity).",";
$sql1 .= " ".MAIN_DB_PREFIX."expensereport as er";
$sql1 .= " WHERE erd.fk_expensereport = er.rowid AND er.entity = ".((int) $conf->entity);
$sql1 .= " AND er.fk_statut IN (".ExpenseReport::STATUS_APPROVED.", ".ExpenseReport::STATUS_CLOSED.") AND erd.fk_code_ventilation <= 0";

View File

@ -83,12 +83,7 @@ $help_url = 'EN:Module_Double_Entry_Accounting#Setup';
llxHeader('', $langs->trans("AccountancyArea"), $help_url);
if (!empty($conf->global->INVOICE_USE_SITUATION) && $conf->global->INVOICE_USE_SITUATION == 1) {
print load_fiche_titre($langs->trans("AccountancyArea"), '', 'accountancy');
print '<span class="opacitymedium">'.$langs->trans("SorryThisModuleIsNotCompatibleWithTheExperimentalFeatureOfSituationInvoices")."</span>\n";
print "<br>";
} elseif (isModEnabled('accounting')) {
if (isModEnabled('accounting')) {
$step = 0;
$resultboxes = FormOther::getBoxesArea($user, "27"); // Load $resultboxes (selectboxlist + boxactivated + boxlista + boxlistb)
@ -124,6 +119,7 @@ if (!empty($conf->global->INVOICE_USE_SITUATION) && $conf->global->INVOICE_USE_S
print "<br>\n";
print '<span class="opacitymedium">'.$langs->trans("AccountancyAreaDescIntro")."</span><br>\n";
if ($user->hasRight('accounting', 'chartofaccount')) {
print '<br>';
print load_fiche_titre('<span class="fa fa-calendar-check-o"></span> '.$langs->trans("AccountancyAreaDescActionOnce"), '', '')."\n";
print '<hr>';
print "<br>\n";

View File

@ -805,6 +805,12 @@ if (!$error && $action == 'writebookkeeping') {
require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
$lettering_static = new Lettering($db);
$nb_lettering = $lettering_static->bookkeepingLetteringAll(array($bookkeeping->id));
if ($nb_lettering < 0) {
$error++;
$errorforline++;
setEventMessages($lettering_static->error, $lettering_static->errors, 'errors');
}
}
}
}

View File

@ -381,6 +381,12 @@ if ($action == 'writebookkeeping') {
require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
$lettering_static = new Lettering($db);
$nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id));
if ($nb_lettering < 0) {
$error++;
$errorforline++;
setEventMessages($lettering_static->error, $lettering_static->errors, 'errors');
}
}
}
}

View File

@ -106,7 +106,7 @@ if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))
$date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
}
$sql = "SELECT f.rowid, f.ref, f.type, f.datef as df, f.ref_client, f.date_lim_reglement as dlr, f.close_code, f.retained_warranty,";
$sql = "SELECT f.rowid, f.ref, f.type, f.situation_cycle_ref, f.datef as df, f.ref_client, f.date_lim_reglement as dlr, f.close_code, f.retained_warranty,";
$sql .= " fd.rowid as fdid, fd.description, fd.product_type, fd.total_ht, fd.total_tva, fd.total_localtax1, fd.total_localtax2, fd.tva_tx, fd.total_ttc, fd.situation_percent, fd.vat_src_code, fd.info_bits,";
$sql .= " s.rowid as socid, s.nom as name, s.code_client, s.code_fournisseur,";
if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) {
@ -206,21 +206,23 @@ if ($result) {
$def_tva[$obj->rowid][$compta_tva][vatrate($obj->tva_tx).($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : '')] = (vatrate($obj->tva_tx).($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : ''));
}
if ($obj->type == Facture::TYPE_SITUATION) {
// Avoid divide by 0
if ($obj->situation_percent == 0) {
$situation_ratio = 0;
} else {
$line = new FactureLigne($db);
$line->fetch($obj->fdid);
// Create a compensation rate.
$situation_ratio = 1;
if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) {
if ($obj->situation_cycle_ref) {
// Avoid divide by 0
if ($obj->situation_percent == 0) {
$situation_ratio = 0;
} else {
$line = new FactureLigne($db);
$line->fetch($obj->fdid);
// Situation invoices handling
$prev_progress = $line->get_prev_progress($obj->rowid);
// Situation invoices handling
$prev_progress = $line->get_prev_progress($obj->rowid);
$situation_ratio = ($obj->situation_percent - $prev_progress) / $obj->situation_percent;
$situation_ratio = ($obj->situation_percent - $prev_progress) / $obj->situation_percent;
}
}
} else {
$situation_ratio = 1;
}
// Invoice lines
@ -461,7 +463,15 @@ if ($action == 'writebookkeeping') {
if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && getDolGlobalInt('ACCOUNTING_ENABLE_AUTOLETTERING')) {
require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
$lettering_static = new Lettering($db);
$nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id));
if ($nb_lettering < 0) {
$error++;
$errorforline++;
$errorforinvoice[$key] = 'other';
setEventMessages($lettering_static->error, $lettering_static->errors, 'errors');
}
}
}
}

View File

@ -60,6 +60,8 @@ if ($action == 'update') {
$amount = price2num(GETPOST('MEMBER_NEWFORM_AMOUNT'), 'MT', 2);
$minamount = GETPOST('MEMBER_MIN_AMOUNT');
$publiccounters = GETPOST('MEMBER_COUNTERS_ARE_PUBLIC');
$showtable = GETPOST('MEMBER_SHOW_TABLE');
$showvoteallowed = GETPOST('MEMBER_SHOW_VOTE_ALLOWED');
$payonline = GETPOST('MEMBER_NEWFORM_PAYONLINE');
$forcetype = GETPOST('MEMBER_NEWFORM_FORCETYPE', 'int');
$forcemorphy = GETPOST('MEMBER_NEWFORM_FORCEMORPHY', 'aZ09');
@ -68,6 +70,8 @@ if ($action == 'update') {
$res = dolibarr_set_const($db, "MEMBER_NEWFORM_AMOUNT", $amount, 'chaine', 0, '', $conf->entity);
$res = dolibarr_set_const($db, "MEMBER_MIN_AMOUNT", $minamount, 'chaine', 0, '', $conf->entity);
$res = dolibarr_set_const($db, "MEMBER_COUNTERS_ARE_PUBLIC", $publiccounters, 'chaine', 0, '', $conf->entity);
$res = dolibarr_set_const($db, "MEMBER_SKIP_TABLE", !$showtable, 'chaine', 0, '', $conf->entity); // Logic is reversed for retrocompatibility: "skip -> show"
$res = dolibarr_set_const($db, "MEMBER_HIDE_VOTE_ALLOWED", !$showvoteallowed, 'chaine', 0, '', $conf->entity); // Logic is reversed for retrocompatibility: "hide -> show"
$res = dolibarr_set_const($db, "MEMBER_NEWFORM_PAYONLINE", $payonline, 'chaine', 0, '', $conf->entity);
if ($forcetype < 0) {
$res = dolibarr_del_const($db, "MEMBER_NEWFORM_FORCETYPE", $conf->entity);
@ -246,6 +250,22 @@ if (!empty($conf->global->MEMBER_ENABLE_PUBLIC)) {
print $form->selectyesno("MEMBER_COUNTERS_ARE_PUBLIC", (!empty($conf->global->MEMBER_COUNTERS_ARE_PUBLIC) ? $conf->global->MEMBER_COUNTERS_ARE_PUBLIC : 0), 1);
print "</td></tr>\n";
// Show the table of all available membership types. If not, show a form (as the default was for Dolibarr <=16.0)
$skiptable = (!empty($conf->global->MEMBER_SKIP_TABLE) ? $conf->global->MEMBER_SKIP_TABLE : 0);
print '<tr class="oddeven" id="tredit"><td>';
print $langs->trans("MembersShowMembershipTypesTable");
print '</td><td>';
print $form->selectyesno("MEMBER_SHOW_TABLE", !$skiptable, 1); // Reverse the logic "hide -> show" for retrocompatibility
print "</td></tr>\n";
// Show "vote allowed" setting for membership types
$hidevoteallowed = (!empty($conf->global->MEMBER_HIDE_VOTE_ALLOWED) ? $conf->global->MEMBER_HIDE_VOTE_ALLOWED : 0);
print '<tr class="oddeven" id="tredit"><td>';
print $langs->trans("MembersShowVotesAllowed");
print '</td><td>';
print $form->selectyesno("MEMBER_SHOW_VOTE_ALLOWED", !$hidevoteallowed, 1); // Reverse the logic "hide -> show" for retrocompatibility
print "</td></tr>\n";
// Jump to an online payment page
print '<tr class="oddeven" id="trpayment"><td>';
print $langs->trans("MEMBER_NEWFORM_PAYONLINE");

View File

@ -61,20 +61,15 @@ abstract class ActionsAdherentCardCommon
*/
public function getObject($id)
{
//$ret = $this->getInstanceDao();
$object = new Adherent($this->db);
/*if (is_object($this->object) && method_exists($this->object,'fetch'))
{
if (!empty($id)) $this->object->fetch($id);
}
else
{*/
$object = new Adherent($this->db);
if (!empty($id)) {
$object->fetch($id);
}
$this->object = $object;
//}
$this->object = $object;
return $object;
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
@ -83,7 +78,7 @@ abstract class ActionsAdherentCardCommon
*
* @param string $action Type of action
* @param int $id Id
* @return string HTML output
* @return void
*/
public function assign_values(&$action, $id)
{

View File

@ -84,7 +84,6 @@ class ActionsAdherentCardDefault extends ActionsAdherentCardCommon
public function assign_values(&$action, $id)
{
// phpcs:enable
global $limit, $offset, $sortfield, $sortorder;
global $conf, $db, $langs, $user;
global $form;

View File

@ -441,7 +441,7 @@ class Adherent extends CommonObject
* @param string $errors_to erros to
* @param string $moreinheader Add more html headers
* @deprecated since V18
* @see sendEmail
* @see sendEmail()
* @return int <0 if KO, >0 if OK
*/
public function send_an_email($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = -1, $errors_to = '', $moreinheader = '')
@ -3303,11 +3303,11 @@ class Adherent extends CommonObject
*/
public function getKanbanView($option = '', $arraydata = null)
{
global $selected;
$return = '<div class="box-flex-item box-flex-grow-zero">';
$return .= '<div class="info-box info-box-sm">';
$return .= '<span class="info-box-icon bg-infobox-action">';
if (property_exists($this, 'photo') || !empty($this->photo)) {
$return.= Form::showphoto('memberphoto', $this, 0, 60, 0, 'photokanban photoref photowithmargin photologintooltip', 'small', 0, 1);
} else {
@ -3316,6 +3316,7 @@ class Adherent extends CommonObject
$return .= '</span>';
$return .= '<div class="info-box-content">';
$return .= '<span class="info-box-ref">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
$return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
if (property_exists($this, 'type')) {
$return .= '<br><span class="info-box-label opacitymedium">'.$this->type.'</span>';
}

View File

@ -991,7 +991,10 @@ class AdherentType extends CommonObject
*/
public function getKanbanView($option = '', $arraydata = null)
{
global $langs,$user;
global $langs, $user;
$selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
$return = '<div class="box-flex-item box-flex-grow-zero">';
$return .= '<div class="info-box info-box-sm">';
$return .= '<span class="info-box-icon bg-infobox-action">';
@ -999,6 +1002,7 @@ class AdherentType extends CommonObject
$return .= '</span>';
$return .= '<div class="info-box-content">';
$return .= '<span class="info-box-ref">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
$return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
if ($user->rights->adherent->configurer) {
$return .= '<span class="right paddingleft"><a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=edit&rowid='.$this->ref.'">'.img_edit().'</a></span>';
} else {

View File

@ -515,6 +515,8 @@ class Subscription extends CommonObject
*/
public function getKanbanView($option = '', $arraydata = null)
{
$selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
$return = '<div class="box-flex-item box-flex-grow-zero">';
$return .= '<div class="info-box info-box-sm">';
$return .= '<span class="info-box-icon bg-infobox-action">';
@ -523,6 +525,7 @@ class Subscription extends CommonObject
$return .= '<div class="info-box-content">';
$return .= '<span class="info-box-ref">'.(property_exists($this, 'fk_adherent')? $this->fk_adherent: $this->ref ).'</span>';
$return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
if (property_exists($this, 'dateh') || property_exists($this, 'datef')) {
$return .= '<br><span class="info-box-status opacitymedium">'.dol_print_date($this->dateh, 'day').' - '.dol_print_date($this->datef, 'day').'</span>';
}

View File

@ -345,19 +345,19 @@ $sql .= " d.note_private, d.note_public, d.import_key,";
$sql .= " s.nom,";
$sql .= " ".$db->ifsql("d.societe IS NULL", "s.nom", "d.societe")." as companyname,";
$sql .= " t.libelle as type, t.subscription,";
$sql .= " state.code_departement as state_code, state.nom as state_name,";
$sql .= " state.code_departement as state_code, state.nom as state_name";
// Add fields from extrafields
if (!empty($extrafields->attributes[$object->table_element]['label'])) {
foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
$sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key." as options_".$key.', ' : '');
$sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
}
}
// Add fields from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
$sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
$sql .= $hookmanager->resPrint;
$sql = preg_replace('/,\s*$/', '', $sql);
$sqlfields = $sql; // $sql fields to remove for count total

View File

@ -4,7 +4,7 @@
* Copyright (C) 2004-2018 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2012-2017 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2015-2016 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2018-2021 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2018-2023 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2019 Thibault FOUCART <support@ptibogxiv.net>
*
* This program is free software; you can redistribute it and/or modify
@ -946,6 +946,8 @@ if ($rowid > 0) {
print '<tr>';
// Date start subscription
$currentyear = dol_print_date(time(), "%Y");
$currentmonth = dol_print_date(time(), "%m");
print '<td class="fieldrequired">'.$langs->trans("DateSubscription").'</td><td>';
if (GETPOST('reday')) {
$datefrom = dol_mktime(0, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
@ -955,7 +957,7 @@ if ($rowid > 0) {
if ($object->datefin > 0 && dol_time_plus_duree($object->datefin, $defaultdelay, $defaultdelayunit) > dol_now()) {
$datefrom = dol_time_plus_duree($object->datefin, 1, 'd');
} else {
$datefrom = dol_get_first_day(dol_print_date(time(), "%Y"));
$datefrom = dol_get_first_day($currentyear);
}
}
print $form->selectDate($datefrom, '', '', '', '', "subscription", 1, 1);
@ -966,7 +968,13 @@ if ($rowid > 0) {
$dateto = dol_mktime(0, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear'));
}
if (!$dateto) {
$dateto = -1; // By default, no date is suggested
if (getDolGlobalInt('MEMBER_SUBSCRIPTION_SUGGEST_END_OF_MONTH')) {
$dateto = dol_get_last_day($currentyear, $currentmonth);
} elseif (getDolGlobalInt('MEMBER_SUBSCRIPTION_SUGGEST_END_OF_YEAR')) {
$dateto = dol_get_last_day($currentyear);
} else {
$dateto = -1; // By default, no date is suggested
}
}
print '<tr><td>'.$langs->trans("DateEndSubscription").'</td><td>';
print $form->selectDate($dateto, 'end', '', '', '', "subscription", 1, 0);

View File

@ -585,6 +585,9 @@ if ($rowid > 0) {
$sql .= " d.datefin,";
$sql .= " d.email, d.fk_adherent_type as type_id, d.morphy, d.statut as status,";
$sql .= " t.libelle as type, t.subscription, t.amount";
$sqlfields = $sql; // $sql fields to remove for count total
$sql .= " FROM ".MAIN_DB_PREFIX."adherent as d, ".MAIN_DB_PREFIX."adherent_type as t";
$sql .= " WHERE d.fk_adherent_type = t.rowid ";
$sql .= " AND d.entity IN (".getEntity('adherent').")";
@ -616,24 +619,32 @@ if ($rowid > 0) {
$sql .= " AND (datefin < '".$db->idate($now)."' AND t.subscription = 1)";
}
$sql .= " ".$db->order($sortfield, $sortorder);
// Count total nb of records
$nbtotalofrecords = '';
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
$resql = $db->query($sql);
/* 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) {
$nbtotalofrecords = $db->num_rows($result);
$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
if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0
$page = 0;
$offset = 0;
}
$db->free($resql);
}
$sql .= " ".$db->plimit($conf->liste_limit + 1, $offset);
// 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) {
@ -668,6 +679,15 @@ if ($rowid > 0) {
}
$param = "&rowid=".urlencode($object->id);
if (!empty($mode)) {
$param .= '&mode='.urlencode($mode);
}
if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
$param .= '&contextpage='.urlencode($contextpage);
}
if ($limit > 0 && $limit != $conf->liste_limit) {
$param .= '&limit='.((int) $limit);
}
if (!empty($status)) {
$param .= "&status=".urlencode($status);
}
@ -691,12 +711,11 @@ if ($rowid > 0) {
print $langs->trans("Filter")." (".$langs->trans("Lastname").", ".$langs->trans("Firstname").", ".$langs->trans("EMail").", ".$langs->trans("Address")." ".$langs->trans("or")." ".$langs->trans("Town")."): ".$sall;
}
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'" name="formfilter" autocomplete="off">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input class="flat" type="hidden" name="rowid" value="'.$object->id.'" size="12"></td>';
print '<input class="flat" type="hidden" name="rowid" value="'.$object->id.'"></td>';
print '<br>';
print_barre_liste('', $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords);
print_barre_liste('', $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'generic', 0, '', '', $limit);
$moreforfilter = '';
@ -706,24 +725,35 @@ if ($rowid > 0) {
// Fields title search
print '<tr class="liste_titre_filter">';
print '<td class="liste_titre left">';
print '<input class="flat" type="text" name="search_lastname" value="'.dol_escape_htmltag($search_lastname).'" size="12"></td>';
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
print '<td class="liste_titre center maxwidthsearch">';
$searchpicto = $form->showFilterButtons('left');
print $searchpicto;
print '</td>';
}
print '<td class="liste_titre left">';
print '<input class="flat" type="text" name="search_login" value="'.dol_escape_htmltag($search_login).'" size="7"></td>';
print '<input class="flat maxwidth100" type="text" name="search_lastname" value="'.dol_escape_htmltag($search_lastname).'"></td>';
print '<td class="liste_titre left">';
print '<input class="flat maxwidth100" type="text" name="search_login" value="'.dol_escape_htmltag($search_login).'"></td>';
print '<td class="liste_titre">&nbsp;</td>';
print '<td class="liste_titre left">';
print '<input class="flat" type="text" name="search_email" value="'.dol_escape_htmltag($search_email).'" size="12"></td>';
print '<input class="flat maxwidth100" type="text" name="search_email" value="'.dol_escape_htmltag($search_email).'"></td>';
print '<td class="liste_titre">&nbsp;</td>';
print '<td class="liste_titre right" colspan="2">';
print '<input type="image" class="liste_titre" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/search.png" name="button_search" value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">';
print '&nbsp; ';
print '<input type="image" class="liste_titre" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/searchclear.png" name="button_removefilter" value="'.dol_escape_htmltag($langs->trans("RemoveFilter")).'" title="'.dol_escape_htmltag($langs->trans("RemoveFilter")).'">';
print '</td>';
print '<td class="liste_titre">&nbsp;</td>';
if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
print '<td class="liste_titre center nowraponall">';
print '<input type="image" class="liste_titre" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/search.png" name="button_search" value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">';
print '&nbsp; ';
print '<input type="image" class="liste_titre" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/searchclear.png" name="button_removefilter" value="'.dol_escape_htmltag($langs->trans("RemoveFilter")).'" title="'.dol_escape_htmltag($langs->trans("RemoveFilter")).'">';
print '</td>';
}
print "</tr>\n";

View File

@ -599,6 +599,7 @@ foreach ($tabcomplete as $key => $value) {
$tabcomplete[$key]['sql'] = $tabsql[$i];
$tabcomplete[$key]['sqlsort'] = $tabsqlsort[$i];
$tabcomplete[$key]['field'] = $tabfield[$i];
//$tabcomplete[$key]['help'] = $tabhelp[$i]; // array help already loaded into tabcomplete
}
$keytable = '';
@ -616,7 +617,6 @@ if (empty($sortfield)) {
//var_dump($sortfield);var_dump($sortorder);
}
// Define elementList and sourceList (used for dictionary type of contacts "llx_c_type_contact")
$elementList = array();
$sourceList = array();
@ -1223,7 +1223,6 @@ if ($action == 'delete') {
print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'rowid='.urlencode($rowid).'&code='.urlencode($code).$paramwithsearch, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1);
}
/*
* Show a dictionary
*/

View File

@ -35,8 +35,6 @@ include_once DOL_DOCUMENT_ROOT.'/emailcollector/class/emailcollectorfilter.class
include_once DOL_DOCUMENT_ROOT.'/emailcollector/class/emailcollectoraction.class.php';
include_once DOL_DOCUMENT_ROOT.'/emailcollector/lib/emailcollector.lib.php';
// use Webklex\PHPIMAP;
require DOL_DOCUMENT_ROOT.'/includes/webklex/php-imap/vendor/autoload.php';
use Webklex\PHPIMAP\ClientManager;
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
use Webklex\PHPIMAP\Exceptions\InvalidWhereQueryCriteriaException;
@ -403,6 +401,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
if ($action == 'scan') {
if (!empty($conf->global->MAIN_IMAP_USE_PHPIMAP)) {
require_once DOL_DOCUMENT_ROOT.'/includes/webklex/php-imap/vendor/autoload.php';
if ($object->acces_type == 1) {
// Mode OAUth2 with PHP-IMAP
require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // define $supportedoauth2array
@ -448,8 +448,13 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
// We have to save the token because Google give it only once
$refreshtoken = $tokenobj->getRefreshToken();
//var_dump($tokenobj);
$tokenobj = $apiService->refreshAccessToken($tokenobj);
try {
$tokenobj = $apiService->refreshAccessToken($tokenobj);
} catch (Exception $e) {
throw new Exception("Failed to refresh access token: ".$e->getMessage());
}
$tokenobj->setRefreshToken($refreshtoken);
$storage->storeAccessToken($OAUTH_SERVICENAME, $tokenobj);
@ -496,6 +501,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
'authentication' => "login",
]);
}
if (!$error) {
try {
// To emulate the command connect, you can run
@ -569,7 +575,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
}
}
$morehtml = $form->textwithpicto($langs->trans("NbOfEmailsInInbox"), 'connect string '.$connectstringserver).': '.($morehtml ? $morehtml : '?');
$morehtml = $form->textwithpicto($langs->trans("NbOfEmailsInInbox"), 'Connect string = '.$connectstringserver.'<br>Option MAIN_IMAP_USE_PHPIMAP = '.getDolGlobalInt('MAIN_IMAP_USE_PHPIMAP')).': '.($morehtml ? $morehtml : '?');
$morehtml .= '<a class="flat paddingleft marginleftonly" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=scan&token='.newToken().'">'.img_picto('', 'refresh', 'class="paddingrightonly"').$langs->trans("Refresh").'</a>';
dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref.'<div class="refidno">'.$morehtml.'</div>', '', 0, '', '', 0, '');

View File

@ -224,7 +224,7 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) {
// Add fields from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
$sql .= $hookmanager->resPrint;
$sql = preg_replace('/,\s*$/', '', $sql);
$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {

View File

@ -629,7 +629,7 @@ if (!empty($conf->global->INVOICE_USE_DEFAULT_DOCUMENT)) { // Hidden conf
Facture::TYPE_CREDIT_NOTE=>$langs->trans("InvoiceAvoir"),
Facture::TYPE_DEPOSIT=>$langs->trans("InvoiceDeposit"),
);
if (!empty($conf->global->INVOICE_USE_SITUATION)) {
if (getDolGlobalInt('INVOICE_USE_SITUATION')) {
$listtype[Facture::TYPE_SITUATION] = $langs->trans("InvoiceSituation");
}

View File

@ -163,6 +163,9 @@ $textoshow = str_replace('{s1}', '<a href="'.$url2.'" target="_blank" rel="noope
print $textoshow;
if ($geoip) {
print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<br><br>';
print '<br><span class="opacitymedium">'.$langs->trans("TestGeoIPResult", $ip).':</span>';
@ -214,6 +217,20 @@ if ($geoip) {
}
}
$ip = GETPOST("iptotest");
print '<br><input type="text class="width100" name="iptotest" id="iptotest" placeholder="'.dol_escape_htmltag($langs->trans("EnterAnIP")).'" value="'.$ip.'">';
print '<input type="submit" class="width40 button small smallpaddingimp" value=" -> ">';
if ($ip) {
$result = dol_print_ip($ip, 1);
if ($result) {
print $result;
} else {
print $langs->trans("Error");
}
}
print '</form>';
$geoip->close();
}

View File

@ -226,19 +226,17 @@ print "<br>\n";
// Build and execute select
// --------------------------------------------------------------------
$sql = 'SELECT ';
foreach ($object->fields as $key => $val) {
$sql .= "t.".$key.", ";
}
$sql .= $object->getFieldList('t');
// Add fields from extrafields
if (!empty($extrafields->attributes[$object->table_element]['label'])) {
foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) {
$sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key." as options_".$key.', ' : '');
$sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? ", ef.".$key." as options_".$key : '');
}
}
// Add fields from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
$sql .= $hookmanager->resPrint;
$sql = preg_replace('/,\s*$/', '', $sql);
$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
if (!empty($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {

View File

@ -974,7 +974,7 @@ if ($mode == 'common' || $mode == 'commonkanban') {
}
// Picto + Name of module
print ' <td class="tdoverflowmax300" title="'.dol_escape_htmltag($objMod->getName()).'">';
print ' <td class="tdoverflowmax300 maxwidth300" title="'.dol_escape_htmltag($objMod->getName()).'">';
$alttext = '';
//if (is_array($objMod->need_dolibarr_version)) $alttext.=($alttext?' - ':'').'Dolibarr >= '.join('.',$objMod->need_dolibarr_version);
//if (is_array($objMod->phpmin)) $alttext.=($alttext?' - ':'').'PHP >= '.join('.',$objMod->phpmin);
@ -1181,7 +1181,11 @@ if ($mode == 'deploy') {
} else {
if (getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
// Show clean message
$message = info_admin($langs->trans('InstallModuleFromWebHasBeenDisabledContactUs'));
if (!is_numeric('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')) {
$message = info_admin($langs->trans(getDolGlobalString('MAIN_MESSAGE_INSTALL_MODULES_DISABLED_CONTACT_US')));
} else {
$message = info_admin($langs->trans('InstallModuleFromWebHasBeenDisabledContactUs'));
}
} else {
// Show technical message
$message = info_admin($langs->trans("InstallModuleFromWebHasBeenDisabledByFile", $dolibarrdataroot.'/installmodules.lock'));

View File

@ -356,8 +356,8 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
dol_print_error($db);
}
print "<table class=\"noborder\" width=\"100%\">\n";
print "<tr class=\"liste_titre\">\n";
print '<table class="noborder centpercent">'."\n";
print '<tr class="liste_titre">'."\n";
print '<td>'.$langs->trans("Name").'</td>';
print '<td>'.$langs->trans("Description").'</td>';
print '<td class="center" width="60">'.$langs->trans("Status")."</td>\n";
@ -396,7 +396,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) {
if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified = 0;
if ($modulequalified) {
print '<tr class="oddeven"><td width="100">';
print '<tr class="oddeven"><td>';
print (empty($module->name) ? $name : $module->name);
print "</td><td>\n";
if (method_exists($module, 'info')) print $module->info($langs);

View File

@ -38,9 +38,11 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
// Load translation files required by the page
$langs->loadLangs(array("admin", "other", "orders"));
$action = GETPOST('action', 'aZ09');
$type = GETPOST('type', 'alpha');
$value = GETPOST('value', 'alpha');
$action = GETPOST('action', 'aZ09');
$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php
$label = GETPOST('label', 'alpha');
$scandir = GETPOST('scan_dir', 'alpha');
@ -98,7 +100,9 @@ if ($action == 'specimen') { // For invoices
$facture->thirdparty = $specimenthirdparty; // Define who should has build the invoice (so the supplier)
// Search template files
$file = ''; $classname = ''; $filefound = 0;
$file = '';
$classname = '';
$filefound = 0;
$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
foreach ($dirmodels as $reldir) {
$file = dol_buildpath($reldir."core/modules/supplier_invoice/doc/pdf_".$modele.".modules.php", 0);
@ -185,12 +189,12 @@ if ($action == 'set_SUPPLIER_INVOICE_FREE_TEXT') {
* View
*/
$form = new Form($db);
$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
llxHeader("", "");
$form = new Form($db);
$linkback = '<a href="'.DOL_URL_ROOT.'/admin/modules.php?restore_lastsearch_values=1">'.$langs->trans("BackToModuleList").'</a>';
print load_fiche_titre($langs->trans("SuppliersSetup"), $linkback, 'title_setup');
@ -205,6 +209,7 @@ print dol_get_fiche_head($head, 'invoice', $langs->trans("Suppliers"), -1, 'comp
print load_fiche_titre($langs->trans("SuppliersInvoiceNumberingModel"), '', '');
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td width="100">'.$langs->trans("Name").'</td>';
@ -244,7 +249,7 @@ foreach ($dirmodels as $reldir) {
print $module->info();
print '</td>';
// Show example of numbering model
// Show example of numbering module
print '<td class="nowrap">';
$tmp = $module->getExample();
if (preg_match('/^Error/', $tmp)) {
@ -297,13 +302,13 @@ foreach ($dirmodels as $reldir) {
}
}
print '</table><br>';
print '</table></div><br>';
/*
* Modeles documents for supplier invoices
* Documents models for supplier invoices
*/
print load_fiche_titre($langs->trans("BillsPDFModules"), '', '');
@ -329,6 +334,7 @@ if ($resql) {
dol_print_error($db);
}
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">'."\n";
print '<tr class="liste_titre">'."\n";
print '<td width="100">'.$langs->trans("Name").'</td>'."\n";
@ -380,7 +386,7 @@ foreach ($dirmodels as $reldir) {
//if ($conf->global->INVOICE_SUPPLIER_ADDON_PDF != "$name")
//{
// Even if choice is the default value, we allow to disable it: For supplier invoice, we accept to have no doc generation at all
print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'&amp;type=invoice_supplier">';
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=del&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'&amp;type=invoice_supplier">';
print img_picto($langs->trans("Enabled"), 'switch_on');
print '</a>';
/*}
@ -391,7 +397,7 @@ foreach ($dirmodels as $reldir) {
print "</td>";
} else {
print '<td class="center">'."\n";
print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'&amp;type=invoice_supplier">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=set&token='.newToken().'&value='.urlencode($name).'&scan_dir='.urlencode($module->scandir).'&label='.urlencode($module->name).'&amp;type=invoice_supplier">'.img_picto($langs->trans("Disabled"), 'switch_off').'</a>';
print "</td>";
}
@ -400,9 +406,9 @@ foreach ($dirmodels as $reldir) {
if (getDolGlobalString("INVOICE_SUPPLIER_ADDON_PDF") == "$name") {
//print img_picto($langs->trans("Default"),'on');
// Even if choice is the default value, we allow to disable it: For supplier invoice, we accept to have no doc generation at all
print '<a href="'.$_SERVER["PHP_SELF"].'?action=unsetdoc&token='.newToken().'&value='.$name.'&scan_dir='.$module->scandir.'&label='.urlencode($module->name).'&type=invoice_supplier"" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').'</a>';
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=unsetdoc&token='.newToken().'&value='.$name.'&scan_dir='.$module->scandir.'&label='.urlencode($module->name).'&type=invoice_supplier"" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').'</a>';
} else {
print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&token='.newToken().'&value='.$name.'&scan_dir='.$module->scandir.'&label='.urlencode($module->name).'&type=invoice_supplier"" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=setdoc&token='.newToken().'&value='.$name.'&scan_dir='.$module->scandir.'&label='.urlencode($module->name).'&type=invoice_supplier"" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
}
print '</td>';
@ -420,7 +426,7 @@ foreach ($dirmodels as $reldir) {
print $form->textwithpicto('', $htmltooltip, 1, 0);
print '</td>';
print '<td class="center">';
print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&amp;module='.$name.'">'.img_object($langs->trans("Preview"), 'pdf').'</a>';
print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.urlencode($name).'">'.img_object($langs->trans("Preview"), 'pdf').'</a>';
print '</td>';
print "</tr>\n";
@ -432,7 +438,7 @@ foreach ($dirmodels as $reldir) {
}
}
print '</table><br>';
print '</table></div><br>';
/*
* Other options
@ -443,6 +449,8 @@ print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="set_SUPPLIER_INVOICE_FREE_TEXT">';
print load_fiche_titre($langs->trans("OtherOptions"), '', '');
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Parameter").'</td>';
@ -472,7 +480,7 @@ print '</td><td class="right">';
print '<input type="submit" class="button button-edit" value="'.$langs->trans("Modify").'">';
print "</td></tr>\n";
print '</table><br>';
print '</table></div><br>';
print '</form>';
@ -482,6 +490,8 @@ print '</form>';
*/
print load_fiche_titre($langs->trans("Notifications"), '', '');
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Parameter").'</td>';
@ -495,6 +505,7 @@ print '</td><td class="right">';
print "</td></tr>\n";
print '</table>';
print '</div>';
// End of page
llxFooter();

View File

@ -38,25 +38,28 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
// Load translation files required by the page
$langs->loadLangs(array("admin", "other", "orders", "stocks"));
if (!$user->admin) {
accessforbidden();
}
$action = GETPOST('action', 'aZ09');
$type = GETPOST('type', 'alpha');
$value = GETPOST('value', 'alpha');
$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php
$label = GETPOST('label', 'alpha');
$action = GETPOST('action', 'aZ09');
$scandir = GETPOST('scan_dir', 'alpha');
$specimenthirdparty = new Societe($db);
$specimenthirdparty->initAsSpecimen();
$error = 0;
if (!$user->admin) {
accessforbidden();
}
/*
* Actions
*/
* Actions
*/
include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
@ -77,7 +80,9 @@ if ($action == 'updateMask') {
} else {
setEventMessages($langs->trans("Error"), null, 'errors');
}
} elseif ($action == 'specimen') { // For orders
}
if ($action == 'specimen') { // For orders
$modele = GETPOST('module', 'alpha');
$commande = new CommandeFournisseur($db);
@ -317,8 +322,8 @@ print '</table></div><br>';
/*
* Documents models for supplier orders
*/
* Documents models for supplier orders
*/
print load_fiche_titre($langs->trans("OrdersModelModule"), '', '');

View File

@ -109,12 +109,18 @@ if (!$base) {
$arrayoffilesrich = dol_dir_list(DOL_DOCUMENT_ROOT.'/install/mysql/tables/', 'files', 0, '\.sql$');
$arrayoffiles = array();
$arrayoftablesautocreated = array();
foreach ($arrayoffilesrich as $value) {
//print $shortsqlfilename.' ';
$shortsqlfilename = preg_replace('/\-[a-z]+\./', '.', $value['name']);
$arrayoffiles[] = $shortsqlfilename;
$arrayoffiles[$value['name']] = $shortsqlfilename;
if ($value['name'] == $shortsqlfilename && ! preg_match('/\.key\.sql$/', $value['name'])) {
// This is a sql file automatically created
$arrayoftablesautocreated[$value['name']] = $shortsqlfilename;
}
}
// Now loop on tables really found into database
$sql = "SHOW TABLE STATUS";
$resql = $db->query($sql);
@ -123,6 +129,7 @@ if (!$base) {
$i = 0;
while ($i < $num) {
$obj = $db->fetch_object($resql);
print '<tr class="oddeven">';
print '<td>'.($i+1).'</td>';
@ -130,11 +137,14 @@ if (!$base) {
$tablename = preg_replace('/^'.MAIN_DB_PREFIX.'/', 'llx_', $obj->Name);
if (in_array($tablename.'.sql', $arrayoffiles)) {
$img = "info";
//print img_picto($langs->trans("ExternalModule"), $img);
if (in_array($tablename.'.sql', $arrayoftablesautocreated)) {
$img = "info";
} else {
$img = "info_black";
print img_picto($langs->trans("NotAvailableByDefaultEnabledOnModuleActivation"), $img, 'class="small opacitymedium"');
}
} else {
$img = "info_black";
//print DOL_DOCUMENT_ROOT.'/install/mysql/tables/'.$tablename.'.sql';
print img_picto($langs->trans("ExternalModule"), $img, 'class="small"');
}
print '</td>';

View File

@ -252,6 +252,7 @@ foreach ($phparray as $key => $value) {
if (!is_array($keyvalue)) {
$keytoshow = $keyparam;
$valtoshow = $keyvalue;
// Hide value of session cookies
if (in_array($keyparam, array('HTTP_COOKIE', 'Cookie', "\$_SERVER['HTTP_COOKIE']", 'Authorization'))) {
$valtoshow = '<span class="opacitymedium">'.$langs->trans("Hidden").'</span>';
@ -260,6 +261,10 @@ foreach ($phparray as $key => $value) {
$keytoshow = $keyparam;
$valtoshow = '<span class="opacitymedium">'.$langs->trans("Hidden").'</span>';
}
if (preg_match('/'.preg_quote('$_SERVER[\'PHP_AUTH_PW', '/').'/i', $keyparam)) {
$keytoshow = $keyparam;
$valtoshow = '<span class="opacitymedium">'.$langs->trans("Hidden").'</span>';
}
print '<tr class="oddeven">';
print '<td>'.$keytoshow.'</td>';

View File

@ -241,14 +241,41 @@ print '<br>';
print '<br>';
$installlock = DOL_DATA_ROOT.'/install.lock';
$upgradeunlock = DOL_DATA_ROOT.'/upgrade.unlock';
$installmoduleslock = DOL_DATA_ROOT.'/installmodules.lock';
// Is install (upgrade) locked
print '<strong>'.$langs->trans("DolibarrSetup").'</strong>: ';
if (file_exists($installlock)) {
print img_picto('', 'tick').' '.$langs->trans("InstallAndUpgradeLockedBy", $installlock);
if (file_exists($upgradeunlock)) {
print img_picto('', 'tick').' '.$langs->trans("InstallLockedBy", $installlock);
} else {
print img_picto('', 'tick').' '.$langs->trans("InstallAndUpgradeLockedBy", $installlock);
}
} else {
print img_warning().' '.$langs->trans("WarningLockFileDoesNotExists", DOL_DATA_ROOT);
}
print '<br>';
// Is upgrade unlocked
if (file_exists($installlock)) { // If install not locked, no need to show this.
if (file_exists($upgradeunlock)) {
print '<strong>'.$langs->trans("DolibarrUpgrade").'</strong>: ';
print img_warning().' '.$langs->trans("UpgradeHasBeenUnlocked", $upgradeunlock);
print '<br>';
}
}
// Is addon install locked ?
print '<strong>'.$langs->trans("DolibarrAddonInstall").'</strong>: ';
if (file_exists($installmoduleslock)) {
print img_picto('', 'tick').' '.$langs->trans("InstallAndUpgradeLockedBy", $installmoduleslock);
} else {
print $langs->trans("InstallOfAddonIsNotBlocked", DOL_DATA_ROOT);
}
print '<br>';
// File conf.php
@ -286,7 +313,7 @@ if (empty($dolibarr_main_restrict_os_commands)) {
} else {
print $dolibarr_main_restrict_os_commands;
}
print ' <span class="opacitymedium">('.$langs->trans("RecommendedValueIs", 'mysqldump, mysql, pg_dump, pgrestore').')</span>';
print ' <span class="opacitymedium">('.$langs->trans("RecommendedValueIs", 'mysqldump, mysql, pg_dump, pgrestore, clamdscan').')</span>';
print '<br>';
if (empty($conf->global->SECURITY_DISABLE_TEST_ON_OBFUSCATED_CONF)) {
@ -581,11 +608,11 @@ print '<strong>MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED</strong> =
print '<br>';
$examplecsprule = "frame-ancestors 'self'; img-src * data:; font-src *; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com;";
print '<strong>MAIN_SECURITY_FORCECSPRO</strong> = '.getDolGlobalString('MAIN_SECURITY_FORCECSP', '<span class="opacitymedium">'.$langs->trans("Undefined").'</span>').' &nbsp; <span class="opacitymedium">('.$langs->trans("Example").': "'.$examplecsprule.'")</span><br>';
print '<strong>MAIN_SECURITY_FORCECSPRO</strong> = '.getDolGlobalString('MAIN_SECURITY_FORCECSPRO', '<span class="opacitymedium">'.$langs->trans("Undefined").'</span>').' &nbsp; <span class="opacitymedium">('.$langs->trans("Example").': "'.$examplecsprule.'")</span><br>';
print '<br>';
$examplecsprule = "frame-ancestors 'self'; img-src * data:; font-src *; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com;";
print '<strong>MAIN_SECURITY_FORCECSP</strong> = '.getDolGlobalString('MAIN_SECURITY_FORCERP', '<span class="opacitymedium">'.$langs->trans("Undefined").'</span>').' &nbsp; <span class="opacitymedium">('.$langs->trans("Example").': "'.$examplecsprule.'")</span><br>';
print '<strong>MAIN_SECURITY_FORCECSP</strong> = '.getDolGlobalString('MAIN_SECURITY_FORCECSP', '<span class="opacitymedium">'.$langs->trans("Undefined").'</span>').' &nbsp; <span class="opacitymedium">('.$langs->trans("Example").': "'.$examplecsprule.'")</span><br>';
print '<br>';
print '<strong>MAIN_SECURITY_FORCERP</strong> = '.getDolGlobalString('MAIN_SECURITY_FORCERP', '<span class="opacitymedium">'.$langs->trans("Undefined").'</span>').' &nbsp; <span class="opacitymedium">('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or")." \"same-origin\" so browser doesn't send any referrer when going into another web site domain)</span><br>";

View File

@ -330,7 +330,7 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) {
print '</tr>';
// Auto fill the contact found from email
// This option is a serious security hole. it allowe to any non looged perso, to get the database of contacts
// This option is a serious security hole. it allows to any non logged perso, to get the database of contacts or to check if an email is a customer or not. We must keep it as hidden option only.
/*
print '<tr class="oddeven"><td>'.$langs->trans("TicketCreateThirdPartyWithContactIfNotExist").'</td>';
print '<td class="left">';

View File

@ -106,6 +106,9 @@ class DolibarrApiAccess implements iAuthenticate
if (isset($_SERVER['HTTP_DOLAPIKEY'])) { // Param DOLAPIKEY in header can be read with HTTP_DOLAPIKEY
$api_key = $_SERVER['HTTP_DOLAPIKEY']; // With header method (recommanded)
}
if (preg_match('/^dolcrypt:/i', $api_key)) {
throw new RestException(503, 'Bad value for the API key. An API key should not start with dolcrypt:');
}
if ($api_key) {
$userentity = 0;
@ -113,15 +116,15 @@ class DolibarrApiAccess implements iAuthenticate
$sql = "SELECT u.login, u.datec, u.api_key, ";
$sql .= " u.tms as date_modification, u.entity";
$sql .= " FROM ".MAIN_DB_PREFIX."user as u";
$sql .= " WHERE u.api_key = '".$this->db->escape($api_key)."'";
// TODO Check if 2 users has same API key.
$sql .= " WHERE u.api_key = '".$this->db->escape($api_key)."' OR u.api_key = '".$this->db->escape(dolEncrypt($api_key, '', '', 'dolibarr'))."'";
$result = $this->db->query($sql);
if ($result) {
if ($this->db->num_rows($result)) {
$nbrows = $this->db->num_rows($result);
if ($nbrows == 1) {
$obj = $this->db->fetch_object($result);
$login = $obj->login;
$stored_key = $obj->api_key;
$stored_key = dolDecrypt($obj->api_key);
$userentity = $obj->entity;
if (!defined("DOLENTITY") && $conf->entity != ($obj->entity ? $obj->entity : 1)) { // If API was not forced with HTTP_DOLENTITY, and user is on another entity, so we reset entity to entity of user
@ -130,6 +133,8 @@ class DolibarrApiAccess implements iAuthenticate
dol_syslog("Entity was not set on http header with HTTP_DOLAPIENTITY (recommanded for performance purpose), so we switch now on entity of user (".$conf->entity.") and we have to reload configuration.", LOG_WARNING);
$conf->setValues($this->db);
}
} elseif ($nbrows > 1) {
throw new RestException(503, 'Error when fetching user api_key : More than 1 user with this apikey');
}
} else {
throw new RestException(503, 'Error when fetching user api_key :'.$this->db->error_msg);

View File

@ -607,6 +607,7 @@ class Documents extends DolibarrApi
if ($ref) {
$tmpreldir = '';
$fetchbyid = false;
if ($modulepart == 'facture' || $modulepart == 'invoice') {
$modulepart = 'facture';
@ -666,13 +667,22 @@ class Documents extends DolibarrApi
$modulepart = 'propale';
require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
$object = new Propal($this->db);
} elseif ($modulepart == 'contact' || $modulepart == 'socpeople') {
$modulepart = 'contact';
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
$object = new Contact($this->db);
$fetchbyid = true;
} else {
// TODO Implement additional moduleparts
throw new RestException(500, 'Modulepart '.$modulepart.' not implemented yet.');
}
if (is_object($object)) {
$result = $object->fetch('', $ref);
if ($fetchbyid) {
$result = $object->fetch($ref);
} else {
$result = $object->fetch('', $ref);
}
if ($result == 0) {
throw new RestException(404, "Object with ref '".$ref."' was not found.");

View File

@ -18,6 +18,7 @@
use Luracast\Restler\RestException;
require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
/**
@ -152,7 +153,7 @@ class Login
// We store API token into database
$sql = "UPDATE ".MAIN_DB_PREFIX."user";
$sql .= " SET api_key = '".$this->db->escape($token)."'";
$sql .= " SET api_key = '".$this->db->escape(dolEncrypt($token, '', '', 'dolibarr'))."'";
$sql .= " WHERE login = '".$this->db->escape($login)."'";
dol_syslog(get_class($this)."::login", LOG_DEBUG); // No log

View File

@ -116,11 +116,6 @@ class AssetAccountancyCodes extends CommonObject
$asset_id = $asset_id > 0 ? $asset_id : 0;
$asset_model_id = $asset_model_id > 0 ? $asset_model_id : 0;
if (!is_object($hookmanager)) {
require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
$hookmanager = new HookManager($this->db);
}
$hookmanager->initHooks(array('assetaccountancycodesdao'));
$parameters = array('asset_id' => $asset_id, 'asset_model_id' => $asset_model_id);
$reshook = $hookmanager->executeHooks('fetchAccountancyCodes', $parameters, $this); // Note that $action and $object may have been modified by some hooks
@ -188,11 +183,6 @@ class AssetAccountancyCodes extends CommonObject
$asset_id = $asset_id > 0 ? $asset_id : 0;
$asset_model_id = $asset_model_id > 0 ? $asset_model_id : 0;
if (!is_object($hookmanager)) {
require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
$hookmanager = new HookManager($this->db);
}
$hookmanager->initHooks(array('assetaccountancycodesdao'));
$parameters = array('user' => $user, 'asset_id' => $asset_id, 'asset_model_id' => $asset_model_id);
$reshook = $hookmanager->executeHooks('updateAccountancyCodes', $parameters, $this); // Note that $action and $object may have been modified by some hooks

View File

@ -319,11 +319,6 @@ class AssetDepreciationOptions extends CommonObject
$asset_id = $asset_id > 0 ? $asset_id : 0;
$asset_model_id = $asset_model_id > 0 ? $asset_model_id : 0;
if (!is_object($hookmanager)) {
require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
$hookmanager = new HookManager($this->db);
}
$hookmanager->initHooks(array('assetdepreciationoptionsdao'));
$parameters = array('asset_id' => $asset_id, 'asset_model_id' => $asset_model_id);
$reshook = $hookmanager->executeHooks('fetchDepreciationOptions', $parameters, $this); // Note that $action and $object may have been modified by some hooks
@ -392,11 +387,6 @@ class AssetDepreciationOptions extends CommonObject
// Clean parameters
$mode = strtolower(trim($mode));
if (!is_object($hookmanager)) {
require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
$hookmanager = new HookManager($this->db);
}
$hookmanager->initHooks(array('assetdepreciationoptionsdao'));
$parameters = array('mode' => $mode);
$reshook = $hookmanager->executeHooks('getGeneralDepreciationInfoForMode', $parameters, $this); // Note that $action and $object may have been modified by some hooks
@ -437,11 +427,6 @@ class AssetDepreciationOptions extends CommonObject
$asset_id = $asset_id > 0 ? $asset_id : 0;
$asset_model_id = $asset_model_id > 0 ? $asset_model_id : 0;
if (!is_object($hookmanager)) {
require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
$hookmanager = new HookManager($this->db);
}
$hookmanager->initHooks(array('assetdepreciationoptionsdao'));
$parameters = array('user' => $user, 'asset_id' => $asset_id, 'asset_model_id' => $asset_model_id);
$reshook = $hookmanager->executeHooks('updateDepreciationOptions', $parameters, $this); // Note that $action and $object may have been modified by some hooks

View File

@ -214,7 +214,7 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) {
// Add fields from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
$sql .= $hookmanager->resPrint;
$sql = preg_replace('/,\s*$/', '', $sql);
$sqlfields = $sql; // $sql fields to remove for count total
@ -639,7 +639,7 @@ if ($num == 0) {
$colspan++;
}
}
print '<tr><td colspan="'.$colspan.'" class="opacitymedium">'.$langs->trans("NoRecordFound").'</td></tr>';
print '<tr><td colspan="'.$colspan.'"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
}

View File

@ -219,7 +219,7 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) {
// Add fields from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
$sql .= $hookmanager->resPrint;
$sql = preg_replace('/,\s*$/', '', $sql);
$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";
if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {

View File

@ -20,6 +20,11 @@
*/
class BlockedLogAuthority
{
/**
* DoliDB
* @var DoliDB
*/
public $db;
/**
* Id of the log
@ -45,6 +50,12 @@ class BlockedLogAuthority
*/
public $tms = 0;
/**
* Error message
* @var string
*/
public $error;
/**
* Constructor
*

View File

@ -306,7 +306,7 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) {
// Add fields from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
$sql .= $hookmanager->resPrint;
$sql = preg_replace('/,\s*$/', '', $sql);
$sqlfields = $sql; // $sql fields to remove for count total

View File

@ -1567,6 +1567,9 @@ class BOM extends CommonObject
public function getKanbanView($option = '', $arraydata = null)
{
global $db,$langs;
$selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
$prod = new Product($db);
$prod->fetch($this->fk_product);
@ -1577,6 +1580,7 @@ class BOM extends CommonObject
$return .= '</span>';
$return .= '<div class="info-box-content">';
$return .= '<span class="info-box-ref">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : '').'</span>';
$return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
if (property_exists($this, 'fields') && !empty($this->fields['bomtype']['arrayofkeyval'])) {
$return .= '<br><span class="info-box-label opacitymedium">'.$langs->trans("Type").' : </span>';
if ($this->bomtype == 0) {

View File

@ -114,17 +114,18 @@ if (isModEnabled("product") || isModEnabled("service")) {
$statustoshow = -1;
if (!empty($conf->global->ENTREPOT_EXTRA_STATUS)) {
// hide products in closed warehouse, but show products for internal transfer
$form->select_produits(GETPOST('idprod', 'int'), (($filtertype == 1) ? 'idprodservice' : 'idprod'), $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, 'warehouseopen,warehouseinternal', GETPOST('combinations', 'array'));
print $form->select_produits(GETPOST('idprod', 'int'), (($filtertype == 1) ? 'idprodservice' : 'idprod'), $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, 'warehouseopen,warehouseinternal', GETPOST('combinations', 'array'), 1);
} else {
$form->select_produits(GETPOST('idprod', 'int'), (($filtertype == 1) ? 'idprodservice' : 'idprod'), $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, '', GETPOST('combinations', 'array'));
print $form->select_produits(GETPOST('idprod', 'int'), (($filtertype == 1) ? 'idprodservice' : 'idprod'), $filtertype, $conf->product->limit_size, $buyer->price_level, $statustoshow, 2, '', 1, array(), $buyer->id, '1', 0, 'maxwidth500', 0, '', GETPOST('combinations', 'array'), 1);
}
$urltocreateproduct = DOL_URL_ROOT.'/product/card.php?action=create&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id);
print '<a href="'.$urltocreateproduct.'"><span class="fa fa-plus-circle valignmiddle paddingleft" title="'.$langs->trans("AddProduct").'"></span></a>';
echo '</span>';
}
if (!empty($conf->global->BOM_SUB_BOM) && $filtertype!=1) {
print '<br><span class="opacitymedium">'.$langs->trans("or").'</span><br>'.$langs->trans("BOM");
// TODO Add component to select a BOM
$form->select_bom();
print $form->select_bom('', 'bom_id', 0, 1, 0, '1', '', 1);
}
if (is_object($objectline)) {

View File

@ -227,7 +227,7 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) {
// Add fields from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
$sql .= $hookmanager->resPrint;
$sql = preg_replace('/,\s*$/', '', $sql);
//$sql .= ", COUNT(rc.rowid) as anotherfield";
$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";

View File

@ -227,7 +227,7 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) {
// Add fields from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
$sql .= $hookmanager->resPrint;
$sql = preg_replace('/,\s*$/', '', $sql);
//$sql .= ", COUNT(rc.rowid) as anotherfield";
$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t";

View File

@ -158,7 +158,7 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) {
// Add fields from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
$sql .= $hookmanager->resPrint;
$sql = preg_replace('/,\s*$/', '', $sql);
$sqlfields = $sql; // $sql fields to remove for count total

View File

@ -845,10 +845,12 @@ class Categorie extends CommonObject
* @param int $offset Offset
* @param string $sortfield Sort fields
* @param string $sortorder Sort order ('ASC' or 'DESC');
* @param array $filter Filter array. Example array('field'=>'valueforlike', 'customsql'=>...)
* @param string $filtermode Filter mode (AND or OR)
* @return array|int -1 if KO, array of instance of object if OK
* @see containsObject()
*/
public function getObjectsInCateg($type, $onlyids = 0, $limit = 0, $offset = 0, $sortfield = '', $sortorder = 'ASC')
public function getObjectsInCateg($type, $onlyids = 0, $limit = 0, $offset = 0, $sortfield = '', $sortorder = 'ASC', $filter = array(), $filtermode = 'AND')
{
global $user;
@ -867,10 +869,24 @@ class Categorie extends CommonObject
if (($type == 'customer' || $type == 'supplier') && $user->socid > 0) {
$sql .= " AND o.rowid = ".((int) $user->socid);
}
// Manage filter
$sqlwhere = array();
if (count($filter) > 0) {
foreach ($filter as $key => $value) {
if ($key == 'o.rowid') {
$sqlwhere[] = $key." = ".((int) $value);
} elseif ($key == 'customsql') {
$sqlwhere[] = $value;
}
}
}
if (count($sqlwhere) > 0) {
$sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")";
}
$sql .= $this->db->order($sortfield, $sortorder);
if ($limit > 0 || $offset > 0) {
$sql .= $this->db->plimit($limit + 1, $offset);
}
$sql .= $this->db->order($sortfield, $sortorder);
dol_syslog(get_class($this)."::getObjectsInCateg", LOG_DEBUG);
$resql = $this->db->query($sql);

View File

@ -176,7 +176,7 @@ if ($elemid && $action == 'addintocategory' &&
($type == Categorie::TYPE_SUPPLIER && $user->rights->societe->creer) ||
($type == Categorie::TYPE_TICKET && $user->rights->ticket->write) ||
($type == Categorie::TYPE_PROJECT && $user->rights->projet->creer) ||
($type == Categorie::TYPE_MEMBER && $user->rights->projet->creer) ||
($type == Categorie::TYPE_MEMBER && $user->hasRight('adherent', 'creer')) ||
($type == Categorie::TYPE_CONTACT && $user->rights->societe->creer) ||
($type == Categorie::TYPE_USER && $user->rights->user->user->creer) ||
($type == Categorie::TYPE_ACCOUNT && $user->rights->banque->configurer)

View File

@ -155,9 +155,6 @@ if (!empty($conf->global->AGENDA_REMINDER_EMAIL)) {
$TDurationTypes = array('y'=>$langs->trans('Years'), 'm'=>$langs->trans('Month'), 'w'=>$langs->trans('Weeks'), 'd'=>$langs->trans('Days'), 'h'=>$langs->trans('Hours'), 'i'=>$langs->trans('Minutes'));
$result = restrictedArea($user, 'agenda', $object->id, 'actioncomm&societe', 'myactions|allactions', 'fk_soc', 'id');
if ($user->socid && $socid) {
$result = restrictedArea($user, 'societe', $socid);
}
$usercancreate = $user->hasRight('agenda', 'allactions', 'create') || (($object->authorid == $user->id || $object->userownerid == $user->id) && $user->rights->agenda->myactions->create);
@ -1469,7 +1466,7 @@ if ($action == 'create') {
print "\n".'<script type="text/javascript">';
print '$(document).ready(function () {
$("#projectid").change(function () {
var url = "'.DOL_URL_ROOT.'/projet/ajax/projects.php?mode=gettasks&socid="+$("#projectid").val()+"&projectid="+$("#projectid").val();
var url = "'.DOL_URL_ROOT.'/projet/ajax/projects.php?mode=gettasks&socid="+$("#search_socid").val()+"&projectid="+$("#projectid").val();
console.log("Call url to get new list of tasks: "+url);
$.get(url, function(data) {
console.log(data);
@ -2403,6 +2400,20 @@ if ($id > 0) {
print '</td></tr>';
}
//mail information
if (!empty($object->email_msgid)) {
print '<tr><td>'.$langs->trans('MailTopic').'</td>';
print '<td>'.dol_escape_htmltag($object->email_subject).'</td></tr>';
print '<tr><td>'.$langs->trans('MailFrom').'</td>';
print '<td>'.dol_escape_htmltag($object->email_from).'</td></tr>';
print '<tr><td>'.$langs->trans('MailTo').'</td>';
print '<td>'.dol_escape_htmltag($object->email_to).'</td></tr>';
if (!empty($object->email_tocc)) {
print '<tr><td>'.$langs->trans('MailCC').'</td>';
print '<td>'.dol_escape_htmltag($object->email_tocc).'</td></tr>';
}
}
// Description
print '<tr><td class="tdtop">'.$langs->trans("Description").'</td><td class="wordbreak">';
print dol_string_onlythesehtmltags(dol_htmlentitiesbr($object->note_private));

View File

@ -415,7 +415,7 @@ if ($usergroup > 0) {
}
$sql .= " s.nom as societe, s.rowid as socid, s.client, s.email as socemail,";
$sql .= " a.id, a.code, a.label, a.note, a.datep as dp, a.datep2 as dp2, a.fulldayevent, a.location,";
$sql .= ' a.fk_user_author,a.fk_user_action,';
$sql .= " a.fk_user_author, a.fk_user_action,";
$sql .= " a.fk_contact, a.note, a.percent as percent,";
$sql .= " a.fk_element, a.elementtype, a.datec, a.tms as datem,";
$sql .= " c.code as type_code, c.libelle as type_label, c.color as type_color, c.type as type_type, c.picto as type_picto,";
@ -933,6 +933,7 @@ while ($i < $imaxinloop) {
$actionstatic->note_private = dol_htmlentitiesbr($obj->note);
$actionstatic->datep = $db->jdate($obj->dp);
$actionstatic->percentage = $obj->percent;
$actionstatic->authorid = $obj->fk_user_author;
// Initialize $this->userassigned && this->socpeopleassigned array && this->userownerid
// but only if we need it

View File

@ -73,17 +73,19 @@ $result = $object->fetch($id);
$hookmanager->initHooks(array('ciblescard', 'globalcard'));
// Security check
if (!$user->rights->mailing->lire || (empty($conf->global->EXTERNAL_USERS_ARE_AUTHORIZED) && $user->socid > 0)) {
if (!$user->hasRight('mailing', 'lire') || (empty($conf->global->EXTERNAL_USERS_ARE_AUTHORIZED) && $user->socid > 0)) {
accessforbidden();
}
//$result = restrictedArea($user, 'mailing');
$sqlmessage = '';
/*
* Actions
*/
if ($action == 'add') {
if ($action == 'add' && $user->hasRight('mailing', 'creer')) { // Add recipients
$module = GETPOST("module", 'alpha');
$result = -1;
@ -103,6 +105,8 @@ if ($action == 'add') {
$obj = new $classname($db);
dol_syslog("Call add_to_target on class ".$classname);
$result = $obj->add_to_target($id);
$sqlmessage = $obj->sql;
}
}
if ($result > 0) {
@ -117,7 +121,7 @@ if ($action == 'add') {
}
}
if (GETPOST('clearlist', 'int')) {
if (GETPOST('clearlist', 'int') && $user->hasRight('mailing', 'creer')) {
// Loading Class
$obj = new MailingTargets($db);
$obj->clear_target($id);
@ -127,7 +131,7 @@ if (GETPOST('clearlist', 'int')) {
*/
}
if (GETPOST('exportcsv', 'int')) {
if (GETPOST('exportcsv', 'int') && $user->hasRight('mailing', 'lire')) {
$completefilename = 'targets_emailing'.$object->id.'_'.dol_print_date(dol_now(), 'dayhourlog').'.csv';
header('Content-Type: text/csv');
header('Content-Disposition: attachment;filename='.$completefilename);
@ -166,7 +170,7 @@ if (GETPOST('exportcsv', 'int')) {
exit;
}
if ($action == 'delete') {
if ($action == 'delete' && $user->hasRight('mailing', 'creer')) {
// Ici, rowid indique le destinataire et id le mailing
$sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE rowid = ".((int) $rowid);
$resql = $db->query($sql);
@ -454,7 +458,14 @@ if ($object->fetch($id) >= 0) {
print '</div>'; // End table
print '</div>';
print '<br><br>';
print '<br>';
if ($sqlmessage && $user->admin) {
print info_admin($langs->trans("SQLUsedForExport").':<br> '.$sqlmessage, 0, 0, 1, '', 'TechnicalInformation');
print '<br>';
}
print '<br>';
}
// List of selected targets

View File

@ -0,0 +1,256 @@
<?php
/* Copyright (C) 2023 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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/comm/propal/agenda.php
* \ingroup propal
* \brief Tab of events on Proposal
*/
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/propal.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
// Load translation files required by the page
$langs->loadLangs(array("propal", "other"));
// Get parameters
$id = GETPOST('id', 'int');
$ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
$backtopage = GETPOST('backtopage', 'alpha');
if (GETPOST('actioncode', 'array')) {
$actioncode = GETPOST('actioncode', 'array', 3);
if (!count($actioncode)) {
$actioncode = '0';
}
} else {
$actioncode = GETPOST("actioncode", "alpha", 3) ? GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : getDolGlobalString('AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT'));
}
$search_rowid = GETPOST('search_rowid');
$search_agenda_label = GETPOST('search_agenda_label');
$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 == -1) {
$page = 0;
} // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
if (!$sortfield) {
$sortfield = 'a.datep,a.id';
}
if (!$sortorder) {
$sortorder = 'DESC,DESC';
}
// Initialize technical objects
$object = new Propal($db);
$extrafields = new ExtraFields($db);
$diroutputmassaction = $conf->propal->multidir_output[$conf->entity].'/temp/massgeneration/'.$user->id;
$hookmanager->initHooks(array('propalagenda', 'globalcard')); // Note that conf->hooks_modules contains array
// Fetch optionals attributes and labels
$extrafields->fetch_name_optionals_label($object->table_element);
// Load object
include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals
if ($id > 0 || !empty($ref)) {
$upload_dir = $conf->propal->multidir_output[!empty($object->entity) ? $object->entity : $conf->entity]."/".$object->id;
}
$permissiontoread = $user->hasRight("propal", "lire");
$permissiontoadd = $user->hasRight("propal", "creer");
// Security check
if (!empty($user->socid)) {
$socid = $user->socid;
}
$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
restrictedArea($user, 'propal', $object->id, '', '', 'fk_soc', 'rowid', $isdraft);
/*
* Actions
*/
$parameters = array('id'=>$id);
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
}
if (empty($reshook)) {
// Cancel
if (GETPOST('cancel', 'alpha') && !empty($backtopage)) {
header("Location: ".$backtopage);
exit;
}
// Purge search criteria
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
$actioncode = '';
$search_agenda_label = '';
}
}
/*
* View
*/
$form = new Form($db);
if ($object->id > 0) {
$title = $langs->trans("Agenda");
//if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->name." - ".$title;
$help_url = 'EN:Module_Agenda_En|DE:Modul_Terminplanung';
llxHeader('', $title, $help_url);
if (isModEnabled('notification')) {
$langs->load("mails");
}
$head = propal_prepare_head($object);
print dol_get_fiche_head($head, 'agenda', $langs->trans("Proposal"), -1, $object->picto);
// Object card
// ------------------------------------------------------------
$linkback = '<a href="'.DOL_URL_ROOT.'/comm/propal/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
$morehtmlref = '<div class="refidno">';
// Ref customer
$morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
$morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
// Project
if (isModEnabled('project')) {
$langs->load("projects");
$morehtmlref .= '<br>';
if (0) {
$morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
if ($action != 'classify') {
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
}
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
} else {
if (!empty($object->fk_project)) {
$proj = new Project($db);
$proj->fetch($object->fk_project);
$morehtmlref .= $proj->getNomUrl(1);
if ($proj->title) {
$morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
}
}
}
}
$morehtmlref .= '</div>';
dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
print '<div class="fichecenter">';
print '<div class="underbanner clearboth"></div>';
$object->info($object->id);
dol_print_object_info($object, 1);
print '</div>';
print dol_get_fiche_end();
// Actions buttons
$objthirdparty = $object;
$objcon = new stdClass();
$out = '&origin='.urlencode($object->element.(property_exists($object, 'module') ? '@'.$object->module : '')).'&originid='.urlencode($object->id);
$urlbacktopage = $_SERVER['PHP_SELF'].'?id='.$object->id;
$out .= '&backtopage='.urlencode($urlbacktopage);
$permok = $user->rights->agenda->myactions->create;
if ((!empty($objthirdparty->id) || !empty($objcon->id)) && $permok) {
//$out.='<a href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create';
if (get_class($objthirdparty) == 'Societe') {
$out .= '&socid='.urlencode($objthirdparty->id);
}
$out .= (!empty($objcon->id) ? '&contactid='.urlencode($objcon->id) : '');
//$out.=$langs->trans("AddAnAction").' ';
//$out.=img_picto($langs->trans("AddAnAction"),'filenew');
//$out.="</a>";
}
$morehtmlright = '';
//$messagingUrl = DOL_URL_ROOT.'/societe/messaging.php?socid='.$object->id;
//$morehtmlright .= dolGetButtonTitle($langs->trans('ShowAsConversation'), '', 'fa fa-comments imgforviewmode', $messagingUrl, '', 1);
//$messagingUrl = DOL_URL_ROOT.'/societe/agenda.php?socid='.$object->id;
//$morehtmlright .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-bars imgforviewmode', $messagingUrl, '', 2);
if (isModEnabled('agenda')) {
if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')) {
$morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out);
} else {
$morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out, '', 0);
}
}
if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
print '<br>';
$param = '&id='.$object->id.(!empty($socid) ? '&socid='.$socid : '');
if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
$param .= '&contextpage='.urlencode($contextpage);
}
if ($limit > 0 && $limit != $conf->liste_limit) {
$param .= '&limit='.urlencode($limit);
}
// Try to know count of actioncomm from cache
require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
$cachekey = 'count_events_propal_'.$object->id;
$nbEvent = dol_getcache($cachekey);
print_barre_liste($langs->trans("ActionsOnPropal").(is_numeric($nbEvent) ? '<span class="opacitymedium colorblack paddingleft">('.$nbEvent.')</span>': ''), 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 1);
//print_barre_liste($langs->trans("ActionsOnPropal"), 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 1);
// List of all actions
$filters = array();
$filters['search_agenda_label'] = $search_agenda_label;
$filters['search_rowid'] = $search_rowid;
// TODO Replace this with same code than into list.php
show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder, property_exists($object, 'module') ? $object->module : '');
}
}
// End of page
llxFooter();
$db->close();

View File

@ -79,6 +79,7 @@ $cancel = GETPOST('cancel', 'alpha');
$origin = GETPOST('origin', 'alpha');
$originid = GETPOST('originid', 'int');
$confirm = GETPOST('confirm', 'alpha');
$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
$lineid = GETPOST('lineid', 'int');
$contactid = GETPOST('contactid', 'int');
$projectid = GETPOST('projectid', 'int');
@ -955,6 +956,8 @@ if (empty($reshook)) {
$price_ttc = '';
$price_ttc_devise = '';
// TODO Implement if (getDolGlobalInt('MAIN_UNIT_PRICE_WITH_TAX_IS_FOR_ALL_TAXES'))
if (GETPOST('price_ht') !== '') {
$price_ht = price2num(GETPOST('price_ht'), 'MU', 2);
}
@ -1772,6 +1775,7 @@ if ($action == 'create') {
print '<form name="addprop" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="add">';
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
if ($origin != 'project' && $originid) {
print '<input type="hidden" name="origin" value="'.$origin.'">';
print '<input type="hidden" name="originid" value="'.$originid.'">';
@ -1809,7 +1813,7 @@ if ($action == 'create') {
print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', '((s.client = 1 OR s.client = 2 OR s.client = 3) AND status=1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 maxwidth500 widthcentpercentminusxx');
// reload page to retrieve customer informations
if (empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED)) {
print '<script type="text/javascript">
print '<script>
$(document).ready(function() {
$("#socid").change(function() {
console.log("We have changed the company - Reload page");
@ -1898,7 +1902,7 @@ if ($action == 'create') {
$shipping_method_id = $soc->shipping_method_id;
}
print '<tr class="field_shipping_method_id"><td class="titlefieldcreate">'.$langs->trans('SendingMethod').'</td><td class="valuefieldcreate">';
print img_picto('', 'object_dollyrevert', 'class="pictofixedwidth"');
print img_picto('', 'dolly', 'class="pictofixedwidth"');
$form->selectShippingMethod($shipping_method_id, 'shipping_method_id', '', 1, '', 0, 'maxwidth200 widthcentpercentminusx');
print '</td></tr>';
}
@ -1943,6 +1947,7 @@ if ($action == 'create') {
print '<tr class="field_incoterm_id">';
print '<td class="titlefieldcreate"><label for="incoterm_id">'.$form->textwithpicto($langs->trans("IncotermLabel"), $soc->label_incoterms, 1).'</label></td>';
print '<td class="valuefieldcreate maxwidthonsmartphone">';
print img_picto('', 'incoterm', 'class="pictofixedwidth"');
print $form->select_incoterms((!empty($soc->fk_incoterms) ? $soc->fk_incoterms : ''), (!empty($soc->location_incoterms) ? $soc->location_incoterms : ''));
print '</td></tr>';
}
@ -2446,6 +2451,7 @@ if ($action == 'create') {
print '<form name="editdate" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="setdate">';
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
print $form->selectDate($object->date, 're', '', '', 0, "editdate");
print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
print '</form>';
@ -2473,6 +2479,7 @@ if ($action == 'create') {
print '<form name="editecheance" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="setecheance">';
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
print $form->selectDate($object->fin_validite, 'ech', '', '', '', "editecheance");
print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
print '</form>';
@ -2833,6 +2840,7 @@ if ($action == 'create') {
<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
<input type="hidden" name="mode" value="">
<input type="hidden" name="page_y" value="">
<input type="hidden" name="backtopage" value="'.$backtopage.'">
<input type="hidden" name="id" value="' . $object->id.'">
';
@ -2842,7 +2850,7 @@ if ($action == 'create') {
print '<div class="div-table-responsive-no-min">';
if (!empty($object->lines) || ($object->statut == Propal::STATUS_DRAFT && $usercancreate && $action != 'selectlines' && $action != 'editline')) {
print '<table id="tablelines" class="noborder noshadow" width="100%">';
print '<table id="tablelines" class="noborder noshadow centpercent">';
}
if (!empty($object->lines)) {
@ -3037,10 +3045,14 @@ if ($action == 'create') {
print '</div><div class="fichehalfright">';
$MAXEVENT = 10;
$morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/comm/propal/agenda.php?id='.$object->id);
// List of actions on element
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
$formactions = new FormActions($db);
$somethingshown = $formactions->showactions($object, 'propal', $socid, 1);
$somethingshown = $formactions->showactions($object, 'propal', $socid, 1, '', $MAXEVENT, '', $morehtmlcenter); // Show all action for thirdparty
print '</div></div>';
}

View File

@ -871,6 +871,8 @@ class Propal extends CommonObject
$txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate.
}
// TODO Implement if (getDolGlobalInt('MAIN_UNIT_PRICE_WITH_TAX_IS_FOR_ALL_TAXES')) ?
$tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise);
$total_ht = $tabprice[0];
$total_tva = $tabprice[1];
@ -3706,6 +3708,7 @@ class Propal extends CommonObject
global $conf, $langs, $user;
$datas = [];
$nofetch = !empty($params['nofetch']);
if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
return ['optimize' => $langs->trans("Proposal")];
@ -3718,9 +3721,25 @@ class Propal extends CommonObject
if (!empty($this->ref)) {
$datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
}
if (!$nofetch) {
$langs->load('companies');
if (empty($this->thirdparty)) {
$this->fetch_thirdparty();
}
$datas['customer'] = '<br><b>'.$langs->trans('Customer').':</b> '.$this->thirdparty->getNomUrl(1, '', 0, 1);
}
if (!empty($this->ref_client)) {
$datas['refcustomer'] = '<br><b>'.$langs->trans('RefCustomer').':</b> '.$this->ref_client;
}
if (!$nofetch) {
$langs->load('project');
if (empty($this->project)) {
$res = $this->fetch_project();
if ($res > 0) {
$datas['project'] = '<br><b>'.$langs->trans('Project').':</b> '.$this->project->getNomUrl(1, '', 0, 1);
}
}
}
if (!empty($this->total_ht)) {
$datas['amountht'] = '<br><b>'.$langs->trans('AmountHT').':</b> '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
}
@ -3765,6 +3784,7 @@ class Propal extends CommonObject
'id' => $this->id,
'objecttype' => $this->element,
'option' => $option,
'nofetch' => 1,
];
$classfortooltip = 'classfortooltip';
$dataparams = '';
@ -3964,6 +3984,9 @@ class Propal extends CommonObject
public function getKanbanView($option = '', $arraydata = null)
{
global $langs;
$selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
$return = '<div class="box-flex-item box-flex-grow-zero">';
$return .= '<div class="info-box info-box-sm">';
$return .= '<span class="info-box-icon bg-infobox-action">';
@ -3972,6 +3995,7 @@ class Propal extends CommonObject
$return .= '</span>';
$return .= '<div class="info-box-content">';
$return .= '<span class="info-box-ref">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
$return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
if (property_exists($this, 'fk_project')) {
$return .= '<span class="info-box-ref"> | '.$this->fk_project.'</span>';
}

View File

@ -246,13 +246,14 @@ class PropaleStats extends Stats
global $user;
$sql = "SELECT product.ref, COUNT(product.ref) as nb, SUM(tl.".$this->field_line.") as total, AVG(tl.".$this->field_line.") as avg";
$sql .= " FROM ".$this->from.", ".$this->from_line.", ".MAIN_DB_PREFIX."product as product";
$sql .= " FROM ".$this->from;
$sql .= " INNER JOIN ".$this->from_line." ON p.rowid = tl.fk_propal";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."product as product ON tl.fk_product = product.rowid";
if (empty($user->rights->societe->client->voir) && !$user->socid) {
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
}
$sql .= $this->join;
$sql .= " WHERE ".$this->where;
$sql .= " AND p.rowid = tl.fk_propal AND tl.fk_product = product.rowid";
$sql .= " AND ".$this->field_date." BETWEEN '".$this->db->idate(dol_get_first_day($year, 1, false))."' AND '".$this->db->idate(dol_get_last_day($year, 12, false))."'";
$sql .= " GROUP BY product.ref";
$sql .= $this->db->order('nb', 'DESC');

View File

@ -63,9 +63,9 @@ if (!$error) {
}
// Security check
$socid = '';
if (!empty($user->socid)) {
$socid = $user->socid;
$object->id = $user->socid;
}
restrictedArea($user, 'propal', $object->id);

View File

@ -45,13 +45,6 @@ $confirm = GETPOST('confirm', 'alpha');
$id = GETPOST('id', 'int');
$ref = GETPOST('ref', 'alpha');
// Security check
$socid = '';
if (!empty($user->socid)) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'propal', $id);
// Get parameters
$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit;
$sortfield = GETPOST('sortfield', 'aZ09comma');
@ -84,9 +77,9 @@ $object->fetch($id, $ref);
$permissiontoadd = $user->rights->propal->creer;
// Security check
$socid = '';
if (!empty($user->socid)) {
$socid = $user->socid;
$object->id = $user->socid;
}
restrictedArea($user, 'propal', $object->id);

View File

@ -1,126 +0,0 @@
<?php
/* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2006 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/comm/propal/info.php
* \ingroup propal
* \brief Page d'affichage des infos d'une proposition commerciale
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/propal.lib.php';
if (isModEnabled('project')) {
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
}
// Load translation files required by the page
$langs->loadLangs(array('propal', 'compta'));
$id = GETPOST('id', 'int');
$ref = GETPOST('ref', 'alpha');
$socid = GETPOST('socid', 'int');
$object = new Propal($db);
if (!$object->fetch($id, $ref) > 0) {
dol_print_error($db);
exit;
}
// Security check
if (!empty($user->socid)) {
$socid = $user->socid;
$object->id = $user->socid;
}
restrictedArea($user, 'propal', $object->id);
$usercancreate = $user->hasRight("propal", "creer");
/*
* View
*/
$form = new Form($db);
$title = $object->ref." - ".$langs->trans('Info');
$help_url = 'EN:Commercial_Proposals|FR:Proposition_commerciale|ES:Presupuestos';
llxHeader('', $title, $help_url);
$object->fetch_thirdparty();
$head = propal_prepare_head($object);
print dol_get_fiche_head($head, 'info', $langs->trans('Proposal'), -1, 'propal');
$object->info($object->id);
// Proposal card
$linkback = '<a href="'.DOL_URL_ROOT.'/comm/propal/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
$morehtmlref = '<div class="refidno">';
// Ref customer
$morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
$morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
// Project
if (isModEnabled('project')) {
$langs->load("projects");
$morehtmlref .= '<br>';
if (0) {
$morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
if ($action != 'classify') {
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
}
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
} else {
if (!empty($object->fk_project)) {
$proj = new Project($db);
$proj->fetch($object->fk_project);
$morehtmlref .= $proj->getNomUrl(1);
if ($proj->title) {
$morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
}
}
}
}
$morehtmlref .= '</div>';
dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
print '<div class="fichecenter">';
print '<div class="underbanner clearboth"></div>';
print '<br>';
dol_print_object_info($object);
print '</div>';
print dol_get_fiche_end();
// End of page
llxFooter();
$db->close();

View File

@ -196,7 +196,7 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen
// List of fields to search into when doing a "search in all"
$fieldstosearchall = array(
'p.ref'=>'Ref',
'p.ref_client'=>'CustomerRef',
'p.ref_client'=>'RefCustomer',
'pd.description'=>'Description',
's.nom'=>"ThirdParty",
's.name_alias'=>"AliasNameShort",

View File

@ -49,9 +49,9 @@ if ($id > 0 || !empty($ref)) {
}
// Security check
$socid = '';
if ($user->socid > 0) {
$socid = $user->socid;
$object->id = $user->socid;
}
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context

256
htdocs/commande/agenda.php Normal file
View File

@ -0,0 +1,256 @@
<?php
/* Copyright (C) 2023 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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/commande/agenda.php
* \ingroup commande
* \brief Tab of events on Sale Orders
*/
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/order.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
// Load translation files required by the page
$langs->loadLangs(array("order", "other"));
// Get parameters
$id = GETPOST('id', 'int');
$ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
$backtopage = GETPOST('backtopage', 'alpha');
if (GETPOST('actioncode', 'array')) {
$actioncode = GETPOST('actioncode', 'array', 3);
if (!count($actioncode)) {
$actioncode = '0';
}
} else {
$actioncode = GETPOST("actioncode", "alpha", 3) ? GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : getDolGlobalString('AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT'));
}
$search_rowid = GETPOST('search_rowid');
$search_agenda_label = GETPOST('search_agenda_label');
$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 == -1) {
$page = 0;
} // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
if (!$sortfield) {
$sortfield = 'a.datep,a.id';
}
if (!$sortorder) {
$sortorder = 'DESC,DESC';
}
// Initialize technical objects
$object = new Commande($db);
$extrafields = new ExtraFields($db);
$diroutputmassaction = $conf->commande->multidir_output[$conf->entity].'/temp/massgeneration/'.$user->id;
$hookmanager->initHooks(array('orderagenda', 'globalcard')); // Note that conf->hooks_modules contains array
// Fetch optionals attributes and labels
$extrafields->fetch_name_optionals_label($object->table_element);
// Load object
include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals
if ($id > 0 || !empty($ref)) {
$upload_dir = $conf->commande->multidir_output[!empty($object->entity) ? $object->entity : $conf->entity]."/".$object->id;
}
$permissiontoread = $user->hasRight("commande", "lire");
$permissiontoadd = $user->hasRight("commande", "creer");
// Security check
if (!empty($user->socid)) {
$socid = $user->socid;
}
$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
restrictedArea($user, 'commande', $object->id, '', '', 'fk_soc', 'rowid', $isdraft);
/*
* Actions
*/
$parameters = array('id'=>$id);
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
}
if (empty($reshook)) {
// Cancel
if (GETPOST('cancel', 'alpha') && !empty($backtopage)) {
header("Location: ".$backtopage);
exit;
}
// Purge search criteria
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
$actioncode = '';
$search_agenda_label = '';
}
}
/*
* View
*/
$form = new Form($db);
if ($object->id > 0) {
$title = $langs->trans("Agenda");
//if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->name." - ".$title;
$help_url = 'EN:Module_Agenda_En|DE:Modul_Terminplanung';
llxHeader('', $title, $help_url);
if (isModEnabled('notification')) {
$langs->load("mails");
}
$head = commande_prepare_head($object);
print dol_get_fiche_head($head, 'agenda', $langs->trans("Order"), -1, $object->picto);
// Object card
// ------------------------------------------------------------
$linkback = '<a href="'.DOL_URL_ROOT.'/commande/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
$morehtmlref = '<div class="refidno">';
// Ref customer
$morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
$morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
// Project
if (isModEnabled('project')) {
$langs->load("projects");
$morehtmlref .= '<br>';
if (0) {
$morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
if ($action != 'classify') {
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
}
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
} else {
if (!empty($object->fk_project)) {
$proj = new Project($db);
$proj->fetch($object->fk_project);
$morehtmlref .= $proj->getNomUrl(1);
if ($proj->title) {
$morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
}
}
}
}
$morehtmlref .= '</div>';
dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
print '<div class="fichecenter">';
print '<div class="underbanner clearboth"></div>';
$object->info($object->id);
dol_print_object_info($object, 1);
print '</div>';
print dol_get_fiche_end();
// Actions buttons
$objthirdparty = $object;
$objcon = new stdClass();
$out = '&origin='.urlencode($object->element.(property_exists($object, 'module') ? '@'.$object->module : '')).'&originid='.urlencode($object->id);
$urlbacktopage = $_SERVER['PHP_SELF'].'?id='.$object->id;
$out .= '&backtopage='.urlencode($urlbacktopage);
$permok = $user->rights->agenda->myactions->create;
if ((!empty($objthirdparty->id) || !empty($objcon->id)) && $permok) {
//$out.='<a href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create';
if (get_class($objthirdparty) == 'Societe') {
$out .= '&socid='.urlencode($objthirdparty->id);
}
$out .= (!empty($objcon->id) ? '&contactid='.urlencode($objcon->id) : '');
//$out.=$langs->trans("AddAnAction").' ';
//$out.=img_picto($langs->trans("AddAnAction"),'filenew');
//$out.="</a>";
}
$morehtmlright = '';
//$messagingUrl = DOL_URL_ROOT.'/societe/messaging.php?socid='.$object->id;
//$morehtmlright .= dolGetButtonTitle($langs->trans('ShowAsConversation'), '', 'fa fa-comments imgforviewmode', $messagingUrl, '', 1);
//$messagingUrl = DOL_URL_ROOT.'/societe/agenda.php?socid='.$object->id;
//$morehtmlright .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-bars imgforviewmode', $messagingUrl, '', 2);
if (isModEnabled('agenda')) {
if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')) {
$morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out);
} else {
$morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out, '', 0);
}
}
if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
print '<br>';
$param = '&id='.$object->id.(!empty($socid) ? '&socid='.$socid : '');
if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
$param .= '&contextpage='.urlencode($contextpage);
}
if ($limit > 0 && $limit != $conf->liste_limit) {
$param .= '&limit='.urlencode($limit);
}
// Try to know count of actioncomm from cache
require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
$cachekey = 'count_events_commande_'.$object->id;
$nbEvent = dol_getcache($cachekey);
print_barre_liste($langs->trans("ActionsOnOrder").(is_numeric($nbEvent) ? '<span class="opacitymedium colorblack paddingleft">('.$nbEvent.')</span>': ''), 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 1);
//print_barre_liste($langs->trans("ActionsOnOrder"), 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 1);
// List of all actions
$filters = array();
$filters['search_agenda_label'] = $search_agenda_label;
$filters['search_rowid'] = $search_rowid;
// TODO Replace this with same code than into list.php
show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder, property_exists($object, 'module') ? $object->module : '');
}
}
// End of page
llxFooter();
$db->close();

View File

@ -84,6 +84,8 @@ $socid = GETPOST('socid', 'int');
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$confirm = GETPOST('confirm', 'alpha');
$backtopage = GETPOST('backtopage', 'alpha');
$lineid = GETPOST('lineid', 'int');
$contactid = GETPOST('contactid', 'int');
$projectid = GETPOST('projectid', 'int');
@ -1755,6 +1757,7 @@ if ($action == 'create' && $usercancreate) {
print '<input type="hidden" name="remise_percent" value="'.$soc->remise_percent.'">';
print '<input type="hidden" name="origin" value="'.$origin.'">';
print '<input type="hidden" name="originid" value="'.$originid.'">';
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
if (!empty($currency_tx)) {
print '<input type="hidden" name="originmulticurrency_tx" value="'.$currency_tx.'">';
}
@ -1785,10 +1788,10 @@ if ($action == 'create' && $usercancreate) {
print '</td>';
} else {
print '<td>';
print img_picto('', 'company').$form->select_company('', 'socid', '((s.client = 1 OR s.client = 2 OR s.client = 3) AND s.status=1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', '((s.client = 1 OR s.client = 2 OR s.client = 3) AND s.status=1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
// reload page to retrieve customer informations
if (empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED)) {
print '<script type="text/javascript">
print '<script>
$(document).ready(function() {
$("#socid").change(function() {
console.log("We have changed the company - Reload page");
@ -1828,6 +1831,7 @@ if ($action == 'create' && $usercancreate) {
// Date
print '<tr><td class="fieldrequired">'.$langs->trans('Date').'</td><td>';
print img_picto('', 'action', 'class="pictofixedwidth"');
print $form->selectDate('', 're', '', '', '', "crea_commande", 1, 1); // Always autofill date with current date
print '</td></tr>';
@ -1835,6 +1839,7 @@ if ($action == 'create' && $usercancreate) {
print '<tr><td>'.$langs->trans("DateDeliveryPlanned").'</td>';
print '<td colspan="3">';
$date_delivery = ($date_delivery ? $date_delivery : $object->delivery_date);
print img_picto('', 'action', 'class="pictofixedwidth"');
print $form->selectDate($date_delivery ? $date_delivery : -1, 'liv_', 1, 1, 1);
print "</td>\n";
print '</tr>';
@ -1848,13 +1853,13 @@ if ($action == 'create' && $usercancreate) {
// Terms of payment
print '<tr><td class="nowrap">'.$langs->trans('PaymentConditionsShort').'</td><td>';
print img_picto('', 'payment', 'class="pictofixedwidth"');
print $form->getSelectConditionsPaiements((GETPOSTISSET('cond_reglement_id')?GETPOST('cond_reglement_id'):$cond_reglement_id), 'cond_reglement_id', 1, 1, 0, 'maxwidth200 widthcentpercentminusx', $deposit_percent);
print $form->getSelectConditionsPaiements(((GETPOSTISSET('cond_reglement_id') && GETPOST('cond_reglement_id') != 0)?GETPOST('cond_reglement_id'):$cond_reglement_id), 'cond_reglement_id', 1, 1, 0, 'maxwidth200 widthcentpercentminusx', $deposit_percent);
print '</td></tr>';
// Payment mode
print '<tr><td>'.$langs->trans('PaymentMode').'</td><td>';
print img_picto('', 'bank', 'class="pictofixedwidth"');
print $form->select_types_paiements((GETPOSTISSET('mode_reglement_id')?GETPOST('mode_reglement_id'):$mode_reglement_id), 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx', 1);
print $form->select_types_paiements(((GETPOSTISSET('mode_reglement_id') && GETPOST('mode_reglement_id') != 0)?GETPOST('mode_reglement_id'):$mode_reglement_id), 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx', 1);
print '</td></tr>';
// Bank Account
@ -1867,7 +1872,7 @@ if ($action == 'create' && $usercancreate) {
// Shipping Method
if (isModEnabled('expedition')) {
print '<tr><td>'.$langs->trans('SendingMethod').'</td><td>';
print img_picto('', 'object_dolly', 'class="pictofixedwidth"');
print img_picto('', 'dolly', 'class="pictofixedwidth"');
$form->selectShippingMethod((GETPOSTISSET('shipping_method_id')?GETPOST('shipping_method_id'):$shipping_method_id), 'shipping_method_id', '', 1, '', 0, 'maxwidth200 widthcentpercentminusx');
print '</td></tr>';
}
@ -1911,6 +1916,7 @@ if ($action == 'create' && $usercancreate) {
$incoterm_id = (!empty($objectsrc->fk_incoterms) ? $objectsrc->fk_incoterms : $soc->fk_incoterms);
$incoterm_location = (!empty($objectsrc->location_incoterms) ? $objectsrc->location_incoterms : $soc->location_incoterms);
}
print img_picto('', 'incoterm', 'class="pictofixedwidth"');
print $form->select_incoterms($incoterm_id, $incoterm_location);
print '</td></tr>';
}
@ -2446,6 +2452,7 @@ if ($action == 'create' && $usercancreate) {
print '<form name="setdate" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="setdate">';
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
print $form->selectDate($object->date, 'order_', '', '', '', "setdate");
print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
print '</form>';
@ -2467,6 +2474,7 @@ if ($action == 'create' && $usercancreate) {
print '<form name="setdate_livraison" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'" method="post">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="setdate_livraison">';
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
print $form->selectDate($object->delivery_date ? $object->delivery_date : -1, 'liv_', 1, 1, '', "setdate_livraison", 1, 0);
print '<input type="submit" class="button button-edit" value="'.$langs->trans('Modify').'">';
print '</form>';
@ -2760,7 +2768,9 @@ if ($action == 'create' && $usercancreate) {
<input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
<input type="hidden" name="mode" value="">
<input type="hidden" name="page_y" value="">
<input type="hidden" name="id" value="' . $object->id.'">';
<input type="hidden" name="id" value="' . $object->id.'">
<input type="hidden" name="backtopage" value="'.$backtopage.'">
';
if (!empty($conf->use_javascript_ajax) && $object->statut == Commande::STATUS_DRAFT) {
include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
@ -2973,10 +2983,14 @@ if ($action == 'create' && $usercancreate) {
print '</div><div class="fichehalfright">';
$MAXEVENT = 10;
$morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/commande/agenda.php?id='.$object->id);
// List of actions on element
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
$formactions = new FormActions($db);
$somethingshown = $formactions->showactions($object, 'order', $socid, 1);
$somethingshown = $formactions->showactions($object, 'order', $socid, 1, '', $MAXEVENT, '', $morehtmlcenter); // Show all action for thirdparty
print '</div></div>';
}
@ -2984,7 +2998,7 @@ if ($action == 'create' && $usercancreate) {
// Presend form
$modelmail = 'order_send';
$defaulttopic = 'SendOrderRef';
$diroutput = $conf->commande->multidir_output[$object->entity];
$diroutput = getMultidirOutput($object);
$trackid = 'ord'.$object->id;
include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';

View File

@ -712,6 +712,7 @@ class Orders extends DolibarrApi
* @throws RestException 401
* @throws RestException 404
* @throws RestException 500 System error
*
*/
public function validate($id, $idwarehouse = 0, $notrigger = 0)
{

View File

@ -2727,7 +2727,7 @@ class Commande extends CommonOrder
* @param int $offset For pagination
* @param string $sortfield Sort criteria
* @param string $sortorder Sort order
* @return int -1 if KO, array with result if OK
* @return int|array -1 if KO, array with result if OK
*/
public function liste_array($shortlist = 0, $draft = 0, $excluser = '', $socid = 0, $limit = 0, $offset = 0, $sortfield = 'c.date_commande', $sortorder = 'DESC')
{
@ -3728,6 +3728,7 @@ class Commande extends CommonOrder
global $conf, $langs, $user;
$datas = [];
$nofetch = !empty($params['nofetch']);
if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
return ['optimize' => $langs->trans("Order")];
@ -3739,7 +3740,23 @@ class Commande extends CommonOrder
$datas[] = ' '.$this->getLibStatut(5);
}
$datas['Ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
if (!$nofetch) {
$langs->load('companies');
if (empty($this->thirdparty)) {
$this->fetch_thirdparty();
}
$datas['customer'] = '<br><b>'.$langs->trans('Customer').':</b> '.$this->thirdparty->getNomUrl(1, '', 0, 1);
}
$datas['RefCustomer'] = '<br><b>'.$langs->trans('RefCustomer').':</b> '.(empty($this->ref_customer) ? (empty($this->ref_client) ? '' : $this->ref_client) : $this->ref_customer);
if (!$nofetch) {
$langs->load('project');
if (empty($this->project)) {
$res = $this->fetch_project();
if ($res > 0) {
$datas['project'] = '<br><b>'.$langs->trans('Project').':</b> '.$this->project->getNomUrl(1, '', 0, 1);
}
}
}
if (!empty($this->total_ht)) {
$datas['AmountHT'] = '<br><b>'.$langs->trans('AmountHT').':</b> '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
}
@ -3811,6 +3828,7 @@ class Commande extends CommonOrder
'id' => $this->id,
'objecttype' => $this->element,
'option' => $option,
'nofetch' => 1,
];
$classfortooltip = 'classfortooltip';
$dataparams = '';
@ -3960,6 +3978,7 @@ class Commande extends CommonOrder
$this->id = 0;
$this->ref = 'SPECIMEN';
$this->specimen = 1;
$this->entity = $conf->entity;
$this->socid = 1;
$this->date = time();
$this->date_lim_reglement = $this->date + 3600 * 24 * 30;

View File

@ -243,13 +243,14 @@ class CommandeStats extends Stats
global $user;
$sql = "SELECT product.ref, COUNT(product.ref) as nb, SUM(tl.".$this->field_line.") as total, AVG(tl.".$this->field_line.") as avg";
$sql .= " FROM ".$this->from.", ".$this->from_line.", ".MAIN_DB_PREFIX."product as product";
$sql .= " FROM ".$this->from;
$sql .= " INNER JOIN ".$this->from_line." ON c.rowid = tl.fk_commande";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."product as product ON tl.fk_product = product.rowid";
if (empty($user->rights->societe->client->voir) && !$user->socid) {
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
}
$sql .= $this->join;
$sql .= " WHERE ".$this->where;
$sql .= " AND c.rowid = tl.fk_commande AND tl.fk_product = product.rowid";
$sql .= " AND c.date_commande BETWEEN '".$this->db->idate(dol_get_first_day($year, 1, false))."' AND '".$this->db->idate(dol_get_last_day($year, 12, false))."'";
$sql .= " GROUP BY product.ref";
$sql .= $this->db->order('nb', 'DESC');

View File

@ -1,129 +0,0 @@
<?php
/* Copyright (C) 2005-2006 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/commande/info.php
* \ingroup commande
* \brief Sale Order info page
*/
// Load Dolibarr environment
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/order.lib.php';
if (isModEnabled('project')) {
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
}
if (!$user->rights->commande->lire) {
accessforbidden();
}
// Load translation files required by the page
$langs->loadLangs(array('orders', 'sendings', 'bills'));
$socid = 0;
$comid = GETPOST("id", 'int');
$id = GETPOST("id", 'int');
$ref = GETPOST('ref', 'alpha');
// Security check
if ($user->socid) {
$socid = $user->socid;
}
$result = restrictedArea($user, 'commande', $comid, '');
$usercancreate = $user->hasRight("commande", "creer");
$object = new Commande($db);
if (!$object->fetch($id, $ref) > 0) {
dol_print_error($db);
exit;
}
/*
* View
*/
$form = new Form($db);
$title = $langs->trans('Order')." - ".$langs->trans('Info');
$help_url = 'EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes|DE:Modul_Kundenaufträge';
llxHeader('', $title, $help_url);
$object->fetch_thirdparty();
$object->info($object->id);
$head = commande_prepare_head($object);
print dol_get_fiche_head($head, 'info', $langs->trans("CustomerOrder"), -1, 'order');
// Order card
$linkback = '<a href="'.DOL_URL_ROOT.'/commande/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
$morehtmlref = '<div class="refidno">';
// Ref customer
$morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
$morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
// Project
if (isModEnabled('project')) {
$langs->load("projects");
$morehtmlref .= '<br>';
if (0) {
$morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
if ($action != 'classify') {
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
}
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
} else {
if (!empty($object->fk_project)) {
$proj = new Project($db);
$proj->fetch($object->fk_project);
$morehtmlref .= $proj->getNomUrl(1);
if ($proj->title) {
$morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
}
}
}
}
$morehtmlref .= '</div>';
dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
print '<div class="fichecenter">';
print '<div class="underbanner clearboth"></div>';
print '<br>';
print '<table width="100%"><tr><td>';
dol_print_object_info($object);
print '</td></tr></table>';
print '</div>';
print dol_get_fiche_end();
// End of page
llxFooter();
$db->close();

View File

@ -223,6 +223,7 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php';
$object->fields = dol_sort_array($object->fields, 'position');
$arrayfields = dol_sort_array($arrayfields, 'position');
$error = 0;
/*
@ -1284,24 +1285,24 @@ if ($resql) {
if ($permissiontovalidate) {
$arrayofmassactions['prevalidate'] = img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate");
}
if ($permissiontosendbymail) {
$arrayofmassactions['presend'] = img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail");
}
if ($permissiontoclose) {
$arrayofmassactions['preshipped'] = img_picto('', 'dollyrevert', 'class="pictofixedwidth"').$langs->trans("ClassifyShipped");
}
if ($permissiontocancel) {
$arrayofmassactions['cancelorders'] = img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("Cancel");
}
if (isModEnabled('facture') && $user->hasRight("facture", "creer")) {
$arrayofmassactions['createbills'] = img_picto('', 'bill', 'class="pictofixedwidth"').$langs->trans("CreateInvoiceForThisCustomer");
}
if ($permissiontoclose) {
$arrayofmassactions['setbilled'] = img_picto('', 'bill', 'class="pictofixedwidth"').$langs->trans("ClassifyBilled");
}
if ($permissiontocancel) {
$arrayofmassactions['cancelorders'] = img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("Cancel");
}
if ($permissiontodelete) {
$arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
}
if (isModEnabled('facture') && $user->hasRight("facture", "creer")) {
$arrayofmassactions['createbills'] = img_picto('', 'bill', 'class="pictofixedwidth"').$langs->trans("CreateInvoiceForThisCustomer");
}
if ($permissiontosendbymail) {
$arrayofmassactions['presend'] = img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail");
}
if (in_array($massaction, array('presend', 'predelete', 'createbills'))) {
$arrayofmassactions = array();
}

View File

@ -135,14 +135,14 @@ if (empty($entity)) {
$error = 0;
$listofchoices = array(
'selectinvoices'=>array('label'=>'Invoices', 'lang'=>'bills', 'enabled' => isModEnabled('facture'), 'perms' => !empty($user->rights->facture->lire)),
'selectsupplierinvoices'=>array('label'=>'BillsSuppliers', 'lang'=>'bills', 'enabled' => isModEnabled('supplier_invoice'), 'perms' => !empty($user->rights->fournisseur->facture->lire)),
'selectexpensereports'=>array('label'=>'ExpenseReports', 'lang'=>'trips', 'enabled' => isModEnabled('expensereport'), 'perms' => !empty($user->rights->expensereport->lire)),
'selectdonations'=>array('label'=>'Donations', 'lang'=>'donation', 'enabled' => isModEnabled('don'), 'perms' => !empty($user->rights->don->lire)),
'selectsocialcontributions'=>array('label'=>'SocialContributions', 'enabled' => isModEnabled('tax'), 'perms' => !empty($user->rights->tax->charges->lire)),
'selectpaymentsofsalaries'=>array('label'=>'SalariesPayments', 'lang'=>'salaries', 'enabled' => isModEnabled('salaries'), 'perms' => !empty($user->rights->salaries->read)),
'selectvariouspayment'=>array('label'=>'VariousPayment', 'enabled' => isModEnabled('banque'), 'perms' => !empty($user->rights->banque->lire)),
'selectloanspayment'=>array('label'=>'PaymentLoan', 'enabled' => isModEnabled('don'), 'perms' => !empty($user->rights->loan->read)),
'selectinvoices'=>array('label'=>'Invoices', 'picto'=>'bill', 'lang'=>'bills', 'enabled' => isModEnabled('facture'), 'perms' => !empty($user->rights->facture->lire)),
'selectsupplierinvoices'=>array('label'=>'BillsSuppliers', 'picto'=>'supplier_invoice', 'lang'=>'bills', 'enabled' => isModEnabled('supplier_invoice'), 'perms' => !empty($user->rights->fournisseur->facture->lire)),
'selectexpensereports'=>array('label'=>'ExpenseReports', 'picto'=>'expensereport', 'lang'=>'trips', 'enabled' => isModEnabled('expensereport'), 'perms' => !empty($user->rights->expensereport->lire)),
'selectdonations'=>array('label'=>'Donations', 'picto'=>'donation', 'lang'=>'donation', 'enabled' => isModEnabled('don'), 'perms' => !empty($user->rights->don->lire)),
'selectsocialcontributions'=>array('label'=>'SocialContributions', 'picto'=>'bill', 'enabled' => isModEnabled('tax'), 'perms' => !empty($user->rights->tax->charges->lire)),
'selectpaymentsofsalaries'=>array('label'=>'SalariesPayments', 'picto'=>'salary', 'lang'=>'salaries', 'enabled' => isModEnabled('salaries'), 'perms' => !empty($user->rights->salaries->read)),
'selectvariouspayment'=>array('label'=>'VariousPayment', 'picto'=>'payment', 'enabled' => isModEnabled('banque'), 'perms' => !empty($user->rights->banque->lire)),
'selectloanspayment'=>array('label'=>'PaymentLoan','picto'=>'loan', 'enabled' => isModEnabled('don'), 'perms' => !empty($user->rights->loan->read)),
);
@ -623,7 +623,9 @@ foreach ($listofchoices as $choice => $val) {
$disabled = ' disabled';
}
$checked = (((!GETPOSTISSET('search') && $action != 'searchfiles') || GETPOST($choice)) ? ' checked="checked"' : '');
print '<div class="paddingleft inline-block marginrightonly"><input type="checkbox" id="'.$choice.'" name="'.$choice.'" value="1"'.$checked.$disabled.'> <label for="'.$choice.'">'.$langs->trans($val['label']).'</label></div>';
print '<div class="paddingleft inline-block marginrightonly paddingright"><input type="checkbox" id="'.$choice.'" name="'.$choice.'" value="1"'.$checked.$disabled.'><label for="'.$choice.'"> ';
print img_picto($langs->trans($val['label']), $val['picto'], 'class=""').' '.$langs->trans($val['label']);
print '</label></div>';
}
print '<input type="submit" class="button small" name="search" value="'.$langs->trans("Search").'">';

View File

@ -55,6 +55,7 @@ $langs->loadLangs(array("banks", "bills", "categories", "companies", "compta", "
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'alpha');
$backtopage = GETPOST('backtopage', 'alpha');
$object = new Account($db);
$extrafields = new ExtraFields($db);
@ -380,6 +381,7 @@ if ($action == 'create') {
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="add">';
print '<input type="hidden" name="clos" value="0">';
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
print dol_get_fiche_head('');
@ -527,6 +529,20 @@ if ($action == 'create') {
print '<td><input type="text" class="flat minwidth150" name="bank" value="'.(GETPOST('bank') ?GETPOST('bank', 'alpha') : $object->bank).'"></td>';
print '</tr>';
$ibankey = FormBank::getIBANLabel($object);
$bickey = "BICNumber";
if ($object->getCountryCode() == 'IN') {
$bickey = "SWIFT";
}
// IBAN
print '<tr><td>'.$langs->trans($ibankey).'</td>';
print '<td><input maxlength="34" type="text" class="flat minwidth300" name="iban" value="'.(GETPOSTISSET('iban') ?GETPOST('iban', 'alpha') : $object->iban).'"></td></tr>';
// BIC
print '<tr><td>'.$langs->trans($bickey).'</td>';
print '<td><input maxlength="11" type="text" class="flat minwidth150" name="bic" value="'.(GETPOSTISSET('bic') ?GETPOST('bic', 'alpha') : $object->bic).'"></td></tr>';
// Show fields of bank account
$sizecss = '';
foreach ($object->getFieldsToShow() as $val) {
@ -553,18 +569,6 @@ if ($action == 'create') {
print '<td><input type="text" class="flat '.$sizecss.'" name="'.$name.'" value="'.(GETPOSTISSET($name) ? GETPOST($name, 'alpha') : $content).'"></td>';
print '</tr>';
}
$ibankey = FormBank::getIBANLabel($object);
$bickey = "BICNumber";
if ($object->getCountryCode() == 'IN') {
$bickey = "SWIFT";
}
// IBAN
print '<tr><td>'.$langs->trans($ibankey).'</td>';
print '<td><input maxlength="34" type="text" class="flat minwidth300" name="iban" value="'.(GETPOSTISSET('iban') ?GETPOST('iban', 'alpha') : $object->iban).'"></td></tr>';
print '<tr><td>'.$langs->trans($bickey).'</td>';
print '<td><input maxlength="11" type="text" class="flat minwidth150" name="bic" value="'.(GETPOSTISSET('bic') ?GETPOST('bic', 'alpha') : $object->bic).'"></td></tr>';
if (isModEnabled('paymentbybanktransfer')) {
print '<tr><td>'.$form->textwithpicto($langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformation"), $langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformationHelp")).'</td>';
@ -753,6 +757,38 @@ if ($action == 'create') {
print '<tr class="liste_titre"><td class="titlefield">'.$langs->trans("BankName").'</td>';
print '<td>'.$object->bank.'</td></tr>';
$ibankey = FormBank::getIBANLabel($object);
$bickey = "BICNumber";
if ($object->getCountryCode() == 'IN') {
$bickey = "SWIFT";
}
// IBAN
print '<tr><td>'.$langs->trans($ibankey).'</td>';
print '<td>'.getIbanHumanReadable($object).'&nbsp;';
if (!empty($object->iban)) {
if (!checkIbanForAccount($object)) {
print img_picto($langs->trans("IbanNotValid"), 'warning');
} else {
print img_picto($langs->trans("IbanValid"), 'info');
}
}
print '</td></tr>';
// BIC
print '<tr><td>'.$langs->trans($bickey).'</td>';
print '<td>'.$object->bic.'&nbsp;';
if (!empty($object->bic)) {
if (!checkSwiftForAccount($object)) {
print img_picto($langs->trans("SwiftNotValid"), 'warning');
} else {
print img_picto($langs->trans("SwiftValid"), 'info');
}
}
print '</td></tr>';
// TODO Add a link "Show more..." for all ohter informations.
// Show fields of bank account
foreach ($object->getFieldsToShow() as $val) {
$content = '';
@ -771,34 +807,6 @@ if ($action == 'create') {
print '</tr>';
}
$ibankey = FormBank::getIBANLabel($object);
$bickey = "BICNumber";
if ($object->getCountryCode() == 'IN') {
$bickey = "SWIFT";
}
print '<tr><td>'.$langs->trans($ibankey).'</td>';
print '<td>'.getIbanHumanReadable($object).'&nbsp;';
if (!empty($object->iban)) {
if (!checkIbanForAccount($object)) {
print img_picto($langs->trans("IbanNotValid"), 'warning');
} else {
print img_picto($langs->trans("IbanValid"), 'info');
}
}
print '</td></tr>';
print '<tr><td>'.$langs->trans($bickey).'</td>';
print '<td>'.$object->bic.'&nbsp;';
if (!empty($object->bic)) {
if (!checkSwiftForAccount($object)) {
print img_picto($langs->trans("SwiftNotValid"), 'warning');
} else {
print img_picto($langs->trans("SwiftValid"), 'info');
}
}
print '</td></tr>';
if (isModEnabled('prelevement')) {
print '<tr><td>'.$form->textwithpicto($langs->trans("ICS"), $langs->trans("ICS").' ('.$langs->trans("UsedFor", $langs->transnoentitiesnoconv("StandingOrder")).')').'</td>';
print '<td>'.$object->ics.'</td>';
@ -898,6 +906,7 @@ if ($action == 'create') {
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="update">';
print '<input type="hidden" name="id" value="'.GETPOST("id", 'int').'">'."\n\n";
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
print dol_get_fiche_head(array(), 0, '', 0);
@ -1080,6 +1089,20 @@ if ($action == 'create') {
print '<td><input type="text" class="flat width300" name="bank" value="'.$object->bank.'"></td>';
print '</tr>';
$ibankey = FormBank::getIBANLabel($object);
$bickey = "BICNumber";
if ($object->getCountryCode() == 'IN') {
$bickey = "SWIFT";
}
// IBAN
print '<tr><td>'.$langs->trans($ibankey).'</td>';
print '<td><input class="minwidth300 maxwidth200onsmartphone" maxlength="34" type="text" class="flat" name="iban" value="'.(GETPOSTISSET('iban') ? GETPOST('iban', 'alphanohtml') : $object->iban).'"></td></tr>';
// BIC
print '<tr><td>'.$langs->trans($bickey).'</td>';
print '<td><input class="minwidth150 maxwidth200onsmartphone" maxlength="11" type="text" class="flat" name="bic" value="'.(GETPOSTISSET('bic') ? GETPOST('bic', 'alphanohtml') : $object->bic).'"></td></tr>';
// Show fields of bank account
foreach ($object->getFieldsToShow() as $val) {
$content = '';
@ -1106,19 +1129,6 @@ if ($action == 'create') {
print '</tr>';
}
$ibankey = FormBank::getIBANLabel($object);
$bickey = "BICNumber";
if ($object->getCountryCode() == 'IN') {
$bickey = "SWIFT";
}
// IBAN
print '<tr><td>'.$langs->trans($ibankey).'</td>';
print '<td><input class="minwidth300 maxwidth200onsmartphone" maxlength="34" type="text" class="flat" name="iban" value="'.(GETPOSTISSET('iban') ? GETPOST('iban', 'alphanohtml') : $object->iban).'"></td></tr>';
print '<tr><td>'.$langs->trans($bickey).'</td>';
print '<td><input class="minwidth150 maxwidth200onsmartphone" maxlength="11" type="text" class="flat" name="bic" value="'.(GETPOSTISSET('bic') ? GETPOST('bic', 'alphanohtml') : $object->bic).'"></td></tr>';
if (isModEnabled('prelevement')) {
print '<tr><td>'.$form->textwithpicto($langs->trans("ICS"), $langs->trans("ICS").' ('.$langs->trans("UsedFor", $langs->transnoentitiesnoconv("StandingOrder")).')').'</td>';
print '<td><input class="minwidth150 maxwidth200onsmartphone" maxlength="32" type="text" class="flat" name="ics" value="'.(GETPOSTISSET('ics') ? GETPOST('ics', 'alphanohtml') : $object->ics).'"></td></tr>';

View File

@ -30,6 +30,7 @@
* \ingroup bank
* \brief File of class to manage bank accounts
*/
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
@ -1118,6 +1119,8 @@ class Account extends CommonObject
$this->db->begin();
// @TODO Check there is no child into llx_payment_various, ... to allow deletion ?
// Delete link between tag and bank account
if (!$error) {
$sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_account";
@ -1831,6 +1834,9 @@ class Account extends CommonObject
public function getKanbanView($option = '', $arraydata = null)
{
global $langs;
$selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
$return = '<div class="box-flex-item box-flex-grow-zero">';
$return .= '<div class="info-box info-box-sm">';
$return .= '<span class="info-box-icon bg-infobox-action">';
@ -1838,6 +1844,7 @@ class Account extends CommonObject
$return .= '</span>';
$return .= '<div class="info-box-content">';
$return .= '<span class="info-box-ref">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).'</span>';
$return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
if (property_exists($this, 'type_lib')) {
$return .= '<br><span class="info-box-label opacitymedium" title="'.$this->type_lib[$this->type].'">'.substr($this->type_lib[$this->type], 0, 24).'...</span>';
@ -1857,6 +1864,8 @@ class Account extends CommonObject
}
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
/**
* Class to manage bank transaction lines
*/
@ -2011,7 +2020,6 @@ class AccountLine extends CommonObjectLine
$sql .= " b.fk_user_author, b.fk_user_rappro,";
$sql .= " b.fk_type, b.num_releve, b.num_chq, b.rappro, b.note,";
$sql .= " b.fk_bordereau, b.banque, b.emetteur,";
//$sql.= " b.author"; // Is this used ?
$sql .= " ba.ref as bank_account_ref, ba.label as bank_account_label";
$sql .= " FROM ".MAIN_DB_PREFIX."bank as b,";
$sql .= " ".MAIN_DB_PREFIX."bank_account as ba";

View File

@ -126,6 +126,22 @@ class PaymentVarious extends CommonObject
public $fk_user_modif;
/**
* @var int Type of bank account if the payment is on a bank account
*/
public $fk_type;
/**
* @var int 1 if the payment is on a bank account line that is conciliated
*/
public $rappro;
/**
* @var string ID of bank receipt
*/
public $bank_num_releve;
/**
* 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password')
* Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)"
@ -251,7 +267,6 @@ class PaymentVarious extends CommonObject
*/
public function fetch($id, $user = null)
{
global $langs;
$sql = "SELECT";
$sql .= " v.rowid,";
$sql .= " v.tms,";
@ -262,7 +277,7 @@ class PaymentVarious extends CommonObject
$sql .= " v.fk_typepayment,";
$sql .= " v.num_payment,";
$sql .= " v.label,";
$sql .= " v.note,";
$sql .= " v.note as note_private,";
$sql .= " v.accountancy_code,";
$sql .= " v.subledger_account,";
$sql .= " v.fk_projet as fk_project,";
@ -271,7 +286,8 @@ class PaymentVarious extends CommonObject
$sql .= " v.fk_user_modif,";
$sql .= " b.fk_account,";
$sql .= " b.fk_type,";
$sql .= " b.rappro";
$sql .= " b.rappro,";
$sql .= " b.num_releve as bank_num_releve";
$sql .= " FROM ".MAIN_DB_PREFIX."payment_various as v";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."bank as b ON v.fk_bank = b.rowid";
$sql .= " WHERE v.rowid = ".((int) $id);
@ -292,7 +308,8 @@ class PaymentVarious extends CommonObject
$this->type_payment = $obj->fk_typepayment;
$this->num_payment = $obj->num_payment;
$this->label = $obj->label;
$this->note = $obj->note;
$this->note = $obj->note_private; // For backward compatibility
$this->note_private = $obj->note_private;
$this->subledger_account = $obj->subledger_account;
$this->accountancy_code = $obj->accountancy_code;
$this->fk_project = $obj->fk_project;
@ -302,6 +319,7 @@ class PaymentVarious extends CommonObject
$this->fk_account = $obj->fk_account;
$this->fk_type = $obj->fk_type;
$this->rappro = $obj->rappro;
$this->bank_num_releve = $obj->bank_num_releve;
}
$this->db->free($resql);
@ -779,6 +797,9 @@ class PaymentVarious extends CommonObject
public function getKanbanView($option = '', $arraydata = null)
{
global $langs;
$selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
$return = '<div class="box-flex-item box-flex-grow-zero">';
$return .= '<div class="info-box info-box-sm">';
$return .= '<span class="info-box-icon bg-infobox-action">';
@ -786,6 +807,7 @@ class PaymentVarious extends CommonObject
$return .= '</span>';
$return .= '<div class="info-box-content">';
$return .= '<span class="info-box-ref">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).'</span>';
$return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
if (property_exists($this, 'fk_bank')) {
$return .= ' | <span class="info-box-status ">'.$this->fk_bank.'</span>';
}
@ -806,4 +828,36 @@ class PaymentVarious extends CommonObject
$return .= '</div>';
return $return;
}
/**
* Return General accounting account with defined length (used for product and miscellaneous)
*
* @param string $account General accounting account
* @return string String with defined length
*/
public function lengthAccountg($account)
{
include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
/*
if (isModEnabled('accounting')) {
$accountingaccount = new AccountingAccount($db);
$accountingaccount->fetch('', $valuetoshow, 1);
}*/
return length_accountg($account);
}
/**
* Return Auxiliary accounting account of thirdparties with defined length
*
* @param string $account Auxiliary accounting account
* @return string String with defined length
*/
public function lengthAccounta($account)
{
include_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
return length_accounta($account);
}
}

View File

@ -6,6 +6,8 @@
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2018-2021 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2023 Maxime Nicolas <maxime@oarces.com>
* Copyright (C) 2023 Benjamin GREMBI <benjamin@oarces.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
@ -35,7 +37,6 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
// Load translation files required by the page
$langs->loadLangs(array('banks', 'categories', 'multicurrency'));
$socid = 0;
if ($user->socid > 0) {
$socid = $user->socid;
@ -45,10 +46,11 @@ if (!$user->rights->banque->transfer) {
}
$action = GETPOST('action', 'aZ09');
$error = 0;
$hookmanager->initHooks(array('banktransfer'));
$MAXLINES = 10;
/*
* Actions
@ -60,123 +62,152 @@ if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
}
if ($action == 'add') {
$langs->load("errors");
$langs->load('errors');
$i = 1;
$dateo = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
$label = GETPOST('label', 'alpha');
$amount = price2num(GETPOST('amount', 'alpha'), 'MT', 2);
$amountto = price2num(GETPOST('amountto', 'alpha'), 'MT', 2);
while ($i < $MAXLINES) {
$dateo[$i] = dol_mktime(12, 0, 0, GETPOST($i.'_month', 'int'), GETPOST($i.'_day', 'int'), GETPOST($i.'_year', 'int'));
$label[$i] = GETPOST($i.'_label', 'alpha');
$amount[$i] = intval(price2num(GETPOST($i.'_amount', 'alpha'), 'MT', 2));
$amountto[$i] = price2num(GETPOST($i.'_amountto', 'alpha'), 'MT', 2);
$accountfrom[$i] = intval(GETPOST($i.'_account_from', 'int'));
$accountto[$i] = intval(GETPOST($i.'_account_to', 'int'));
$type[$i] = GETPOST($i.'_type', 'int');
$errori[$i] = 0;
if (!$label) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Description")), null, 'errors');
$tabnum[$i] = 0;
if (!empty($label[$i]) || !empty($type[$i]) || !($amount[$i] <= 0) || !($accountfrom[$i] < 0) || !($accountto[$i] < 0)) {
$tabnum[$i] = 1;
}
$i++;
}
if (!$amount) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Amount")), null, 'errors');
}
if (!GETPOST('account_from', 'int')) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("TransferFrom")), null, 'errors');
}
if (!GETPOST('account_to', 'int')) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("TransferTo")), null, 'errors');
}
if (!$error) {
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
$accountfrom = new Account($db);
$accountfrom->fetch(GETPOST('account_from', 'int'));
$n = 1;
while ($n < $MAXLINES) {
if ($tabnum[$n] === 1) {
if ($accountfrom[$n] < 0) {
$errori[$n]++;
setEventMessages($langs->trans("ErrorFieldRequired", '#'.$n. ' ' .$langs->transnoentities("TransferFrom")), null, 'errors');
}
if ($accountto[$n] < 0) {
$errori[$n]++;
setEventMessages($langs->trans("ErrorFieldRequired", '#'.$n. ' ' .$langs->transnoentities("TransferTo")), null, 'errors');
}
if (!$type[$n]) {
$errori[$n]++;
setEventMessages($langs->trans("ErrorFieldRequired", '#'.$n. ' ' .$langs->transnoentities("Type")), null, 'errors');
}
if (!$dateo[$n]) {
$errori[$n]++;
setEventMessages($langs->trans("ErrorFieldRequired", '#'.$n. ' ' .$langs->transnoentities("Date")), null, 'errors');
}
$accountto = new Account($db);
$accountto->fetch(GETPOST('account_to', 'int'));
if (!($label[$n])) {
$errori[$n]++;
setEventMessages($langs->trans("ErrorFieldRequired", '#'.$n. ' ' . $langs->transnoentities("Description")), null, 'errors');
}
if (!($amount[$n])) {
$errori[$n]++;
setEventMessages($langs->trans("ErrorFieldRequired", '#'.$n. ' ' .$langs->transnoentities("Amount")), null, 'errors');
}
if ($accountto->currency_code == $accountfrom->currency_code) {
$amountto = $amount;
} else {
if (!$amountto) {
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AmountTo")), null, 'errors');
}
}
if ($amountto < 0) {
$error++;
setEventMessages($langs->trans("AmountMustBePositive"), null, 'errors');
}
if ($accountto->id == $accountfrom->id) {
$error++;
setEventMessages($langs->trans("ErrorFromToAccountsMustDiffers"), null, 'errors');
}
if (empty($error)) {
$db->begin();
$bank_line_id_from = 0;
$bank_line_id_to = 0;
$result = 0;
// By default, electronic transfert from bank to bank
$typefrom = 'PRE';
$typeto = 'VIR';
if ($accountto->courant == Account::TYPE_CASH || $accountfrom->courant == Account::TYPE_CASH) {
// This is transfer of change
$typefrom = 'LIQ';
$typeto = 'LIQ';
}
if (!$error) {
$bank_line_id_from = $accountfrom->addline($dateo, $typefrom, $label, price2num(-1 * $amount), '', '', $user);
}
if (!($bank_line_id_from > 0)) {
$error++;
}
if (!$error) {
$bank_line_id_to = $accountto->addline($dateo, $typeto, $label, $amountto, '', '', $user);
}
if (!($bank_line_id_to > 0)) {
$error++;
}
if (!$error) {
$result = $accountfrom->add_url_line($bank_line_id_from, $bank_line_id_to, DOL_URL_ROOT.'/compta/bank/line.php?rowid=', '(banktransfert)', 'banktransfert');
}
if (!($result > 0)) {
$error++;
}
if (!$error) {
$result = $accountto->add_url_line($bank_line_id_to, $bank_line_id_from, DOL_URL_ROOT.'/compta/bank/line.php?rowid=', '(banktransfert)', 'banktransfert');
}
if (!($result > 0)) {
$error++;
}
if (!$error) {
$mesgs = $langs->trans("TransferFromToDone", '{s1}', '{s2}', $amount, $langs->transnoentitiesnoconv("Currency".$conf->currency));
$mesgs = str_replace('{s1}', '<a href="bankentries_list.php?id='.$accountfrom->id.'&sortfield=b.datev,b.dateo,b.rowid&sortorder=desc">'.$accountfrom->label.'</a>', $mesgs);
$mesgs = str_replace('{s2}', '<a href="bankentries_list.php?id='.$accountto->id.'">'.$accountto->label.'</a>', $mesgs);
setEventMessages($mesgs, null, 'mesgs');
$db->commit();
} else {
setEventMessages($accountfrom->error.' '.$accountto->error, null, 'errors');
$db->rollback();
if (!$errori[$n]) {
require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
$accountfrom = new Account($db);
$accountfrom->fetch(GETPOST($n.'_account_from', 'int'));
$accountto = new Account($db);
$accountto->fetch(GETPOST($n.'_account_to', 'int'));
if ($accountto->currency_code == $accountfrom->currency_code) {
$amountto[$n] = $amount[$n];
} else {
if (!$amountto[$n]) {
$error[$n]++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("AmountTo")).' #'.$n, null, 'errors');
}
}
if ($amountto[$n] < 0) {
$errori[$n]++;
setEventMessages($langs->trans("AmountMustBePositive").' #'.$n, null, 'errors');
}
if ($accountto->id == $accountfrom->id) {
$errori[$n]++;
setEventMessages($langs->trans("ErrorFromToAccountsMustDiffers").' #'.$n, null, 'errors');
}
}
if ($errori[$n] == 0) {
$db->begin();
$bank_line_id_from = 0;
$bank_line_id_to = 0;
$result = 0;
// By default, electronic transfert from bank to bank
$typefrom = $type[$n];
$typeto = $type[$n];
if ($accountto->courant == Account::TYPE_CASH || $accountfrom->courant == Account::TYPE_CASH) {
// This is transfer of change
$typefrom = 'LIQ';
$typeto = 'LIQ';
}
if (!$errori[$n]) {
$bank_line_id_from = $accountfrom->addline($dateo[$n], $typefrom, $label[$n], price2num(-1 * $amount[$n]), '', '', $user);
}
if (!($bank_line_id_from > 0)) {
$errori[$n]++;
}
if (!$errori[$n]) {
$bank_line_id_to = $accountto->addline($dateo[$n], $typeto, $label[$n], $amountto[$n], '', '', $user);
}
if (!($bank_line_id_to > 0)) {
$errori[$n]++;
}
if (!$errori[$n]) {
$result = $accountfrom->add_url_line($bank_line_id_from, $bank_line_id_to, DOL_URL_ROOT.'/compta/bank/line.php?rowid=', '(banktransfert)', 'banktransfert');
}
if (!($result > 0)) {
$errori++;
}
if (!$errori[$n]) {
$result = $accountto->add_url_line($bank_line_id_to, $bank_line_id_from, DOL_URL_ROOT.'/compta/bank/line.php?rowid=', '(banktransfert)', 'banktransfert');
}
if (!($result > 0)) {
$errori[$n]++;
}
if (!$errori[$n]) {
$mesgs = $langs->trans("TransferFromToDone", '{s1}', '{s2}', $amount[$n], $langs->transnoentitiesnoconv("Currency".$conf->currency));
$mesgs = str_replace('{s1}', '<a href="bankentries_list.php?id='.$accountfrom->id.'&sortfield=b.datev,b.dateo,b.rowid&sortorder=desc">'.$accountfrom->label.'</a>', $mesgs);
$mesgs = str_replace('{s2}', '<a href="bankentries_list.php?id='.$accountto->id.'">'.$accountto->label.'</a>', $mesgs);
setEventMessages($mesgs, null, 'mesgs');
$db->commit();
} else {
setEventMessages($accountfrom->error.' '.$accountto->error, null, 'errors');
$db->rollback();
}
}
}
$n++;
}
}
/*
* View
*/
$form = new Form($db);
$help_url = 'EN:Module_Banks_and_Cash|FR:Module_Banques_et_Caisses|ES:M&oacute;dulo_Bancos_y_Cajas';
$title = $langs->trans('MenuBankInternalTransfer');
llxHeader('', $title, $help_url);
print ' <script type="text/javascript">
$(document).ready(function () {
$(".selectbankaccount").change(function() {
@ -191,6 +222,13 @@ print ' <script type="text/javascript">
var currencycode1="";
var currencycode2="";
$("select").each(function() {
if( $(this).attr("view")){
$(this).closest("tr").removeClass("hidejs").removeClass("hideobject");
}
});
$.get("'.DOL_URL_ROOT.'/core/ajax/getaccountcurrency.php", {id: account1})
.done(function( data ) {
if (data != null)
@ -238,63 +276,104 @@ print ' <script type="text/javascript">
});
</script>';
$form = new Form($db);
$account_from = '';
$account_to = '';
$label = '';
$amount = '';
$amountto = '';
if ($error) {
$account_from = GETPOST('account_from', 'int');
$account_to = GETPOST('account_to', 'int');
$label = GETPOST('label', 'alpha');
$amount = GETPOST('amount', 'alpha');
}
print load_fiche_titre($langs->trans("MenuBankInternalTransfer"), '', 'bank_account');
print '<span class="opacitymedium">'.$langs->trans("TransferDesc").'</span>';
print "<br><br>";
print '<br><br>';
print '<form name="add" method="post" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="add">';
print '<div>';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<table id="tablemouvbank" class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("TransferFrom").'</td><td>'.$langs->trans("TransferTo").'</td><td>'.$langs->trans("Date").'</td><td>'.$langs->trans("Description").'</td>';
print '<td class="right">'.$langs->trans("Amount").'</td>';
print '<td style="display:none" class="multicurrency">'.$langs->trans("AmountToOthercurrency").'</td>';
print '<th>'.$langs->trans("TransferFrom").'</th>';
print '<th>'.$langs->trans("TransferTo").'</th>';
print '<th>'.$langs->trans("Type").'</th>';
print '<th>'.$langs->trans("Date").'</th>';
print '<th>'.$langs->trans("Description").'</th>';
print '<th class="right">'.$langs->trans("Amount").'</th>';
//print '<td class="hideobject" class="multicurrency">'.$langs->trans("AmountToOthercurrency").'</td>';
print '</tr>';
print '<tr class="oddeven"><td>';
print img_picto('', 'bank_account', 'class="paddingright"');
$form->select_comptes($account_from, 'account_from', 0, '', 1, '', !isModEnabled('multicurrency') ? 0 : 1);
print "</td>";
for ($i = 1 ; $i < $MAXLINES; $i++) {
$label = '';
$amount = '';
print "<td>\n";
print img_picto('', 'bank_account', 'class="paddingright"');
$form->select_comptes($account_to, 'account_to', 0, '', 1, '', !isModEnabled('multicurrency') ? 0 : 1);
print "</td>\n";
if ($errori[$i]) {
$label = GETPOST($i.'_label', 'alpha');
$amount = GETPOST($i.'_amount', 'alpha');
}
print "<td>";
print $form->selectDate((!empty($dateo) ? $dateo : ''), '', '', '', '', 'add');
print "</td>\n";
print '<td><input name="label" class="flat quatrevingtpercent" type="text" value="'.dol_escape_htmltag($label).'"></td>';
print '<td class="right"><input name="amount" class="flat right" type="text" size="6" value="'.dol_escape_htmltag($amount).'"></td>';
print '<td style="display:none" class="multicurrency"><input name="amountto" class="flat" type="text" size="6" value="'.dol_escape_htmltag($amountto).'"></td>';
if ($i == 1) {
$classi = 'numvir number'. $i;
$classi .= ' active';
} else {
$classi = 'numvir number'. $i;
$classi .= ' hidejs hideobject';
}
print "</table>";
print '<tr class="oddeven nowraponall '.$classi.'"><td>';
print img_picto('', 'bank_account', 'class="paddingright"');
$form->select_comptes(($errori[$i] ? GETPOST($i.'_account_from', 'int') : ''), $i.'_account_from', 0, '', 1, ($errori[$i] ? 'view=view' : ''), isModEnabled('multicurrency') ? 1 : 0, 'minwidth100');
print '</td>';
print '<td class="nowraponall">';
print img_picto('', 'bank_account', 'class="paddingright"');
$form->select_comptes(($errori[$i] ? GETPOST($i.'_account_to', 'int') : ''), $i.'_account_to', 0, '', 1, ($errori[$i] ? 'view=view' : ''), isModEnabled('multicurrency') ? 1 : 0, 'minwidth100');
print "</td>\n";
// Payment mode
print '<td class="nowraponall">';
$idpaymentmodetransfer = dol_getIdFromCode($db, 'VIR', 'c_paiement');
$form->select_types_paiements(($errori[$i] ? GETPOST($i.'_type', 'aZ09') : $idpaymentmodetransfer), $i.'_type', '', 0, 1, 0, 0, 1, 'minwidth100');
print "</td>\n";
// Date
print '<td class="nowraponall">';
print $form->selectDate((!empty($dateo[$i]) ? $dateo[$i] : ''), $i.'_', '', '', '', 'add');
print "</td>\n";
print '<td><input name="'.$i.'_label" class="flat quatrevingtpercent selectjs" type="text" value="'.dol_escape_htmltag($label).'"></td>';
print '<td class="right"><input name="'.$i.'_amount" class="flat right selectjs" type="text" size="6" value="'.dol_escape_htmltag($amount).'"></td>';
print '<td class="hideobject" class="multicurrency"><input name="'.$i.'_amountto" class="flat" type="text" size="6" value="'.dol_escape_htmltag($amountto).'"></td>';
print '</tr>';
}
print '</table>';
print '</div>';
print '</div>';
print '<div id="btncont" style="display: flex; align-items: center">';
print '<a id="btnincrement" style="margin-left:35%" class="btnTitle btnTitlePlus" onclick="increment()" title="Ajouter écriture">
<span class="fa fa-plus-circle valignmiddle btnTitle-icon">
</span>
</a>';
print '<br><div class=""><input type="submit" class="button" value="'.$langs->trans("Save").'"></div>';
print '</div>';
print '<br><div class="center"><input type="submit" class="button" value="'.$langs->trans("Create").'"></div>';
print '</form>';
print "</form>";
print ' <script type="text/javascript">
function increment(){
$(".numvir").nextAll(".hidejs:first").removeClass("hidejs").removeClass("hideobject").addClass("active").show();
};
$(".number1").on("click",(function() {
console.log("We click on number1");
$(".hidejs").each(function (){$(this).hide()});
$("#btncont").show();
}))
</script>
';
// End of page
llxFooter();
$db->close();

View File

@ -1,6 +1,7 @@
<?php
/* Copyright (C) 2017-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2018-2020 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2023 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
@ -71,6 +72,8 @@ $object = new PaymentVarious($db);
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('variouscard', 'globalcard'));
$permissiontoadd = $user->hasRight('banque', 'modifier');
/**
* Actions
@ -83,14 +86,8 @@ if ($reshook < 0) {
}
if (empty($reshook)) {
// Link to a project
if ($action == 'classin' && $user->rights->banque->modifier) {
$object->fetch($id);
$object->setProject(GETPOST('projectid'));
}
if ($cancel) {
if ($action != 'addlink') {
if ($action != 'addlink' && $action != 'setaccountancy_code' && $action != 'setsubledger_account') {
$urltogo = $backtopage ? $backtopage : dol_buildpath('/compta/bank/various_payment/list.php', 1);
header("Location: ".$urltogo);
exit;
@ -101,6 +98,12 @@ if (empty($reshook)) {
$action = '';
}
// Link to a project
if ($action == 'classin' && $permissiontoadd) {
$object->fetch($id);
$object->setProject(GETPOST('projectid', 'int'));
}
if ($action == 'add') {
$error = 0;
@ -214,6 +217,22 @@ if (empty($reshook)) {
}
}
if ($action == 'setaccountancy_code') {
$db->begin();
$result = $object->fetch($id);
$object->accountancy_code = GETPOST('accountancy_code', 'alpha');
$res = $object->update($user);
if ($res > 0) {
$db->commit();
} else {
$db->rollback();
setEventMessages($object->error, $object->errors, 'errors');
}
}
if ($action == 'setsubledger_account') {
$db->begin();
@ -236,7 +255,7 @@ if ($action == 'confirm_clone' && $confirm != 'yes') {
$action = '';
}
if ($action == 'confirm_clone' && $confirm == 'yes' && ($user->rights->banque->modifier)) {
if ($action == 'confirm_clone' && $confirm == 'yes' && $permissiontoadd) {
$db->begin();
$originalId = $id;
@ -560,32 +579,25 @@ if ($id) {
// Project
if (isModEnabled('project')) {
$langs->load("projects");
$morehtmlref .= $langs->trans('Project').' ';
if ($user->rights->banque->modifier) {
//$morehtmlref .= '<br>';
if ($permissiontoadd) {
$morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
if ($action != 'classify') {
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> : ';
}
if ($action == 'classify') {
//$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
$morehtmlref .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
$morehtmlref .= '<input type="hidden" name="action" value="classin">';
$morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
$morehtmlref .= $formproject->select_projects(0, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1);
$morehtmlref .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
$morehtmlref .= '</form>';
} else {
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300');
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
}
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
} else {
if (!empty($object->fk_project)) {
$proj = new Project($db);
$proj->fetch($object->fk_project);
$morehtmlref .= $proj->getNomUrl(1);
} else {
$morehtmlref .= '';
if ($proj->title) {
$morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
}
}
}
}
$morehtmlref .= '</div>';
$linkback = '<a href="'.DOL_URL_ROOT.'/compta/bank/various_payment/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
@ -622,39 +634,48 @@ if ($id) {
print '<tr><td>'.$langs->trans("Amount").'</td><td><span class="amount">'.price($object->amount, 0, $langs, 1, -1, -1, $conf->currency).'</span></td></tr>';
// Accountancy code
print '<tr><td class="nowrap">';
print $langs->trans("AccountAccounting");
print '</td><td>';
// Account of Chart of account
$editvalue = '';
if (isModEnabled('accounting')) {
$accountingaccount = new AccountingAccount($db);
$accountingaccount->fetch('', $object->accountancy_code, 1);
print $accountingaccount->getNomUrl(0, 1, 1, '', 1);
} else {
print $object->accountancy_code;
$editvalue = $formaccounting->select_account($object->accountancy_code, 'accountancy_code', 1, null, 1, 1);
}
print '</td></tr>';
print '<tr><td class="nowrap">';
print $form->editfieldkey('AccountAccounting', 'accountancy_code', $object->accountancy_code, $object, (!$alreadyaccounted && $permissiontoadd), 'string', '', 0);
print '</td><td>';
print $form->editfieldval('AccountAccounting', 'accountancy_code', $object->accountancy_code, $object, (!$alreadyaccounted && $permissiontoadd), 'asis', $editvalue, 0, null, '', 1, 'lengthAccountg');
print '</td></tr>';
// Subledger account
print '<tr><td class="nowrap">';
print $form->editfieldkey('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'string', '', 0);
print $form->editfieldkey('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $permissiontoadd), 'string', '', 0);
print '</td><td>';
print $form->editfieldval('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $user->rights->banque->modifier), 'string', '', 0);
print $form->editfieldval('SubledgerAccount', 'subledger_account', $object->subledger_account, $object, (!$alreadyaccounted && $permissiontoadd), 'string', '', 0, null, '', 1, 'lengthAccounta');
print '</td></tr>';
if (isModEnabled("banque")) {
if ($object->fk_account > 0) {
$bankline = new AccountLine($db);
$bankline->fetch($object->fk_bank);
$bankaccountnotfound = 0;
print '<tr>';
print '<td>'.$langs->trans('BankTransactionLine').'</td>';
print '<td colspan="3">';
print $bankline->getNomUrl(1, 0, 'showall');
print '</td>';
print '</tr>';
if (isModEnabled('banque')) {
print '<tr>';
print '<td>'.$langs->trans('BankTransactionLine').'</td>';
print '<td colspan="3">';
if ($object->fk_bank > 0) {
$bankline = new AccountLine($db);
$result = $bankline->fetch($object->fk_bank);
if ($result <= 0) {
$bankaccountnotfound = 1;
} else {
print $bankline->getNomUrl(1, 0, 'showall');
}
} else {
$bankaccountnotfound = 1;
print '<span class="opacitymedium">'.$langs->trans("NoRecordfound").'</span>';
}
print '</td>';
print '</tr>';
}
// Other attributes
@ -679,13 +700,13 @@ if ($id) {
// Add button modify
// Clone
if ($user->rights->banque->modifier) {
if ($permissiontoadd) {
print '<div class="inline-block divButAction"><a class="butAction" href="'.dol_buildpath("/compta/bank/various_payment/card.php", 1).'?id='.$object->id.'&amp;action=clone">'.$langs->trans("ToClone")."</a></div>";
}
// Delete
if (empty($object->rappro)) {
if (!empty($user->rights->banque->modifier)) {
if (empty($object->rappro) || $bankaccountnotfound) {
if ($permissiontoadd) {
if ($alreadyaccounted) {
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("Accounted").'">'.$langs->trans("Delete").'</a></div>';
} else {

View File

@ -100,7 +100,6 @@ if ($object->id) {
// Project
if (isModEnabled('project')) {
$langs->load("projects");
$morehtmlref .= $langs->trans('Project').' : ';
if ($user->rights->banque->modifier && 0) {
if ($action != 'classify') {
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> : ';

View File

@ -60,7 +60,6 @@ $morehtmlref = '<div class="refidno">';
// Project
if (isModEnabled('project')) {
$langs->load("projects");
$morehtmlref .= $langs->trans('Project').' : ';
if ($user->rights->banque->modifier && 0) {
if ($action != 'classify') {
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> : ';

View File

@ -178,8 +178,8 @@ if (empty($reshook)) {
// Mass actions
$objectclass = 'CashControl';
$objectlabel = 'CashControl';
//$uploaddir = '';
//include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
$uploaddir = $conf->bank->dir_output;
include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php';
}
@ -211,7 +211,7 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) {
// Add fields from hooks
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
$sql .= $hookmanager->resPrint;
$sql = preg_replace('/,\s*$/', '', $sql);
$sqlfields = $sql; // $sql fields to remove for count total
@ -376,15 +376,9 @@ $reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters,
$param .= $hookmanager->resPrint;
// List of mass actions available
$arrayofmassactions = array(
//'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
//'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
);
//if ($permissiontodelete) {
// $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
//}
if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) {
$arrayofmassactions = array();
$arrayofmassactions = array();
if (!empty($permissiontodelete)) {
$arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
}
$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
@ -585,7 +579,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) {
$object->cheque = $obj->cheque;
print $object->getKanbanView('');
print $object->getKanbanView('', array('selected' => in_array($object->id, $arrayofselected)));
if ($i == (min($num, $limit) - 1)) {
print '</div>';
print '</td></tr>';

View File

@ -480,6 +480,9 @@ class CashControl extends CommonObject
public function getKanbanView($option = '', $arraydata = null)
{
global $langs;
$selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
$return = '<div class="box-flex-item box-flex-grow-zero">';
$return .= '<div class="info-box info-box-sm">';
$return .= '<span class="info-box-icon bg-infobox-action">';
@ -488,6 +491,7 @@ class CashControl extends CommonObject
$return .= '</span>';
$return .= '<div class="info-box-content">';
$return .= '<span class="info-box-ref">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1, 1) : $this->ref).'</span>';
$return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
if (property_exists($this, 'posmodule')) {
$return .= '<br><span class="opacitymedium">'.substr($langs->trans("Module/Application"), 0, 12).'</span> : <span class="info-box-label">'.$this->posmodule.'</span>';
}

View File

@ -0,0 +1,256 @@
<?php
/* Copyright (C) 2023 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
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/compta/facture/agenda.php
* \ingroup facture
* \brief Tab of events on Invoices
*/
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
// Load translation files required by the page
$langs->loadLangs(array("bills", "other"));
// Get parameters
$id = GETPOST('id', 'int');
$ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'aZ09');
$cancel = GETPOST('cancel', 'aZ09');
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
$backtopage = GETPOST('backtopage', 'alpha');
if (GETPOST('actioncode', 'array')) {
$actioncode = GETPOST('actioncode', 'array', 3);
if (!count($actioncode)) {
$actioncode = '0';
}
} else {
$actioncode = GETPOST("actioncode", "alpha", 3) ? GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : getDolGlobalString('AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT'));
}
$search_rowid = GETPOST('search_rowid');
$search_agenda_label = GETPOST('search_agenda_label');
$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 == -1) {
$page = 0;
} // If $page is not defined, or '' or -1
$offset = $limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;
if (!$sortfield) {
$sortfield = 'a.datep,a.id';
}
if (!$sortorder) {
$sortorder = 'DESC,DESC';
}
// Initialize technical objects
$object = new Facture($db);
$extrafields = new ExtraFields($db);
$diroutputmassaction = $conf->facture->multidir_output[$conf->entity].'/temp/massgeneration/'.$user->id;
$hookmanager->initHooks(array('invoiceagenda', 'globalcard')); // Note that conf->hooks_modules contains array
// Fetch optionals attributes and labels
$extrafields->fetch_name_optionals_label($object->table_element);
// Load object
include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals
if ($id > 0 || !empty($ref)) {
$upload_dir = $conf->facture->multidir_output[!empty($object->entity) ? $object->entity : $conf->entity]."/".$object->id;
}
$permissiontoread = $user->hasRight("facture", "lire");
$permissiontoadd = $user->hasRight("facture", "creer");
// Security check
if (!empty($user->socid)) {
$socid = $user->socid;
}
$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
restrictedArea($user, 'facture', $object->id, '', '', 'fk_soc', 'rowid', $isdraft);
/*
* Actions
*/
$parameters = array('id'=>$id);
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
}
if (empty($reshook)) {
// Cancel
if (GETPOST('cancel', 'alpha') && !empty($backtopage)) {
header("Location: ".$backtopage);
exit;
}
// Purge search criteria
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers
$actioncode = '';
$search_agenda_label = '';
}
}
/*
* View
*/
$form = new Form($db);
if ($object->id > 0) {
$title = $langs->trans("Agenda");
//if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->name." - ".$title;
$help_url = 'EN:Module_Agenda_En|DE:Modul_Terminplanung';
llxHeader('', $title, $help_url);
if (isModEnabled('notification')) {
$langs->load("mails");
}
$head = facture_prepare_head($object);
print dol_get_fiche_head($head, 'agenda', $langs->trans("Invoice"), -1, $object->picto);
// Object card
// ------------------------------------------------------------
$linkback = '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
$morehtmlref = '<div class="refidno">';
// Ref customer
$morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
$morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1);
// Project
if (isModEnabled('project')) {
$langs->load("projects");
$morehtmlref .= '<br>';
if (0) {
$morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
if ($action != 'classify') {
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
}
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
} else {
if (!empty($object->fk_project)) {
$proj = new Project($db);
$proj->fetch($object->fk_project);
$morehtmlref .= $proj->getNomUrl(1);
if ($proj->title) {
$morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
}
}
}
}
$morehtmlref .= '</div>';
dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
print '<div class="fichecenter">';
print '<div class="underbanner clearboth"></div>';
$object->info($object->id);
dol_print_object_info($object, 1);
print '</div>';
print dol_get_fiche_end();
// Actions buttons
$objthirdparty = $object;
$objcon = new stdClass();
$out = '&origin='.urlencode($object->element.(property_exists($object, 'module') ? '@'.$object->module : '')).'&originid='.urlencode($object->id);
$urlbacktopage = $_SERVER['PHP_SELF'].'?id='.$object->id;
$out .= '&backtopage='.urlencode($urlbacktopage);
$permok = $user->rights->agenda->myactions->create;
if ((!empty($objthirdparty->id) || !empty($objcon->id)) && $permok) {
//$out.='<a href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create';
if (get_class($objthirdparty) == 'Societe') {
$out .= '&socid='.urlencode($objthirdparty->id);
}
$out .= (!empty($objcon->id) ? '&contactid='.urlencode($objcon->id) : '');
//$out.=$langs->trans("AddAnAction").' ';
//$out.=img_picto($langs->trans("AddAnAction"),'filenew');
//$out.="</a>";
}
$morehtmlright = '';
//$messagingUrl = DOL_URL_ROOT.'/societe/messaging.php?socid='.$object->id;
//$morehtmlright .= dolGetButtonTitle($langs->trans('ShowAsConversation'), '', 'fa fa-comments imgforviewmode', $messagingUrl, '', 1);
//$messagingUrl = DOL_URL_ROOT.'/societe/agenda.php?socid='.$object->id;
//$morehtmlright .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-bars imgforviewmode', $messagingUrl, '', 2);
if (isModEnabled('agenda')) {
if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')) {
$morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out);
} else {
$morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out, '', 0);
}
}
if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
print '<br>';
$param = '&id='.$object->id.(!empty($socid) ? '&socid='.$socid : '');
if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
$param .= '&contextpage='.urlencode($contextpage);
}
if ($limit > 0 && $limit != $conf->liste_limit) {
$param .= '&limit='.urlencode($limit);
}
// Try to know count of actioncomm from cache
require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
$cachekey = 'count_events_facture_'.$object->id;
$nbEvent = dol_getcache($cachekey);
print_barre_liste($langs->trans("ActionsOnBill").(is_numeric($nbEvent) ? '<span class="opacitymedium colorblack paddingleft">('.$nbEvent.')</span>': ''), 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 1);
//print_barre_liste($langs->trans("ActionsOnBill"), 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 1);
// List of all actions
$filters = array();
$filters['search_agenda_label'] = $search_agenda_label;
$filters['search_rowid'] = $search_rowid;
// TODO Replace this with same code than into list.php
show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder, property_exists($object, 'module') ? $object->module : '');
}
}
// End of page
llxFooter();
$db->close();

View File

@ -3,7 +3,7 @@
* Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2013 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2013-2023 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
* Copyright (C) 2015 Alexandre Spangaro <aspangaro@open-dsi.fr>
@ -437,6 +437,9 @@ if (empty($reshook)) {
$qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS', 2);
$remise_percent = price2num(GETPOST('remise_percent'.$predef), '', 2);
if (empty($remise_percent)) {
$remise_percent = 0;
}
// Extrafields
$extralabelsline = $extrafields->fetch_name_optionals_label($object->table_element_line);
@ -784,6 +787,9 @@ if (empty($reshook)) {
}*/
$remise_percent = price2num(GETPOST('remise_percent'), '', 2);
if (empty($remise_percent)) {
$remise_percent = 0;
}
// Check minimum price
$productid = GETPOST('productid', 'int');

View File

@ -14,7 +14,7 @@
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* Copyright (C) 2014-2019 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2015-2016 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2018-2021 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2018-2023 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
*
* This program is free software; you can redistribute it and/or modify
@ -86,6 +86,8 @@ $socid = GETPOST('socid', 'int');
$action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
$cancel = GETPOST('cancel', 'alpha');
$backtopage = GETPOST('backtopage', 'alpha');
$lineid = GETPOST('lineid', 'int');
$userid = GETPOST('userid', 'int');
$search_ref = GETPOST('sf_ref', 'alpha') ? GETPOST('sf_ref', 'alpha') : GETPOST('search_ref', 'alpha');
@ -1304,7 +1306,8 @@ if (empty($reshook)) {
$object->date_pointoftax = $date_pointoftax;
$object->note_public = trim(GETPOST('note_public', 'restricthtml'));
$object->note_private = trim(GETPOST('note_private', 'restricthtml'));
$object->ref_client = GETPOST('ref_client');
$object->ref_customer = GETPOST('ref_client');
$object->ref_client = $object->ref_customer;
$object->model_pdf = GETPOST('model');
$object->fk_project = GETPOST('projectid', 'int');
$object->cond_reglement_id = (GETPOST('type') == 3 ? 1 : GETPOST('cond_reglement_id'));
@ -3152,6 +3155,8 @@ if ($action == 'create') {
if ($soc->id > 0) {
print '<input type="hidden" name="socid" value="'.$soc->id.'">'."\n";
}
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
print '<input name="ref" type="hidden" value="provisoire">';
print '<input name="ref_client" type="hidden" value="'.$ref_client.'">';
print '<input name="force_cond_reglement_id" type="hidden" value="0">';
@ -3200,10 +3205,10 @@ if ($action == 'create') {
} else {
print '<tr><td class="fieldrequired">'.$langs->trans('Customer').'</td>';
print '<td colspan="2">';
print img_picto('', 'company').$form->select_company($soc->id, 'socid', '((s.client = 1 OR s.client = 3) AND s.status = 1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company($soc->id, 'socid', '((s.client = 1 OR s.client = 3) AND s.status = 1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
// Option to reload page to retrieve customer informations.
if (empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED)) {
print '<script type="text/javascript">
print '<script>
$(document).ready(function() {
$("#socid").change(function() {
/*
@ -3656,19 +3661,22 @@ if ($action == 'create') {
// Date invoice
print '<tr><td class="fieldrequired">'.$langs->trans('DateInvoice').'</td><td colspan="2">';
print img_picto('', 'action', 'class="pictofixedwidth"');
print $form->selectDate($newdateinvoice ? $newdateinvoice : $dateinvoice, '', '', '', '', "add", 1, 1);
print '</td></tr>';
// Date point of tax
if (!empty($conf->global->INVOICE_POINTOFTAX_DATE)) {
print '<tr><td class="fieldrequired">'.$langs->trans('DatePointOfTax').'</td><td colspan="2">';
print img_picto('', 'action', 'class="pictofixedwidth"');
print $form->selectDate($date_pointoftax ? $date_pointoftax : -1, 'date_pointoftax', '', '', '', "add", 1, 1);
print '</td></tr>';
}
// Payment term
print '<tr><td class="nowrap fieldrequired">'.$langs->trans('PaymentConditionsShort').'</td><td colspan="2">';
print $form->getSelectConditionsPaiements(GETPOSTISSET('cond_reglement_id') ? GETPOST('cond_reglement_id', 'int') : $cond_reglement_id, 'cond_reglement_id');
print img_picto('', 'payment', 'class="pictofixedwidth"');
print $form->getSelectConditionsPaiements((GETPOSTISSET('cond_reglement_id') && GETPOST('cond_reglement_id', 'int') != 0) ? GETPOST('cond_reglement_id', 'int') : $cond_reglement_id, 'cond_reglement_id', -1, 1);
print '</td></tr>';
@ -3724,8 +3732,8 @@ if ($action == 'create') {
// Payment mode
print '<tr><td>'.$langs->trans('PaymentMode').'</td><td colspan="2">';
print img_picto('', 'payment', 'class="pictofixedwidth"');
print $form->select_types_paiements(GETPOSTISSET('mode_reglement_id') ? GETPOST('mode_reglement_id') : $mode_reglement_id, 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx', 1);
print img_picto('', 'bank', 'class="pictofixedwidth"');
print $form->select_types_paiements((GETPOSTISSET('mode_reglement_id') && GETPOST('mode_reglement_id') != 0)? GETPOST('mode_reglement_id') : $mode_reglement_id, 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx', 1);
print '</td></tr>';
// Bank Account
@ -3740,7 +3748,7 @@ if ($action == 'create') {
if (isModEnabled('project')) {
$langs->load('projects');
print '<tr><td>'.$langs->trans('Project').'</td><td colspan="2">';
print img_picto('', 'project').$formproject->select_projects(($socid > 0 ? $socid : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx');
print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects(($socid > 0 ? $socid : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx');
print ' <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.$soc->id.'&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?action=create&socid='.$soc->id.($fac_rec ? '&fac_rec='.$fac_rec : '')).'"><span class="fa fa-plus-circle valignmiddle" title="'.$langs->trans("AddProject").'"></span></a>';
print '</td></tr>';
}
@ -3756,6 +3764,7 @@ if ($action == 'create') {
$incoterm_id = (!empty($objectsrc->fk_incoterms) ? $objectsrc->fk_incoterms : $soc->fk_incoterms);
$incoterm_location = (!empty($objectsrc->location_incoterms) ? $objectsrc->location_incoterms : $soc->location_incoterms);
}
print img_picto('', 'incoterm', 'class="pictofixedwidth"');
print $form->select_incoterms($incoterm_id, $incoterm_location);
print '</td></tr>';
}
@ -4683,6 +4692,7 @@ if ($action == 'create') {
print '<form id="retained-warranty-form" method="POST" action="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'">';
print '<input type="hidden" name="action" value="setretainedwarranty">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
print '<input name="retained_warranty" type="number" step="0.01" min="0" max="100" value="'.$object->retained_warranty.'" >';
print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
print '</form>';
@ -4712,6 +4722,7 @@ if ($action == 'create') {
print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'">';
print '<input type="hidden" name="action" value="setretainedwarrantyconditions">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
$retained_warranty_fk_cond_reglement = GETPOST('retained_warranty_fk_cond_reglement', 'int');
$retained_warranty_fk_cond_reglement = !empty($retained_warranty_fk_cond_reglement) ? $retained_warranty_fk_cond_reglement : $object->retained_warranty_fk_cond_reglement;
$retained_warranty_fk_cond_reglement = !empty($retained_warranty_fk_cond_reglement) ? $retained_warranty_fk_cond_reglement : $conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID;
@ -4747,6 +4758,7 @@ if ($action == 'create') {
print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'?facid='.$object->id.'">';
print '<input type="hidden" name="action" value="setretainedwarrantydatelimit">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
print '<input name="retained_warranty_date_limit" type="date" step="1" min="'.dol_print_date($object->date, '%Y-%m-%d').'" value="'.dol_print_date($defaultDate, '%Y-%m-%d').'" >';
print '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
print '</form>';
@ -4827,6 +4839,7 @@ if ($action == 'create') {
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="setrevenuestamp">';
print '<input type="hidden" name="revenuestamp" id="revenuestamp_val" value="'.price2num($object->revenuestamp).'">';
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
print $formother->select_revenue_stamp('', 'revenuestamp_type', $mysoc->country_code);
print ' &rarr; <span id="revenuestamp_span"></span>';
print ' <input type="submit" class="button buttongen button-save" value="'.$langs->trans('Modify').'">';
@ -5366,6 +5379,7 @@ if ($action == 'create') {
print '<input type="hidden" name="token" value="'.newToken().'" />';
print '<input type="hidden" name="action" value="updatealllines" />';
print '<input type="hidden" name="id" value="'.$object->id.'" />';
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
print '<table id="tablelines_all_progress" class="noborder noshadow" width="100%">';
@ -5404,6 +5418,7 @@ if ($action == 'create') {
<input type="hidden" name="mode" value="">
<input type="hidden" name="page_y" value="">
<input type="hidden" name="id" value="' . $object->id.'">
<input type="hidden" name="backtopage" value="'.$backtopage.'">
';
if (!empty($conf->use_javascript_ajax) && $object->statut == 0) {
@ -5805,10 +5820,14 @@ if ($action == 'create') {
print '</div><div class="fichehalfright">';
$MAXEVENT = 10;
$morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/compta/facture/agenda.php?id='.$object->id);
// List of actions on element
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
$formactions = new FormActions($db);
$somethingshown = $formactions->showactions($object, 'invoice', $socid, 1);
$somethingshown = $formactions->showactions($object, 'invoice', $socid, 1, '', $MAXEVENT, '', $morehtmlcenter); // Show all action for thirdparty
print '</div></div>';
}

View File

@ -18,7 +18,7 @@
* Copyright (C) 2018-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2022 Sylvain Legrand <contact@infras.fr>
* Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
* Copyright (C) 2023 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -336,10 +336,6 @@ class Facture extends CommonInvoice
'localtax2' =>array('type'=>'double(24,8)', 'label'=>'LT2', 'enabled'=>1, 'visible'=>-1, 'position'=>120, 'isameasure'=>1),
'revenuestamp' =>array('type'=>'double(24,8)', 'label'=>'RevenueStamp', 'enabled'=>1, 'visible'=>-1, 'position'=>115, 'isameasure'=>1),
'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'AmountTTC', 'enabled'=>1, 'visible'=>1, 'position'=>130, 'isameasure'=>1),
'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>165),
'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>166),
'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>167),
'fk_user_closing' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserClosing', 'enabled'=>1, 'visible'=>-1, 'position'=>168),
'fk_facture_source' =>array('type'=>'integer', 'label'=>'SourceInvoice', 'enabled'=>1, 'visible'=>-1, 'position'=>170),
'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Project', 'enabled'=>1, 'visible'=>-1, 'position'=>175),
'fk_account' =>array('type'=>'integer', 'label'=>'Fk account', 'enabled'=>1, 'visible'=>-1, 'position'=>180),
@ -370,7 +366,11 @@ class Facture extends CommonInvoice
'module_source' =>array('type'=>'varchar(32)', 'label'=>'POSModule', 'enabled'=>1, 'visible'=>-1, 'position'=>315),
'pos_source' =>array('type'=>'varchar(32)', 'label'=>'POSTerminal', 'enabled'=>1, 'visible'=>-1, 'position'=>320),
'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>500),
'tms' =>array('type'=>'timestamp', 'label'=>'DateModificationShort', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500),
'tms' =>array('type'=>'timestamp', 'label'=>'DateModificationShort', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>502),
'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>506),
'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-1, 'notnull'=>-1, 'position'=>508),
'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>510),
'fk_user_closing' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserClosing', 'enabled'=>1, 'visible'=>-1, 'position'=>512),
'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>900),
'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Paid', 3=>'Abandonned')),
);
@ -1733,12 +1733,6 @@ class Facture extends CommonInvoice
}
}
if (! is_object($hookmanager)) {
require_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php';
$hookmanager = new HookManager($origin->db);
}
$hookmanager->initHooks(array('invoicedao'));
$parameters = array('objFrom' => $origin);
@ -2695,7 +2689,7 @@ class Facture extends CommonInvoice
return -5;
}
$sql = 'UPDATE '.MAIN_DB_PREFIX.'projet_task_time';
$sql = 'UPDATE '.MAIN_DB_PREFIX.'element_time';
$sql .= ' SET invoice_id = NULL, invoice_line_id = NULL';
$sql .= ' WHERE invoice_id = '.((int) $rowid);
@ -3584,6 +3578,7 @@ class Facture extends CommonInvoice
/**
* Add an invoice line into database (linked to product/service or not).
* Note: ->thirdparty must be defined.
* Les parametres sont deja cense etre juste et avec valeurs finales a l'appel
* de cette methode. Aussi, pour le taux tva, il doit deja avoir ete defini
* par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,produit)
@ -4230,19 +4225,6 @@ class Facture extends CommonInvoice
$this->db->begin();
// Free discount linked to invoice line
$sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
$sql .= ' SET fk_facture_line = NULL';
$sql .= ' WHERE fk_facture_line = '.((int) $rowid);
dol_syslog(get_class($this)."::deleteline", LOG_DEBUG);
$result = $this->db->query($sql);
if (!$result) {
$this->error = $this->db->error();
$this->db->rollback();
return -1;
}
// Memorize previous line for triggers
$staticline = clone $line;
$line->oldline = $staticline;
@ -5674,7 +5656,7 @@ class Facture extends CommonInvoice
$actioncomm->contact_id = 0;
$actioncomm->code = 'AC_EMAIL';
$actioncomm->label = 'sendEmailsRemindersOnInvoiceDueDateOK';
$actioncomm->label = 'sendEmailsRemindersOnInvoiceDueDateOK (nbdays='.$nbdays.' paymentmode='.$paymentmode.' template='.$template.' forcerecipient='.$forcerecipient.')';
$actioncomm->note_private = $sendContent;
$actioncomm->fk_project = $tmpinvoice->fk_project;
$actioncomm->datep = dol_now();
@ -5684,6 +5666,7 @@ class Facture extends CommonInvoice
$actioncomm->userownerid = $user->id; // Owner of action
// Fields when action is an email (content should be added into note)
$actioncomm->email_msgid = $cMailFile->msgid;
$actioncomm->email_subject = $sendTopic;
$actioncomm->email_from = $from;
$actioncomm->email_sender = '';
$actioncomm->email_to = $to;
@ -5811,6 +5794,8 @@ class Facture extends CommonInvoice
*/
public function getKanbanView($option = '', $arraydata = null)
{
$selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
$return = '<div class="box-flex-item box-flex-grow-zero">';
$return .= '<div class="info-box info-box-sm">';
$return .= '<span class="info-box-icon bg-infobox-action">';
@ -5819,6 +5804,7 @@ class Facture extends CommonInvoice
$return .= '</span>';
$return .= '<div class="info-box-content">';
$return .= '<span class="info-box-ref">'.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).'</span>';
$return .= '<input id="cb'.$this->id.'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->id.'"'.($selected ? ' checked="checked"' : '').'>';
if (property_exists($this, 'socid')) {
$return .= '<br><span class="info-box-label">'.$this->socid.'</span>';
}
@ -6441,13 +6427,38 @@ class FactureLigne extends CommonInvoiceLine
return -1;
}
$sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet WHERE rowid = ".((int) $this->rowid);
// Free discount linked to invoice line
$sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except';
$sql .= ' SET fk_facture_line = NULL';
$sql .= ' WHERE fk_facture_line = '.((int) $this->id);
dol_syslog(get_class($this)."::deleteline", LOG_DEBUG);
$result = $this->db->query($sql);
if (!$result) {
$this->error = $this->db->error();
$this->errors[] = $this->error;
$this->db->rollback();
return -1;
}
$sql = 'UPDATE '.MAIN_DB_PREFIX.'projet_task_time';
$sql .= ' SET invoice_id = NULL, invoice_line_id = NULL';
$sql .= ' WHERE invoice_line_id = '.((int) $this->id);
if (!$this->db->query($sql)) {
$this->error = $this->db->error()." sql=".$sql;
$this->errors[] = $this->error;
$this->db->rollback();
return -1;
}
$sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet WHERE rowid = ".((int) $this->id);
if ($this->db->query($sql)) {
$this->db->commit();
return 1;
} else {
$this->error = $this->db->error()." sql=".$sql;
$this->errors[] = $this->error;
$this->db->rollback();
return -1;
}
@ -6501,9 +6512,9 @@ class FactureLigne extends CommonInvoiceLine
* Returns situation_percent of the previous line.
* Warning: If invoice is a replacement invoice, this->fk_prev_id is id of the replaced line.
*
* @param int $invoiceid Invoice id
* @param int $invoiceid Invoice id
* @param bool $include_credit_note Include credit note or not
* @return int >= 0
* @return int >= 0
*/
public function get_prev_progress($invoiceid, $include_credit_note = true)
{

View File

@ -1,144 +0,0 @@
<?php
/* Copyright (C) 2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2005 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2017 Ferran Marcet <fmarcet@2byte.es>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/compta/facture/info.php
* \ingroup facture
* \brief Page des informations d'une facture
*/
// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php';
if (isModEnabled('project')) {
include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
}
// Load translation files required by the page
$langs->loadLangs(array('companies', 'bills'));
$id = GETPOST("facid", "int");
$ref = GETPOST("ref", 'alpha');
$object = new Facture($db);
$extrafields = new ExtraFields($db);
// Fetch optionals attributes and labels
$extrafields->fetch_name_optionals_label($object->table_element);
// Load object
if ($id > 0 || !empty($ref)) {
$ret = $object->fetch($id, $ref, '', '', (!empty($conf->global->INVOICE_USE_SITUATION) ? $conf->global->INVOICE_USE_SITUATION : 0));
}
// Security check
if ($user->socid) {
$socid = $user->socid;
}
$isdraft = (($object->statut == Facture::STATUS_DRAFT) ? 1 : 0);
$result = restrictedArea($user, 'facture', $object->id, '', '', 'fk_soc', 'rowid', $isdraft);
$usercancreate = $user->hasRight("facture", "creer");
/*
* View
*/
$form = new Form($db);
$title = $object->ref." - ".$langs->trans('Info');
$help_url = "EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes";
llxHeader('', $title, $help_url);
if (empty($object->id)) {
$langs->load('errors');
echo '<div class="error">'.$langs->trans("ErrorRecordNotFound").'</div>';
llxFooter();
exit;
}
$object->fetch_thirdparty();
$object->info($object->id);
$head = facture_prepare_head($object);
print dol_get_fiche_head($head, 'info', $langs->trans("InvoiceCustomer"), -1, 'bill');
$totalpaid = $object->getSommePaiement();
// Invoice content
$linkback = '<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
$morehtmlref = '<div class="refidno">';
// Ref customer
$morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1);
$morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1);
// Thirdparty
$morehtmlref .= '<br>'.$object->thirdparty->getNomUrl(1, 'customer');
// Project
if (isModEnabled('project')) {
$langs->load("projects");
$morehtmlref .= '<br>';
if (0) {
$morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
if ($action != 'classify') {
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
}
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
} else {
if (!empty($object->fk_project)) {
$proj = new Project($db);
$proj->fetch($object->fk_project);
$morehtmlref .= $proj->getNomUrl(1);
if ($proj->title) {
$morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
}
}
}
}
$morehtmlref .= '</div>';
$object->totalpaid = $totalpaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status
dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0);
print '<div class="fichecenter">';
print '<div class="underbanner clearboth"></div>';
print '<br>';
print '<table class="centpercent"><tr><td>';
dol_print_object_info($object);
print '</td></tr></table>';
print '</div>';
print dol_get_fiche_end();
// End of page
llxFooter();
$db->close();

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