diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 432f30f2332..00000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: Bug report -about: Create a report to help us fix something that is broken -title: '' -labels: Bug -assignees: '' - ---- - -# Instructions -*This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report.* -*Please:* -- *replace the bracket enclosed texts with meaningful information* -- *remove any unused sub-section* - - -# Bug -[*Short description*] - -## Environment -- **Version**: [*Affected Dolibarr version(s)*] -- **OS**: [*Server OS type and version*] -- **Web server**: [*Webserver type and version*] -- **PHP**: [*PHP version*] -- **Database**: [*Database type and version*] -- **URL(s)**: [*Affected URL(s)*] - -## Expected and actual behavior -[*Verbose description*] - -## Steps to reproduce the behavior -[*Verbose description*] - -## [Attached files](https://help.github.com/articles/issue-attachments) (Screenshots, screencasts, dolibarr.log, debugging informations…) -[*Files*] diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000000..d7dc3d584e3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,71 @@ +name: Bug report +description: Create a report to help us fix something that is broken +labels: ["Bug"] + +body: + - type: markdown + attributes: + value: | + This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report. + + - type: textarea + id: bug + attributes: + label: Bug + description: Please give a short description of the bug + validations: + required: true + + - type: input + id: environment-version + attributes: + label: Environment Version + description: Affected Dolibarr version(s) + + - type: input + id: environment-os + attributes: + label: Environment OS + description: Server OS type and version + + - type: input + id: environment-webserver + attributes: + label: Environment Web server + description: Webserver type and version + + - type: input + id: environment-php + attributes: + label: Environment PHP + description: PHP version + + - type: input + id: environment-database + attributes: + label: Environment Database + description: Database type and version + + - type: input + id: environment-urls + attributes: + label: Environment URL(s) + description: Affected URL(s) + + - type: textarea + id: expected-behaviour + attributes: + label: Expected and actual behavior + description: Verbose description + + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce the behavior + description: Verbose description + + - type: textarea + id: files + attributes: + label: Attached files + description: Screenshots, screencasts, dolibarr.log, debugging informations diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 32e2deff2c1..00000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Feature request -about: Suggest a new idea for this project -title: '' -labels: Feature request -assignees: '' - ---- - -# Instructions -*This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report.* -*Please:* -- *replace the bracket enclosed texts with meaningful information* -- *remove any unused sub-section* - - -# Feature Request -[*Short description*] - -## Use case -[*Verbose description*] - -## Suggested implementation -[*Verbose description*] - -## Suggested steps -[*List of tasks to achieve goal*] diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000000..885f3472d18 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,35 @@ +name: Feature request +description: Suggest a new idea for this project +labels: ["Feature request"] + +body: + - type: markdown + attributes: + value: | + This is a template to help you report good issues. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report. + + - type: textarea + id: feature-request + attributes: + label: Feature Request + description: Short description + validations: + required: true + + - type: textarea + id: use-case + attributes: + label: Use case + description: Verbose description + + - type: textarea + id: suggested-implementation + attributes: + label: Suggested implementation + description: Verbose description + + - type: textarea + id: suggested-steps + attributes: + label: Suggested steps + description: List of tasks to achieve goal diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 3cffed355fa..67b4b346b6c 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -18,9 +18,10 @@ filter: - dev/* - doc/* - documents/* - - htdocs/includes/* - node_modules/* - test/* + dependency_paths: + - htdocs/includes/* paths: - htdocs/* - scripts/* diff --git a/.travis.yml b/.travis.yml index 45be1a9a6ba..44d784ea091 100644 --- a/.travis.yml +++ b/.travis.yml @@ -414,6 +414,9 @@ script: php upgrade.php 14.0.0 15.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade14001500.log php upgrade2.php 14.0.0 15.0.0 > $TRAVIS_BUILD_DIR/upgrade14001500-2.log php step5.php 14.0.0 15.0.0 > $TRAVIS_BUILD_DIR/upgrade14001500-3.log + php upgrade.php 15.0.0 16.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade15001600.log + php upgrade2.php 15.0.0 16.0.0 > $TRAVIS_BUILD_DIR/upgrade15001600-2.log + php step5.php 15.0.0 16.0.0 > $TRAVIS_BUILD_DIR/upgrade15001600-3.log ls -alrt $TRAVIS_BUILD_DIR/ - | diff --git a/COPYRIGHT b/COPYRIGHT index c43d77581a7..de293e3867e 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -24,11 +24,10 @@ Component Version License GPL Compatible ------------------------------------------------------------------------------------- PHP libraries: ADOdb-Date 0.36 Modified BSD License Yes Date convertion (not into rpm package) -CKEditor 4.12.1 LGPL-2.1+ Yes Editor WYSIWYG EvalMath 1.0 BSD Yes Safe math expressions evaluation Escpos-php 2.2 MIT License Yes Thermal receipt printer library, for use with ESC/POS compatible printers GeoIP2 0.2.0 Apache License 2.0 Yes Lib to make geoip convert -Mobiledetect 2.8.34 MIT License Yes Detect mobile devices browsers +Mobiledetect 2.8.39 MIT License Yes Detect mobile devices browsers NuSoap 0.9.5 LGPL 2.1+ Yes Library to develop SOAP Web services (not into rpm and deb package) PEAR Mail_MIME 1.8.9 BSD Yes NuSoap dependency ParseDown 1.6 MIT License Yes Markdown parser @@ -48,10 +47,11 @@ TCPDF 6.3.2 LGPL-3+ Yes TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes FPDI replacement JS libraries: -Ace 1.4.8 BSD Yes JS library to get code syntaxique coloration in a textarea. -ChartJS 2.9.4 MIT License Yes JS library for graph -jQuery 3.5.1 MIT License Yes JS library -jQuery UI 1.12.1 GPL and MIT License Yes JS library plugin UI +Ace 1.4.14 BSD Yes JS library to get code syntaxique coloration in a textarea. +ChartJS 3.7.1 MIT License Yes JS library for graph +CKEditor 4.18 LGPL-2.1+ Yes Editor WYSIWYG +jQuery 3.6.0 MIT License Yes JS library +jQuery UI 1.13.1 GPL and MIT License Yes JS library plugin UI jQuery select2 4.0.13 GPL and Apache License Yes JS library plugin for sexier multiselect. Warning: 4.0.6+ create troubles without patching css jQuery blockUI 2.70.0 GPL and MIT License Yes JS library plugin blockUI (to use ajax popups) jQuery Colorpicker 1.1 MIT License Yes JS library for color picker for a defined list of colors diff --git a/ChangeLog b/ChangeLog index b67cbabafb4..37957f61c1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,203 @@ English Dolibarr ChangeLog -------------------------------------------------------------- + +***** ChangeLog for 16.0.0 compared to 15.0.0 ***** + +For users: +--------------- + +NEW: PHP 8.1 compatibility +NEW: Support for recurring purchase invoices. +NEW: #20292 Include German public holidays +NEW: Can show ZATCA QRCode on PDFs +NEW: #17123 added ExtraFields for Stock Mouvement +NEW: #20609 : new massaction to assign a sale representatives on a selection of thirdparties +NEW: #20653 edit discount pourcentage for all lines in one shot +NEW: Accept 'auto' for ref of object on import of purchase order/proposal +NEW: Accountancy - Add more filters and info on page to bind accounting accounts +NEW: Accountancy - Add subledger account when we generate a transaction with a deposit invoice +NEW: Accountancy - Add a massaction to preselect an account (customer and supplier list) +NEW: ACE Editor is restored at same cursor position after a save. +NEW: Add "addMoreActionsButtons" hook to subscription form +NEW: Add an option in GUI to show a Quick add button into top menu bar +NEW: Module Recruitment - Add a public page with all list of open job positions. +NEW: Module Recruitment - Add a tab with list of application on the jobposition file. +NEW: Add a workflow to auto link contract on a ticket +NEW: Add column date of Signature on proposal list +NEW: Add column template invoice in invoice list +NEW: Add column "Total HT" to products array on document creation card +NEW: ADD configuration for text color of button action +NEW: Add constant to hide categories in TakePos +NEW: Add constant to show category description in TakePos +NEW: Add constant to show only the products in stock in TakePos +NEW: Add entity filter in exports +NEW: Show the event block on recurring invoices #20870 +NEW: Add filter "opportunity status" on statistics of projects. +NEW: Add firstname, lastname and max number of attendees for module "Event Organization" +NEW: add margin info in proposal and order list +NEW: Add massaction "Edit Extrafield" for Product +NEW: Add more fields to detect duplicate during import of thirdparties +NEW: Add option to foce delivery on email for purchase order receipt to yes +NEW: Add param boder table for md theme +NEW: Add param color button action +NEW: Add possibility to create contract from invoice +NEW: Add possibility with constant MAIN_LOGIN_BADCHARUNAUTHORIZED to define bad character unauthorized into login name +NEW: Add private and public notes on tax files. +NEW: Add status "Obsolete" to KM articles +NEW: Add substitutions "user numbers" +NEW: Add the possibility to add sub-BOMs to BOM +NEW: allow a ticket to be automatically marked as read when created from backend. +NEW: allow cut&paste as real numeric value to excel +NEW: A public form to send a message and create a lead is available +NEW: automatically set totally received status in reception +NEW: Auto set invoice paid when adding credit not and remain to pay is 0 +NEW: Availibility dictionnary has a new column unit and number +NEW: barcode rule to insert product in takepos +NEW: Can change value of AWP during the inventory +NEW: Can enter price with tax for predefined products on purchase objects +NEW: Can filter on a thirdparty on product statistics +NEW: Can removed doc templates from setup page of thirdparty +NEW: Can set the parent company during the creation of thirdparty (action=add of societe/card.php) +NEW: Can use ! to make a search that exclude a string +NEW: Change in theme colors does not need to use the refresh button +NEW: clean values and amount in FEC import +NEW: const MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND for mailing mass action +NEW: Contact filter project list +NEW: Create contract from invoice +NEW: create third-party with contact if not found on public ticket +NEW: Default value for MAIN_SECURITY_CSRF_WITH_TOKEN is now 2 (GET are also protected agains CSRF attacks) +NEW: deposit payment terms: add field into dictionary admin page to define default percentage of deposit. +NEW: Dictionaries - add possibility to manage countries in EEC +NEW: display errors in a message box after generating documents +NEW: Display physical and virtual stock of the products when creating OF from a BOM +NEW: Display product ref in "Object link" product tab for BOM +NEW: Enhance the import. Can use 'auto' for the ref (import of orders) +NEW: Events on Proposal to Return to Draft +NEW: Page to list expense report payments +NEW: JS inventory autocalc input +NEW: language support for more emailing target selectors +NEW: leave requests: add field into type dictionary to block request if balance is negative +NEW: MAIN_MAIL_AUTOCOPY_TO can accept several email and special keys +NEW: MAIN_SEARCH_CAT_OR_BY_DEFAULT const for search by category +NEW: Mass action "Close shipments" +NEW: Module website now supports the multicompany module +NEW: More mode for THEME_TOPMENU_DISABLE_IMAGE (2, 3, ...) +NEW: Add option to move checkbox column as first column on Thirdparty list (only few screens) +NEW: Add tabs for nets Bom +NEW: on redirect of page in website module, GET parameters are kept. +NEW: optional display warning icons on ticket list +NEW: option to default check "notify tier at creation" in ticket module +NEW: option update prices on proposal cloning +NEW: payment conditions enabling semi-automatic deposit creation (Issue #18439) +NEW: possibility to consume multiple batch +NEW: Reverse movement product consumption +NEW: Send email to the supplier order contact +NEW: New permission to report time on timesheet. +NEW: SEPA XML - option to place payment Type Info at Credit transfer Transaction level +NEW: Show number of votes into the label of tab "Results" of a survey +NEW: Show product reference in Takepos +NEW: Some core tables are created only at module activation +NEW: split consumption line on MO +NEW: stock filter in reassort lists +NEW: stock limit in stock export CSV +NEW: Sub-bom are availables +NEW: Supplier order - Show ref supplier of reception in linked object block +NEW: support user_modif in order +NEW: TakePos - pagination on search results +NEW: The backup tools has an "lowmemory" option for mysqldump on large database +NEW: The 'reposition' class works on ajax constantonoff that make redirects +NEW: Thirdparty - Add rules "customer accountancy code" is mandatory to validate invoice +NEW: thumbnail field in product list +NEW: total mark rate in list +NEW: uncheck "send message" by default on a ticket when private messages has been checked +NEW: VAT Report by month - Show detail by rate and also by code +NEW: Ticket triggers: allow to automatically send messages on new tickets +NEW: Accountancy - Add hidden feature for accounting reconciliation +NEW: Can store the session into database (instead of beeing managed by PHP) + + Modules +NEW: Module Partnership Management +NEW: Experimental module Event Organization Management + + +For developers or integrators: +------------------------------ +NEW: dol_uncompress() supports more extensions (.gz, .bz2, .zstd). Only .zip was supported before. +NEW: Implement a generic method for Kaban views +NEW: Upgrade chartjs library to 3.7.1 +NEW: update rank line is possible on API for customer invoices, sales orders and supplier invoice +NEW: stripe element with more gateways +NEW: solde() function evolution to be able to get solde until a chosen date +NEW: Suggest a way to run upgrade per entities. +NEW: Support html content for multiselect component. +NEW: ModuleBuilder - Add tabs view in module builder +NEW: ModuleBuilder - More feature that can be modifed after module generation +NEW: Hook getNomUrl available everywhere in tooltip of ref links +NEW: Identification of tr is possible with by attribute data-id on some pages +NEW: Import with select boxes V2 +NEW: Can update rank of invoice, proposal and order lines with API update +NEW: Can use current entity filter on 'chkbxlst' +NEW: Creation of the function select_bom() used to display bom select list +NEW: add printFieldListWhere hook in product reassort card +NEW: Add trigger and event on completely received status change +NEW: Add utility function send backup by mail +NEW: add WordPress OAuth to save a token (not SSO) +NEW: A module can embed a sql script run at each Dolibarr upgrade +NEW: API Proposals - Add POST lines +NEW: API REST filter states by country +NEW: Add option INVOICEREC_SET_AUTOFILL_DATE_START/END +NEW: Add option MAIN_API_DEBUG to save API logs into a file +NEW: Add param to keep the robot=index meta tag on public pages +NEW: Add method hintindex() in database handlers. +NEW: add modifications for new function "$db->prefix()" +NEW: addMoreActionsButtonsList hook for button in list +NEW: Add API to get a template invoice +NEW: Standardize a lot of code. +NEW: #20736 Allow extrafields SQL filters on REST API product lookup +NEW: #19294 implement detailed timespent in task of project API +NEW: Add a protection into PHPunit to avoid to forget a var_dump +NEW: Add datem and type parameters to API to create movements +NEW: Add hidden option on contract PDF line to hide qty and price +NEW: Option MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND to send last document in mass mailing action +NEW: Add hooks: selectContactListWhere hook, selectThirdpartyListWhere hook +NEW: TakePos - add hooks complete product display +NEW: TakePos - add hooks for cart display +NEW: TakePos - add hooks to complete ajax return array +NEW: Add hook before the public ticket list +NEW: Add hook doaction in takepos invoice +NEW: Add Hook for Notif +NEW: Add hook for more buttons +NEW: Add hook printFieldListWhere in "show_contacts" function +NEW: Add hook printFieldWhere in load_state_board function +NEW: Add hooks contact tab badge and hooks parameter for avoid conflicts +NEW: Add hook selectProductsListWhere in select_produits_list function +NEW: Add hooks in commercial index +NEW: Add hooks in customers and products boxes +NEW: Add hooks in thirdparty index page +NEW: Add hooks on project task time page +NEW: Add hooks on salaries and sociales card +NEW: Add hooks select product list and select thirdparty list function +NEW: Add hook to getSellPrice function + + +Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: +* There is a new specific permission to be allowed to enter timesheets. If you use timesheet, don't forget to give the new permission (disable and + enable the module project if it is not visible). +* The default value for MAIN_SECURITY_CSRF_WITH_TOKEN has been set to 2. It means any POST and any GET request that contains the "action" or "massaction" + with a value of a sensitive action must also a valid token parameter (With previous value 1, only POST was concerned). Note: With value 3, any URL + with parameter "action" or "massaction" need the token, whatever is the value of the action. +* verifCond('stringtoevaluate') now return false when string contains a bad syntax content instead of true. +* The deprecated method thirdparty_doc_create() has been removed. You can use the generateDocument() instead. +* All triggers with a name XXX_UPDATE have been renamed with name XXX_MODIFY for code consistency purpose. +* Rename build_path_from_id_categ() into buildPathFromId() and set method to private. +* Move massaction 'confirm_createbills' from actions_massactions.inc.php to commande/list.php +* Method fetch_all_resources(), fetch_all_used(), fetch_all_available() of DolResource has been removed (they were not used by core code). +* Method fetch_all of DolResource has been renamed into fetchAll() to match naming conventions. +* The hook 'upgrade' and 'doUpgrade2" has been renamed 'doUpgradeBefore' and 'doUpgradeAfterDB'. A new trigger 'doUpgradeAfterFiles' has been introduced. + + + ***** ChangeLog for 15.0.2 compared to 15.0.1 ***** FIX: #19777 #20281 @@ -209,8 +406,9 @@ NEW: Increase size of params of actions for emailcollector NEW: Invoice list - Use complete country select field with EEC or not NEW: mass action delete, no more break if at least one object has child NEW: mass action paid on customer invoice list -NEW: massaction validate on supplier orders list -NEW: Mass action send email to all attendees of an event. +NEW: mass action validate on supplier orders list +NEW: mass action send email to all attendees of an event +NEW: mass action to switch status on sale / on purchase of a product NEW: expense reports: conf to pre-fill start/end dates with bounds of current month NEW: Option "Add a link on the PDF to make the online payment" NEW: More options to generate PDF (show Frame option, width of picture option) @@ -231,7 +429,7 @@ NEW: when multiple order linked to facture, show list into note. NEW: when we delete several objects with massaction, if somes object has child we must see which objects are concerned and nevertheless delete objects which can be deleted NEW: Editing a page in website module keep old page with name .back NEW: External backups can be downloaded from the "About info page". -NEW: Add massaction to switch status on sale / on purchase of a product. + Modules @@ -239,36 +437,49 @@ NEW: Stable module Knowledge Management NEW: Experimental module Event Organization Management NEW: Experimental module Workstations Management NEW: Development of module Partnership Management +OLD: module SimplePOS has been completely removed -> use TakePOS For developers: --------------- +API: +NEW: #18319 REST API - Shipment: Add 'close' action / endpoint / POST method. +NEW: add API /approve and /makeOrder for purchase orders +NEW: API for knowledgemanagement +NEW: API get list of legal form of business +NEW: API list of staff units +NEW: Hidden option API_DISABLE_COMPRESSION is now visible in API setup page. + +Hook: +NEW: add hook 'beforeBodyClose' +NEW: add hook 'hookGetEntity' +NEW: add hook 'menuLeftMenuItems' to filter the leftmenu items +NEW: add hook 'printUnderHeaderPDFline' on invoice PDF templates (can be used for example to add a barcode or more information on header of invoices). +NEW: add hookmanager on note pages +NEW: hook after rank update +NEW: 'printFieldListFrom' hook call on several lists + +ModuleBuilder: +NEW: add the property "copytoclipboard" in modulebuilder +NEW: Use lang selector when using a field key 'lang' in modulebuilder + +Options: +NEW: add options MAIN_IBAN_IS_NEVER_MANDATORY, MAIN_IBAN_NOT_MANDATORY, PROPAL_NOT_BILLABLE, PROPAL_REOPEN_UNSIGNED_ONLY, PROPOSAL_ARE_NOT_BILLABLE, TICKETS_MESSAGE_FORCE_MAIL + +Trigger: +NEW: add action trigger for member excluded + + NEW: Introduce method hasRight NEW: Can use textarea field into a confirm popup. NEW: Can use the result_mode of mysqli driver. Save memory for list count -NEW: #18319 REST API - Shipment: Add 'close' action / endpoint / POST method. -NEW: Add API /approve and /makeOrder for purchase orders. -NEW: add action trigger for member excluded -NEW: add option MAIN_IBAN_IS_NEVER_MANDATORY, MAIN_IBAN_NOT_MANDATORY, PROPAL_NOT_BILLABLE, PROPAL_REOPEN_UNSIGNED_ONLY, PROPOSAL_ARE_NOT_BILLABLE, TICKETS_MESSAGE_FORCE_MAIL -NEW: Add code codebar column on serial/lot structure -NEW: Add date_valid and date_approve columns in the list of supplier orders -NEW: add hook `beforeBodyClose` -NEW: Add hook hookGetEntity. -NEW: add hookmanager on note pages -NEW: add hook 'menuLeftMenuItems' to filter the leftmenu items -NEW: Add the property "copytoclipboard" in modulebuilder -NEW: api for knowledgemanagement -NEW: API get list of legal form of business -NEW: API list of staff units -NEW: hook after rank update -NEW: printFieldListFrom hook call on several lists -NEW: Use lang selector when using a field key 'lang' in modulebuilder +NEW: add code codebar column on serial/lot structure +NEW: add date_valid and date_approve columns in the list of supplier orders NEW: we need to be able to put more filters on deleteByParentField() function NEW: make it easier to set the `keyword`, `keywords` and `description` attributes of an ecm file object NEW: Experimental feature to manage user sessions in database -NEW: Hidden option API_DISABLE_COMPRESSION is now visible in API setup page. -NEW: Add hook printUnderHeaderPDFline on invoice PDF templates (can be used for example to add a barcode or more information on header of invoices). + Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: * ALL EXTERNAL MODULES THAT WERE NOT CORRECTLY DEVELOPPED WILL NOT WORK ON V15 (All modules that forgot to manage the security token field @@ -1125,7 +1336,6 @@ NEW: introduce constant FACTUREFOURN_REUSE_NOTES_ON_CREATE_FROM NEW: introducing new modal boxes in TakePOS NEW: keep TakePOS terminal when login/logout NEW: link on balance to the ledger -NEW: MAIN_EMAILCOLLECTOR_MAIL_WITHOUT_HEADER const in email collector NEW: manage errors on update extra fields in ticket card NEW: mass-actions for the event list view NEW: more filter for "View change logs" diff --git a/README.md b/README.md index 4e120a4cb91..c476f14a8cc 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Other licenses apply for some included dependencies. See [COPYRIGHT](https://git If you have low technical skills and you're looking to install Dolibarr ERP/CRM in just a few clicks, you can use one of the packaged versions: -- [DoliWamp for Windows](https://wiki.dolibarr.org/index.php/Dolibarr_for_Windows_DoliWamp) +- [DoliWamp for Windows](https://wiki.dolibarr.org/index.php/Dolibarr_for_Windows_(DoliWamp)) - [DoliDeb for Debian](https://wiki.dolibarr.org/index.php/Dolibarr_for_Ubuntu_or_Debian) - DoliRpm for Redhat, Fedora, OpenSuse, Mandriva or Mageia @@ -111,7 +111,7 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - Customers/Prospects + Contacts management - Opportunities or Leads management -- Commercial proposals management +- Commercial proposals management (online signing) - Customer Orders management - Contracts/Subscription management - Interventions management @@ -129,11 +129,11 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - Supplier Invoices/credit notes and payment management - INCOTERMS - Finance / Accounting + Finance/Accounting -- Invoices / Payments +- Invoices/Payments - Bank accounts management -- Direct debit orders management (European SEPA) +- Direct debit and Credit transfer management (European SEPA) - Accounting management - Donations management - Loan management @@ -142,14 +142,14 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) Collaboration -- Shared calendar/agenda (with ical and vcal export for third party tools integration) +- Shared calendar/agenda (with ical and vcal import/export for third party tools integration) - Projects & Tasks management - Ticket System - Surveys HR -- Employee's leave requests management +- Employee's leaves management - Expense reports - Recruitment management - Timesheets @@ -157,16 +157,14 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) ### Other application/modules - Electronic Document Management (EDM) -- Bookmarks management +- Bookmarks - Reporting - Data export/import - Barcodes -- Margin calculations - LDAP connectivity - ClickToDial integration - Mass emailing - RSS integration -- Skype integration - Social platforms linking - Payment platforms integration (PayPal, Stripe, Paybox...) - Email-Collector @@ -175,13 +173,12 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) ### Other general features -- Localization in most major languages -- Multi-Language Support +- Multi-Language Support (Localization in most major languages) - Multi-Users and groups with finely grained rights - Multi-Currency - Multi-Company (by adding of an external module) - Very user friendly and easy to use -- customizable Dashboard +- Customizable dashboards - Highly customizable: enable only the modules you need, add user personalized fields, choose your skin, several menu managers (can be used by internal users as a back-office with a particular menu, or by external users as a front-office with another one) - APIs (REST, SOAP) - Code that is easy to understand, maintain and develop (PHP with no heavy framework; trigger and hook architecture) @@ -191,8 +188,9 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - Canadian double taxes (federal/province) and other countries using cumulative VAT - Tunisian tax stamp - Argentina invoice numbering using A,B,C... + - ZATCA e-invoicing QR-Code - Compatible with [European directives](https://europa.eu/legislation_summaries/taxation/l31057_en.htm) (2006/112/CE ... 2010/45/UE) - - Compatible with European GDPR rules + - Compatible with data privacy rules (europe GDPR, ...) - ... - Flexible PDF & ODT generation for invoices, proposals, orders... - ... @@ -244,6 +242,7 @@ Follow Dolibarr project on: - [Facebook](https://www.facebook.com/dolibarr) - [Twitter](https://www.twitter.com/dolibarr) - [LinkedIn](https://www.linkedin.com/company/association-dolibarr) +- [Reddit](https://www.reddit.com/r/Dolibarr_ERP_CRM/) - [YouTube](https://www.youtube.com/user/DolibarrERPCRM) - [GitHub](https://github.com/Dolibarr/dolibarr) diff --git a/SECURITY.md b/SECURITY.md index 4e7e5fa933a..cd3156bece9 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -6,8 +6,9 @@ This file contains some policies about the security reports on Dolibarr ERP CRM | Version | Supported | | ---------- | ---------------------- | -| <= 14.0.4 | :x: | -| >= 14.0.5+ | :white_check_mark: except CSRF attacks| +| <= 15.0.0 | :x: | +| >= 15.0.1+ | :white_check_mark: except CSRF attacks| +| >= 16.0.0 | :white_check_mark: | | >= develop | :white_check_mark: | ## Reporting a Vulnerability @@ -17,7 +18,7 @@ Alternatively send an email to security@dolibarr.org (for everybody) ## Hunting vulnerabilities on Dolibarr -We believe that future of software is online SaaS. This means software are more and more critical and no technology is perfect. Working with skilled security researchers is crucial in identifying weaknesses in our technology. +We believe that the future of software is online SaaS. This means software are more and more critical and no technology is perfect. Working with skilled security researchers is crucial in identifying weaknesses in our technology. If you believe you've found a security bug in our service, we are happy to work with you to resolve the issue promptly and ensure you are fairly rewarded for your discovery. @@ -35,13 +36,13 @@ You can install the web application yourself on your own platform/server so you ## Eligibility and Responsible Disclosure -We are happy to thank everyone who submits valid reports which help us improve the security of Dolibarr however, only those that meet the following eligibility requirements will be "validated reports" (if not, we may close the report without any answer): +We are happy to thank everyone who submits valid reports which help us improve the security of Dolibarr, however only those that meet the following eligibility requirements will be "validated reports" (if not, we may close the report without any answer): You must be the first reporter of the vulnerability (duplicate reports are closed). You must send a clear textual description of the report along with steps to reproduce the issue, include attachments such as screenshots or proof of concept code as necessary. -You must avoid tests that could cause degradation or interruption of our service (refrain from using automated tools, and limit yourself about requests per second), that's why we recommand to install softwate on your own platform. +You must avoid tests that could cause degradation or interruption of our service (refrain from using automated tools, and limit yourself about requests per second), that's why we recommand to install software on your own platform. You must not leak, manipulate, or destroy any user data of third parties to find your vulnerability. @@ -56,7 +57,7 @@ ONLY vulnerabilities discovered, when the following setup on test platform is us * The module DebugBar and ModuleBuilder must NOT be enabled (by default, these modules are not enabled. They are developer tools) * ONLY security reports on modules provided by default and with the "stable" status are valid (troubles into "experimental", "developement" or external modules are not valid vulnerabilities). * The root of web server must link to htdocs and the documents directory must be outside of the web server root (this is the default when using the default installer but may differs with external installer). -* The web server setup must be done so only the documents directory is in write mode. The root directory called htdocs must be readonly. +* The web server setup must be done so that only the documents directory is in write mode. The root directory called htdocs must be read-only. * CSRF attacks are accepted but double check that you have set MAIN_SECURITY_CSRF_WITH_TOKEN to value 3. * Ability for a high level user to edit web site pages into the CMS by including HTML or Javascript is an expected feature. Vulnerabilities into the website module are validated only if HTML or Javascript injection can be done by a non allowed user. @@ -67,7 +68,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, ...) -* Cross-Site Scripting (XSS), except from setup page of module "External web site" (allowing any content here, editable by admin user only, is accepted on purpose or into module "Web site" when permission to edit website content is allowed). +* Cross-Site Scripting (XSS), except from setup page of module "External web site" (allowing any content here, editable by admin user only, is accepted on purpose) and except into module "Web site" when permission to edit website content is allowed (injecting any data in this case is allowed too). * Cross-Site Requests Forgery (CSRF) with real security impact (when using GET URLs, CSRF are qualified only for creating, updating or deleting data from pages restricted to admin users) * Open redirect * Broken authentication & session management diff --git a/build/exe/doliwamp/doliwamp.iss b/build/exe/doliwamp/doliwamp.iss index dbf74a96f67..c316e0f91d6 100644 --- a/build/exe/doliwamp/doliwamp.iss +++ b/build/exe/doliwamp/doliwamp.iss @@ -27,12 +27,12 @@ OutputBaseFilename=__FILENAMEEXEDOLIWAMP__ ;SourceDir=Z:\home\ldestailleur\git\dolibarrxxx SourceDir=..\..\.. AppId=doliwamp -AppPublisher=NLTechno -AppPublisherURL=https://www.nltechno.com +AppPublisher=DoliCloud +AppPublisherURL=https://www.dolicloud.com AppSupportURL=https://www.dolibarr.org AppUpdatesURL=https://www.dolibarr.org AppComments=DoliWamp includes Dolibarr, Apache, PHP and Mysql software. -AppCopyright=Copyright (C) 2008-2020 Laurent Destailleur (NLTechno), Fabian Rodriguez (Le Goût du Libre) +AppCopyright=Copyright (C) 2008-2022 Laurent Destailleur (NLTechno), Fabian Rodriguez (Le Goût du Libre) DefaultDirName=c:\dolibarr DefaultGroupName=Dolibarr ;LicenseFile=COPYING @@ -99,13 +99,12 @@ Source: "build\exe\doliwamp\startdoliwamp_manual_donotuse.bat.install"; DestDir: Source: "build\exe\doliwamp\builddemosslfiles.bat.install"; DestDir: "{app}\"; Flags: ignoreversion; Source: "build\exe\doliwamp\UsedPort.exe"; DestDir: "{app}\"; Flags: ignoreversion; -; PhpMyAdmin, Apache, Php, Mysql +; Apache, Php, Mysql ; Put here path of Wampserver applications ; Value OK: apache 2.2.6, php 5.2.5 (5.2.11, 5.3.0 and 5.3.1 fails if php_exif, php_pgsql, php_zip is on), mysql 5.0.45 ; Value OK: apache 2.2.11, php 5.3.0 (if no php_exif, php_pgsql, php_zip), mysql 5.0.45 ; Value OK: apache 2.4.9, php 5.5.12, mysql 5.0.45 instead of 5.6.17 (wampserver2.5-Apache-2.4.9-Mysql-5.6.17-php5.5.12-32b.exe) ; Value OK: apache 2.4.41, php 7.3.12, mariadb10.4.10 (wampserver3.2.0_x64.exe) -Source: "C:\wamp64\apps\phpmyadmin4.9.2\*.*"; DestDir: "{app}\apps\phpmyadmin4.9.2"; Flags: ignoreversion recursesubdirs; Excludes: "config.inc.php,wampserver.conf,*.log,*_log,darkblue_orange" ;Source: "C:\Program Files\Wamp\bin\apache\apache2.4.9\*.*"; DestDir: "{app}\bin\apache\apache2.4.9"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,httpd.conf,wampserver.conf,*.log,*_log" Source: "C:\wamp64\bin\apache\apache2.4.41\*.*"; DestDir: "{app}\bin\apache\apache2.4.41"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,httpd.conf,wampserver.conf,*.log,*_log" ;Source: "C:\Program Files\Wamp\bin\php\php5.5.12\*.*"; DestDir: "{app}\bin\php\php5.5.12"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,phpForApache.ini,wampserver.conf,*.log,*_log" @@ -125,9 +124,7 @@ Source: "scripts\*.*"; DestDir: "{app}\www\dolibarr\scripts"; Flags: ignoreversi Source: "*.*"; DestDir: "{app}\www\dolibarr"; Flags: ignoreversion; Excludes: ".gitignore,.project,CVS\*,Thumbs.db,default.properties,install.lock" ; Config files -Source: "build\exe\doliwamp\phpmyadmin.conf.install"; DestDir: "{app}\alias"; Flags: ignoreversion; Source: "build\exe\doliwamp\dolibarr.conf.install"; DestDir: "{app}\alias"; Flags: ignoreversion; -Source: "build\exe\doliwamp\config.inc.php.install"; DestDir: "{app}\apps\phpmyadmin4.1.14"; Flags: ignoreversion; ;Source: "build\exe\doliwamp\httpd.conf.install"; DestDir: "{app}\bin\apache\apache2.4.9\conf"; Flags: ignoreversion; Source: "build\exe\doliwamp\httpd.conf.install"; DestDir: "{app}\bin\apache\apache2.4.41\conf"; Flags: ignoreversion; Source: "build\exe\doliwamp\my.ini.install"; DestDir: "{app}\bin\mysql\mysql5.0.45"; Flags: ignoreversion; @@ -196,7 +193,6 @@ var destFileA: String; var srcContents: String; var browser: String; var mysqlVersion: String; -var phpmyadminVersion: String; var phpDllCopy: String; var batFile: String; @@ -246,7 +242,6 @@ begin phpVersion := '7.3.12' ; //mysqlVersion := '5.0.45'; mysqlVersion := '10.4.10'; - phpmyadminVersion := '4.1.14'; smtpServer := 'localhost'; apachePort := '80'; @@ -635,27 +630,6 @@ begin begin - //---------------------------------------------- - // Create file alias phpmyadmin (always) - //---------------------------------------------- - - destFile := pathWithSlashes+'/alias/phpmyadmin.conf'; - srcFile := pathWithSlashes+'/alias/phpmyadmin.conf.install'; - - if FileExists(srcFile) then - begin - LoadStringFromFile (srcFile, srcContents); - - //installDir et version de phpmyadmin - StringChangeEx (srcContents, 'WAMPROOT', pathWithSlashes, True); - StringChangeEx (srcContents, 'WAMPPHPMYADMINVERSION', phpmyadminVersion, True); - - SaveStringToFile(destFile,srcContents, False); - end; - DeleteFile(srcFile); - - - //---------------------------------------------- // Create file alias dolibarr (if not exists) //---------------------------------------------- @@ -691,35 +665,6 @@ begin - //---------------------------------------------- - // Create file configuration for phpmyadmin (if not exists) - //---------------------------------------------- - - destFile := pathWithSlashes+'/apps/phpmyadmin'+phpmyadminVersion+'/config.inc.php'; - srcFile := pathWithSlashes+'/apps/phpmyadmin'+phpmyadminVersion+'/config.inc.php.install'; - - if FileExists(srcFile) then - begin - if not FileExists (destFile) then - begin - LoadStringFromFile (srcFile, srcContents); - StringChangeEx (srcContents, 'WAMPMYSQLNEWPASSWORD', mypass, True); - StringChangeEx (srcContents, 'WAMPMYSQLPORT', myport, True); - SaveStringToFile(destFile,srcContents, False); - end - else - begin - // We must replace to use format 2.4 of apache - DeleteFile(destFile); - LoadStringFromFile (srcFile, srcContents); - StringChangeEx (srcContents, 'WAMPMYSQLNEWPASSWORD', mypass, True); - StringChangeEx (srcContents, 'WAMPMYSQLPORT', myport, True); - SaveStringToFile(destFile,srcContents, False); - end; - end; - - - //---------------------------------------------- // Create file httpd.conf (if not exists) //---------------------------------------------- diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index 906601d94d4..b648bd7aff7 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -582,9 +582,7 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/teclib*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/timesheet*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/webmail*`; - $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/themes/oblyon*`; - $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/themes/allscreen*`; - $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/theme/common/octicons/LICENSE`; + $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/theme/common/fontawesome-5/svgs`; # Removed other test files $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/public/test`; diff --git a/build/pad/README b/build/pad/README index 3cbc171686c..241d27d01c2 100644 --- a/build/pad/README +++ b/build/pad/README @@ -1,6 +1,7 @@ README (English) ################################################## Building PAD files +http://pad.asp-software.org/padgen.php ################################################## This directory contains files and docs used to build diff --git a/build/perl/virtualmin/dolibarr.pl b/build/perl/virtualmin/dolibarr.pl index 8b6a9888db0..b5bacf59356 100644 --- a/build/perl/virtualmin/dolibarr.pl +++ b/build/perl/virtualmin/dolibarr.pl @@ -30,7 +30,7 @@ return "Regis Houssin"; # script_dolibarr_versions() sub script_dolibarr_versions { -return ( "12.0.3", "11.0.5", "10.0.7", "9.0.4", "8.0.6", "7.0.5" ); +return ( "14.0.5", "13.0.5", "12.0.5", "11.0.5", "10.0.7", "9.0.4", "8.0.6", "7.0.5" ); } sub script_dolibarr_release @@ -400,6 +400,8 @@ sub script_dolibarr_check_latest { local ($ver) = @_; local @vers = &osdn_package_versions("dolibarr", + $ver >= 14.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" : + $ver >= 13.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" : $ver >= 12.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" : $ver >= 11.0 ? "dolibarr\\-(11\\.0\\.[0-9\\.]+)\\.tgz" : $ver >= 10.0 ? "dolibarr\\-(10\\.0\\.[0-9\\.]+)\\.tgz" : diff --git a/composer.json b/composer.json.disabled similarity index 97% rename from composer.json rename to composer.json.disabled index 8d82f530df8..adeaffd2334 100644 --- a/composer.json +++ b/composer.json.disabled @@ -28,7 +28,7 @@ "ext-curl" : "*", "ckeditor/ckeditor" : "4.12.1", "mike42/escpos-php" : "2.2", - "mobiledetect/mobiledetectlib" : "2.8.34", + "mobiledetect/mobiledetectlib" : "2.8.39", "phpoffice/phpexcel" : "1.8.2", "restler/framework" : "3.0.0-RC6", "tecnickcom/tcpdf" : "6.3.2", @@ -59,4 +59,4 @@ "ext-zip" : "ODT, Excel and file compression support", "ext-xml" : "Excel support" } -} \ No newline at end of file +} diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 5f761cb63fe..00000000000 --- a/composer.lock +++ /dev/null @@ -1,2349 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "1dbd2d05cc0836acfca5988f29005cf2", - "packages": [ - { - "name": "ckeditor/ckeditor", - "version": "4.12.1", - "source": { - "type": "git", - "url": "https://github.com/ckeditor/ckeditor-releases.git", - "reference": "b1a25e93ae0b038f45dcba458f4c2c18bd7318e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ckeditor/ckeditor-releases/zipball/b1a25e93ae0b038f45dcba458f4c2c18bd7318e5", - "reference": "b1a25e93ae0b038f45dcba458f4c2c18bd7318e5", - "shasum": "" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "GPL-2.0+", - "LGPL-2.1+", - "MPL-1.1+" - ], - "authors": [ - { - "name": "CKSource", - "homepage": "http://cksource.com" - } - ], - "description": "JavaScript WYSIWYG web text editor.", - "homepage": "http://ckeditor.com", - "keywords": [ - "CKEditor", - "editor", - "fckeditor", - "html", - "javascript", - "richtext", - "text", - "wysiwyg" - ], - "support": { - "forum": "http://ckeditor.com/forums", - "issues": "http://dev.ckeditor.com", - "source": "http://github.com/ckeditor/ckeditor-dev", - "wiki": "http://docs.ckeditor.com" - }, - "time": "2019-06-28T10:41:23+00:00" - }, - { - "name": "maximebf/debugbar", - "version": "v1.15.1", - "source": { - "type": "git", - "url": "https://github.com/maximebf/php-debugbar.git", - "reference": "6c4277f6117e4864966c9cb58fb835cee8c74a1e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/6c4277f6117e4864966c9cb58fb835cee8c74a1e", - "reference": "6c4277f6117e4864966c9cb58fb835cee8c74a1e", - "shasum": "" - }, - "require": { - "php": ">=5.6", - "psr/log": "^1.0", - "symfony/var-dumper": "^2.6|^3|^4" - }, - "require-dev": { - "phpunit/phpunit": "^5" - }, - "suggest": { - "kriswallsmith/assetic": "The best way to manage assets", - "monolog/monolog": "Log using Monolog", - "predis/predis": "Redis storage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.15-dev" - } - }, - "autoload": { - "psr-4": { - "DebugBar\\": "src/DebugBar/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Maxime Bouroumeau-Fuseau", - "email": "maxime.bouroumeau@gmail.com", - "homepage": "http://maximebf.com" - }, - { - "name": "Barry vd. Heuvel", - "email": "barryvdh@gmail.com" - } - ], - "description": "Debug bar in the browser for php application", - "homepage": "https://github.com/maximebf/php-debugbar", - "keywords": [ - "debug", - "debugbar" - ], - "support": { - "issues": "https://github.com/maximebf/php-debugbar/issues", - "source": "https://github.com/maximebf/php-debugbar/tree/v1.15.1" - }, - "time": "2019-09-24T14:55:42+00:00" - }, - { - "name": "mike42/escpos-php", - "version": "v2.2", - "source": { - "type": "git", - "url": "https://github.com/mike42/escpos-php.git", - "reference": "e5496cf819b048b11877117bd14a9cea4fb17c03" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mike42/escpos-php/zipball/e5496cf819b048b11877117bd14a9cea4fb17c03", - "reference": "e5496cf819b048b11877117bd14a9cea4fb17c03", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "guzzlehttp/guzzle": "^5.3", - "phpunit/phpunit": "^4.8", - "squizlabs/php_codesniffer": "^3.2" - }, - "suggest": { - "ext-gd": "Used for image printing if present.", - "ext-imagick": "Will be used for image printing if present. Required for PDF printing or use of custom fonts.", - "guzzlehttp/guzzle": "Allows the use of the ApiConnector to send print jobs over HTTP." - }, - "type": "library", - "autoload": { - "psr-4": { - "Mike42\\": "src/Mike42" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Billington", - "email": "michael.billington@gmail.com" - } - ], - "description": "PHP receipt printer library for use with ESC/POS-compatible thermal and impact printers", - "homepage": "https://github.com/mike42/escpos-php", - "keywords": [ - "ESC-POS", - "driver", - "escpos", - "print", - "receipt" - ], - "support": { - "issues": "https://github.com/mike42/escpos-php/issues", - "source": "https://github.com/mike42/escpos-php/tree/v2.2" - }, - "time": "2019-10-05T05:59:00+00:00" - }, - { - "name": "mobiledetect/mobiledetectlib", - "version": "2.8.34", - "source": { - "type": "git", - "url": "https://github.com/serbanghita/Mobile-Detect.git", - "reference": "6f8113f57a508494ca36acbcfa2dc2d923c7ed5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/6f8113f57a508494ca36acbcfa2dc2d923c7ed5b", - "reference": "6f8113f57a508494ca36acbcfa2dc2d923c7ed5b", - "shasum": "" - }, - "require": { - "php": ">=5.0.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8.35||~5.7" - }, - "type": "library", - "autoload": { - "classmap": [ - "Mobile_Detect.php" - ], - "psr-0": { - "Detection": "namespaced/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Serban Ghita", - "email": "serbanghita@gmail.com", - "homepage": "http://mobiledetect.net", - "role": "Developer" - } - ], - "description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.", - "homepage": "https://github.com/serbanghita/Mobile-Detect", - "keywords": [ - "detect mobile devices", - "mobile", - "mobile detect", - "mobile detector", - "php mobile detect" - ], - "support": { - "issues": "https://github.com/serbanghita/Mobile-Detect/issues", - "source": "https://github.com/serbanghita/Mobile-Detect/tree/2.8.34" - }, - "time": "2019-09-18T18:44:20+00:00" - }, - { - "name": "nnnick/chartjs", - "version": "v2.9.4", - "source": { - "type": "git", - "url": "https://github.com/chartjs/Chart.js.git", - "reference": "9bd4cf82fda9f50a5fb50b72843e06ab88124278" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/chartjs/Chart.js/zipball/9bd4cf82fda9f50a5fb50b72843e06ab88124278", - "reference": "9bd4cf82fda9f50a5fb50b72843e06ab88124278", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "release/2.0": "v2.0-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "NICK DOWNIE", - "email": "hello@nickdownie.com" - } - ], - "description": "Simple HTML5 charts using the canvas element.", - "homepage": "https://www.chartjs.org/", - "keywords": [ - "JS", - "chart" - ], - "support": { - "issues": "https://github.com/chartjs/Chart.js/issues", - "source": "https://github.com/chartjs/Chart.js/tree/v2.9.4" - }, - "time": "2020-10-19T12:22:11+00:00" - }, - { - "name": "psr/log", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", - "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/1.1.3" - }, - "time": "2020-03-23T09:12:05+00:00" - }, - { - "name": "phpoffice/phpexcel", - "version": "1.8.2", - "source": { - "type": "git", - "url": "https://github.com/PHPOffice/PHPExcel.git", - "reference": "1441011fb7ecdd8cc689878f54f8b58a6805f870" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PHPExcel/zipball/1441011fb7ecdd8cc689878f54f8b58a6805f870", - "reference": "1441011fb7ecdd8cc689878f54f8b58a6805f870", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "php": "^5.2|^7.0" - }, - "require-dev": { - "squizlabs/php_codesniffer": "2.*" - }, - "type": "library", - "autoload": { - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1" - ], - "authors": [ - { - "name": "Maarten Balliauw", - "homepage": "http://blog.maartenballiauw.be" - }, - { - "name": "Erik Tilt" - }, - { - "name": "Franck Lefevre", - "homepage": "http://rootslabs.net" - }, - { - "name": "Mark Baker", - "homepage": "http://markbakeruk.net" - } - ], - "description": "PHPExcel - OpenXML - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", - "homepage": "https://github.com/PHPOffice/PHPExcel", - "keywords": [ - "OpenXML", - "excel", - "xlsx" - ], - "abandoned": "phpoffice/phpspreadsheet", - "time": "2018-11-22T23:07:24+00:00" - }, - { - "name": "restler/framework", - "version": "3.0.0-RC6", - "target-dir": "Luracast/Restler", - "source": { - "type": "git", - "url": "https://github.com/Luracast/Restler-Framework.git", - "reference": "d52e61600d153bca60a287c35141c5c01863127b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Luracast/Restler-Framework/zipball/d52e61600d153bca60a287c35141c5c01863127b", - "reference": "d52e61600d153bca60a287c35141c5c01863127b", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "replace": { - "luracast/restler": "3.*" - }, - "suggest": { - "bshaffer/oauth2-server-php": "If you want to use OAuth2 for authentication", - "illuminate/view": "If you want to use laravel blade templates with Html format", - "mustache/mustache": "If you want to use mustache/handlebar templates with Html format", - "rodneyrehm/plist": "If you need Apple plist binary/xml format", - "symfony/yaml": "If you need YAML format", - "twig/twig": "If you want to use twig templates with Html format", - "zendframework/zendamf": "If you need AMF format" - }, - "type": "library", - "extra": { - "branch-alias": { - "master": "v3.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Luracast\\Restler": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-2.1" - ], - "authors": [ - { - "name": "Luracast", - "email": "arul@luracast.com" - } - ], - "description": "Just the Restler Framework without the tests and examples", - "homepage": "http://luracast.com/products/restler/", - "keywords": [ - "api", - "framework", - "rest", - "server" - ], - "support": { - "source": "https://github.com/Luracast/Restler-Framework/tree/3.0.0-RC6" - }, - "time": "2020-02-13T16:05:12+00:00" - }, - { - "name": "stripe/stripe-php", - "version": "v6.43.1", - "source": { - "type": "git", - "url": "https://github.com/stripe/stripe-php.git", - "reference": "42fcdaf99c44bb26937223f8eae1f263491d5ab8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/stripe/stripe-php/zipball/42fcdaf99c44bb26937223f8eae1f263491d5ab8", - "reference": "42fcdaf99c44bb26937223f8eae1f263491d5ab8", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-json": "*", - "ext-mbstring": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "php-coveralls/php-coveralls": "1.*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0", - "symfony/process": "~2.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "psr-4": { - "Stripe\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Stripe and contributors", - "homepage": "https://github.com/stripe/stripe-php/contributors" - } - ], - "description": "Stripe PHP Library", - "homepage": "https://stripe.com/", - "keywords": [ - "api", - "payment processing", - "stripe" - ], - "support": { - "issues": "https://github.com/stripe/stripe-php/issues", - "source": "https://github.com/stripe/stripe-php/tree/master" - }, - "time": "2019-08-29T16:56:12+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.20.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.20-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.20.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-10-23T14:02:19+00:00" - }, - { - "name": "symfony/var-dumper", - "version": "v3.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "737e07704cca83f9dd0af926d45ce27eedc25657" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/737e07704cca83f9dd0af926d45ce27eedc25657", - "reference": "737e07704cca83f9dd0af926d45ce27eedc25657", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "symfony/polyfill-mbstring": "~1.0" - }, - "require-dev": { - "twig/twig": "~1.20|~2.0" - }, - "suggest": { - "ext-symfony_debug": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-dev" - } - }, - "autoload": { - "files": [ - "Resources/functions/dump.php" - ], - "psr-4": { - "Symfony\\Component\\VarDumper\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony mechanism for exploring and dumping PHP variables", - "homepage": "https://symfony.com", - "keywords": [ - "debug", - "dump" - ], - "support": { - "source": "https://github.com/symfony/var-dumper/tree/master" - }, - "time": "2015-11-18T13:48:51+00:00" - }, - { - "name": "tecnickcom/tcpdf", - "version": "6.3.2", - "source": { - "type": "git", - "url": "https://github.com/tecnickcom/TCPDF.git", - "reference": "9fde7bb9b404b945e7ea88fb7eccd23d9a4e324b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/9fde7bb9b404b945e7ea88fb7eccd23d9a4e324b", - "reference": "9fde7bb9b404b945e7ea88fb7eccd23d9a4e324b", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "config", - "include", - "tcpdf.php", - "tcpdf_parser.php", - "tcpdf_import.php", - "tcpdf_barcodes_1d.php", - "tcpdf_barcodes_2d.php", - "include/tcpdf_colors.php", - "include/tcpdf_filters.php", - "include/tcpdf_font_data.php", - "include/tcpdf_fonts.php", - "include/tcpdf_images.php", - "include/tcpdf_static.php", - "include/barcodes/datamatrix.php", - "include/barcodes/pdf417.php", - "include/barcodes/qrcode.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "LGPL-3.0" - ], - "authors": [ - { - "name": "Nicola Asuni", - "email": "info@tecnick.com", - "role": "lead" - } - ], - "description": "TCPDF is a PHP class for generating PDF documents and barcodes.", - "homepage": "http://www.tcpdf.org/", - "keywords": [ - "PDFD32000-2008", - "TCPDF", - "barcodes", - "datamatrix", - "pdf", - "pdf417", - "qrcode" - ], - "support": { - "source": "https://github.com/tecnickcom/TCPDF/tree/6.3.2" - }, - "time": "2019-09-20T09:35:01+00:00" - } - ], - "packages-dev": [ - { - "name": "doctrine/instantiator", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^8.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2020-11-10T18:47:58+00:00" - }, - { - "name": "php-parallel-lint/php-console-color", - "version": "v0.3", - "source": { - "type": "git", - "url": "https://github.com/php-parallel-lint/PHP-Console-Color.git", - "reference": "b6af326b2088f1ad3b264696c9fd590ec395b49e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-parallel-lint/PHP-Console-Color/zipball/b6af326b2088f1ad3b264696c9fd590ec395b49e", - "reference": "b6af326b2088f1ad3b264696c9fd590ec395b49e", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "replace": { - "jakub-onderka/php-console-color": "*" - }, - "require-dev": { - "php-parallel-lint/php-code-style": "1.0", - "php-parallel-lint/php-parallel-lint": "1.0", - "php-parallel-lint/php-var-dump-check": "0.*", - "phpunit/phpunit": "~4.3", - "squizlabs/php_codesniffer": "1.*" - }, - "type": "library", - "autoload": { - "psr-4": { - "JakubOnderka\\PhpConsoleColor\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Jakub Onderka", - "email": "jakub.onderka@gmail.com" - } - ], - "support": { - "issues": "https://github.com/php-parallel-lint/PHP-Console-Color/issues", - "source": "https://github.com/php-parallel-lint/PHP-Console-Color/tree/master" - }, - "time": "2020-05-14T05:47:14+00:00" - }, - { - "name": "php-parallel-lint/php-console-highlighter", - "version": "v0.5", - "source": { - "type": "git", - "url": "https://github.com/php-parallel-lint/PHP-Console-Highlighter.git", - "reference": "21bf002f077b177f056d8cb455c5ed573adfdbb8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-parallel-lint/PHP-Console-Highlighter/zipball/21bf002f077b177f056d8cb455c5ed573adfdbb8", - "reference": "21bf002f077b177f056d8cb455c5ed573adfdbb8", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.4.0", - "php-parallel-lint/php-console-color": "~0.2" - }, - "replace": { - "jakub-onderka/php-console-highlighter": "*" - }, - "require-dev": { - "php-parallel-lint/php-code-style": "~1.0", - "php-parallel-lint/php-parallel-lint": "~1.0", - "php-parallel-lint/php-var-dump-check": "~0.1", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~1.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "JakubOnderka\\PhpConsoleHighlighter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jakub Onderka", - "email": "acci@acci.cz", - "homepage": "http://www.acci.cz/" - } - ], - "description": "Highlight PHP code in terminal", - "support": { - "issues": "https://github.com/php-parallel-lint/PHP-Console-Highlighter/issues", - "source": "https://github.com/php-parallel-lint/PHP-Console-Highlighter/tree/master" - }, - "time": "2020-05-13T07:37:49+00:00" - }, - { - "name": "php-parallel-lint/php-parallel-lint", - "version": "v0.9.2", - "source": { - "type": "git", - "url": "https://github.com/php-parallel-lint/PHP-Parallel-Lint.git", - "reference": "2ead2e4043ab125bee9554f356e0a86742c2d4fa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-parallel-lint/PHP-Parallel-Lint/zipball/2ead2e4043ab125bee9554f356e0a86742c2d4fa", - "reference": "2ead2e4043ab125bee9554f356e0a86742c2d4fa", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "jakub-onderka/php-console-highlighter": "~0.3", - "nette/tester": "~1.3" - }, - "suggest": { - "jakub-onderka/php-console-highlighter": "Highlight syntax in code snippet" - }, - "bin": [ - "parallel-lint" - ], - "type": "library", - "autoload": { - "classmap": [ - "./" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Jakub Onderka", - "email": "jakub.onderka@gmail.com" - } - ], - "description": "This tool check syntax of PHP files about 20x faster than serial check.", - "homepage": "https://github.com/JakubOnderka/PHP-Parallel-Lint", - "support": { - "source": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/tree/v0.9.2" - }, - "time": "2015-12-15T10:42:16+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.2.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" - }, - "time": "2020-09-03T19:13:55+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" - }, - "time": "2020-09-17T18:55:26+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.10.3", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "451c3cd1418cf640de218914901e51b064abb093" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", - "reference": "451c3cd1418cf640de218914901e51b064abb093", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5 || ^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.10.3" - }, - "time": "2020-03-05T15:02:03+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "2.2.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": "~1.3", - "phpunit/php-text-template": "~1.2", - "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "^1.3.2", - "sebastian/version": "~1.0" - }, - "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.2.1", - "ext-xmlwriter": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/2.2" - }, - "time": "2015-10-06T15:47:00+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.4.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/1.4.5" - }, - "time": "2017-11-27T13:52:08+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" - }, - "time": "2015-06-21T13:50:34+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.9", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/master" - }, - "time": "2017-02-26T11:10:40+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "1.4.12", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", - "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", - "source": "https://github.com/sebastianbergmann/php-token-stream/tree/1.4" - }, - "abandoned": true, - "time": "2017-12-04T08:55:13+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "4.8.36", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", - "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpspec/prophecy": "^1.3.1", - "phpunit/php-code-coverage": "~2.1", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.2.2", - "sebastian/diff": "~1.2", - "sebastian/environment": "~1.3", - "sebastian/exporter": "~1.2", - "sebastian/global-state": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.1|~3.0" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.8.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/4.8.36" - }, - "time": "2017-06-21T08:07:12+00:00" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "2.3.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2", - "sebastian/exporter": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues", - "source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/2.3" - }, - "abandoned": true, - "time": "2015-10-02T06:51:40+00:00" - }, - { - "name": "phpunit/phpunit-selenium", - "version": "2.0.3", - "source": { - "type": "git", - "url": "https://github.com/giorgiosironi/phpunit-selenium.git", - "reference": "013037eeea481657d236431634042648797e1da8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/giorgiosironi/phpunit-selenium/zipball/013037eeea481657d236431634042648797e1da8", - "reference": "013037eeea481657d236431634042648797e1da8", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-dom": "*", - "php": ">=5.3.3", - "phpunit/phpunit": "~4.8", - "sebastian/comparator": "~1.0" - }, - "require-dev": { - "phing/phing": "2.*" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHPUnit/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Giorgio Sironi", - "email": "info@giorgiosironi.com", - "role": "developer" - }, - { - "name": "Ivan Kurnosov", - "email": "zerkms@zerkms.com", - "role": "developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "original developer" - } - ], - "description": "Selenium Server integration for PHPUnit", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "phpunit", - "selenium", - "testing", - "xunit" - ], - "support": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/phpunit-selenium/issues", - "source": "https://github.com/giorgiosironi/phpunit-selenium/tree/2.x" - }, - "time": "2017-01-23T22:15:32+00:00" - }, - { - "name": "sebastian/comparator", - "version": "1.2.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2 || ~2.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/1.2" - }, - "time": "2017-01-29T09:50:25+00:00" - }, - { - "name": "sebastian/diff", - "version": "1.4.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/1.4" - }, - "time": "2017-05-22T07:24:03+00:00" - }, - { - "name": "sebastian/environment", - "version": "1.3.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", - "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8 || ^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/1.3" - }, - "time": "2016-08-18T05:49:44+00:00" - }, - { - "name": "sebastian/exporter", - "version": "1.2.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", - "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~1.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/master" - }, - "time": "2016-06-17T09:04:28+00:00" - }, - { - "name": "sebastian/global-state", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/1.1.1" - }, - "time": "2015-10-12T03:26:01+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", - "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/master" - }, - "time": "2016-10-03T07:41:43+00:00" - }, - { - "name": "sebastian/version", - "version": "1.0.6", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", - "shasum": "" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/1.0.6" - }, - "time": "2015-06-21T13:59:46+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "2.9.2", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "2acf168de78487db620ab4bc524135a13cfe6745" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/2acf168de78487db620ab4bc524135a13cfe6745", - "reference": "2acf168de78487db620ab4bc524135a13cfe6745", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "bin": [ - "scripts/phpcs", - "scripts/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "classmap": [ - "CodeSniffer.php", - "CodeSniffer/CLI.php", - "CodeSniffer/Exception.php", - "CodeSniffer/File.php", - "CodeSniffer/Fixer.php", - "CodeSniffer/Report.php", - "CodeSniffer/Reporting.php", - "CodeSniffer/Sniff.php", - "CodeSniffer/Tokens.php", - "CodeSniffer/Reports/", - "CodeSniffer/Tokenizers/", - "CodeSniffer/DocGenerators/", - "CodeSniffer/Standards/AbstractPatternSniff.php", - "CodeSniffer/Standards/AbstractScopeSniff.php", - "CodeSniffer/Standards/AbstractVariableSniff.php", - "CodeSniffer/Standards/IncorrectPatternException.php", - "CodeSniffer/Standards/Generic/Sniffs/", - "CodeSniffer/Standards/MySource/Sniffs/", - "CodeSniffer/Standards/PEAR/Sniffs/", - "CodeSniffer/Standards/PSR1/Sniffs/", - "CodeSniffer/Standards/PSR2/Sniffs/", - "CodeSniffer/Standards/Squiz/Sniffs/", - "CodeSniffer/Standards/Zend/Sniffs/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "http://www.squizlabs.com/php-codesniffer", - "keywords": [ - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "time": "2018-11-07T22:31:41+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.20.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.20-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-10-23T14:02:19+00:00" - }, - { - "name": "symfony/yaml", - "version": "v3.4.47", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "88289caa3c166321883f67fe5130188ebbb47094" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/88289caa3c166321883f67fe5130188ebbb47094", - "reference": "88289caa3c166321883f67fe5130188ebbb47094", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/polyfill-ctype": "~1.8" - }, - "conflict": { - "symfony/console": "<3.4" - }, - "require-dev": { - "symfony/console": "~3.4|~4.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/yaml/tree/v3.4.47" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-10-24T10:57:07+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.9.1", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" - }, - "type": "library", - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozart/assert/issues", - "source": "https://github.com/webmozart/assert/tree/master" - }, - "time": "2020-07-08T17:02:28+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "restler/framework": 5 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=5.6.0", - "ext-curl": "*" - }, - "platform-dev": [], - "plugin-api-version": "2.0.0" -} diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index d4a9b725524..204988c5442 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -111,6 +111,10 @@ with // DOL CHANGE If we keep this, the image is not visible on pages after the first one. //var_dump($file.' '.(!@TCPDF_STATIC::file_exists($file))); //return false; + $tfile = str_replace(' ', '%20', $file); + if (@TCPDF_STATIC::file_exists($tfile)) { + $file = $tfile; + } } * Replace in tcpdf.php diff --git a/dev/examples/code/README b/dev/examples/code/README index b7c31558de5..bf3dd3f4969 100644 --- a/dev/examples/code/README +++ b/dev/examples/code/README @@ -5,4 +5,4 @@ This directory contains samples of code to use Dolibarr business classes to buil external interfaces that need to read/update data from/into Dolibarr. You can also have a look at the Dolibarr doxygen doc that describes all files and classes: -http://www.dolibarr.org/html_doxygen/index.html +https://doxygen.dolibarr.org/ diff --git a/dev/examples/zapier/package.json b/dev/examples/zapier/package.json index a9d519dec69..8852928771f 100644 --- a/dev/examples/zapier/package.json +++ b/dev/examples/zapier/package.json @@ -15,7 +15,7 @@ "npm": ">=5.6.0" }, "dependencies": { - "zapier-platform-core": "11.0.1" + "zapier-platform-core": "11.3.1" }, "devDependencies": { "mocha": "^5.2.0", diff --git a/dev/resources/iso-normes/accountancy_rules.txt b/dev/resources/iso-normes/accountancy/accountancy_rules.txt similarity index 61% rename from dev/resources/iso-normes/accountancy_rules.txt rename to dev/resources/iso-normes/accountancy/accountancy_rules.txt index 15e07ffbea1..a265bcf4f54 100644 --- a/dev/resources/iso-normes/accountancy_rules.txt +++ b/dev/resources/iso-normes/accountancy/accountancy_rules.txt @@ -2,13 +2,13 @@ Gestion escompte: Sur une facture de 120 € TTC : -707xxx 100 € HT -44571x 20 € TVA -411xxx 120 € TTC - +707xxx 100 € HT +44571x 20 € TVA +411xxx 120 € TTC + Le client règle rapidement et on lui accorde un escompte de 3% (120 € * 3% = 3.6 € TTC), on aura donc : -665000 3,00 € HT -44571x 0,60 € TVA -411xxx 3.60 € TVA - +665000 3,00 € HT +44571x 0,60 € TVA +411xxx 3,60 € TTC + Et ça marche à l’inverse avec un fournisseur sauf que l’on est en 775000 au lieu de 665000 pour escompte obtenus. diff --git a/dev/resources/iso-normes/banknumber_format.txt b/dev/resources/iso-normes/banking/banknumber_format.txt similarity index 100% rename from dev/resources/iso-normes/banknumber_format.txt rename to dev/resources/iso-normes/banking/banknumber_format.txt diff --git a/dev/resources/iso-normes/iban_iso-13616.txt b/dev/resources/iso-normes/banking/iban_iso-13616_fr.txt similarity index 100% rename from dev/resources/iso-normes/iban_iso-13616.txt rename to dev/resources/iso-normes/banking/iban_iso-13616_fr.txt diff --git a/dev/resources/iso-normes/barcode_EAN13.txt b/dev/resources/iso-normes/barcode_EAN13.txt deleted file mode 100644 index f4496327ee4..00000000000 --- a/dev/resources/iso-normes/barcode_EAN13.txt +++ /dev/null @@ -1,129 +0,0 @@ -Barcode EAN 13 - -FR -== -Signification des chiffres. - -- 2 chiffres pour le code pays ou code systeme -- 5 chiffres pour l'identificateur de societe -- 5 chiffres pour l'identificateur d'article -- 1 chiffre pour la somme de controle - -Cette regle subit de nombreuses entorses pour ameliorer l'usage des chiffres disponibles. -Voici la liste des codes pays ou systeme : - - - -EN -== -Meaning of the numbers. - -- 2 digits for the country code or system code -- 5 digits for the company identifier -- 5 digits for item identifier -- 1 digit for checksum - -This rule has been twisted many times to improve the use of the available numbers. -Here is the list of country codes or system: - - - -List -==== - -00 � 13 UCC (Etats-Unis et Canada) -20 � 29 Codification interne en magasin -30 � 37 GENCOD-EAN France -380 BCCI (Bulgarie) -383 SANA (Slovenie) -385 CRO-EAN (Croatie) -387 EAN-BIH (Bosnie-Herzegovine) -400 � 440 CCG (Allemagne) -45 + 49 Distribution Code Center � DCC (Japon) -460 � 469 UNISCAN - EAN Russie (Federation de Russie) -471 CAN (Taiwan) -474 EAN Estonie -475 EAN Lettonie -476 EAN Azerba� djan -477 EAN Lituanie -478 EAN Ouzbekistan -479 EAN Sri Lanka -480 PANC (Philippines) -481 EAN Bielorussie -482 EAN Ukraine -484 EAN Moldavie -485 EAN Armenie -486 EAN Georgie -487 EAN Kazakhstan -489 HKANA (Hong Kong) -50 E Centre UK -520 HELLCAN-EAN HELLAS (Grece) -528 EAN Liban -529 EAN Chypre -531 EAN-MAC (FYR Mac�donie) -535 EAN Malte -539 EAN Irlande -54 ICODIF/EAN Belgique. Luxembourg -560 CODIPOR (Portugal) -569 EAN Islande -57 EAN Danemark -590 EAN Pologne -594 EAN Roumanie -599 H.A.P.M.H. (Hongrie) -600 - 601 EAN Afrique du Sud -609 EAN Ile Maurice -611 EAN Maroc -613 EAN Algerie -619 Tunicode (Tunisie) -621 EAN Syrie -622 EAN Egypte -625 EAN Jordanie -626 EAN Iran -628 EAN Arabie Saoudite -64 EAN Finlande -690 - 693 Article Numbering Centre of China - ANCC (Chine) -70 EAN Norge (Norvege) -729 Israeli Bar Code Association � EAN Israel -73 EAN Suede -740 EAN Guatemala -741 EAN El Salvador -742 ICCC (Honduras) -743 EAN Nicaragua -744 EAN Costa Rica Panama -746 746 EAN Republique Dominicaine -750 AMECE (Mexique) -759 EAN Venezuela -76 EAN (Schweiz, Suisse, Svizzera) -770 IAC (Colombie) -773 EAN Uruguay -775 APC - EAN Peru (Perou) -777 EAN Bolivie -779 CODIGO - EAN Argentine -780 EAN Chili -784 EAN Paraguay -786 ECOP (Equateur) -789 EAN Bresil -80 � 83 INDICOD (Italie) -84 AECOC (Espagne) -850 Camera de Comercio de la Republica de Cuba (Cuba) -858 EAN Slovaquie -859 EAN Republique Tcheque -860 EAN YU (Yougoslavie) -867 EAN DPR Korea (Coree du Nord) -869 Union of Chambers of Commerce of Turkey (Turquie) -87 EAN Nederland (Hollande) -880 EAN Korea (Coree du Sud) -885 EAN Thailande -888 SANC (Singapour) -890 EAN Inde -893 EAN Vietnam -899 EAN Indonesie -90 - 91 EAN Autriche -93 EAN Australie -94 EAN Nouvelle Zelande -955 Malaysian Article Numbering Council (MANC) - Malaisie -977 Publications sirielles (ISSN) -978 - 979 Livres (ISBN) -980 Refus de remboursement -981 - 982 Coupons (monnaie courante) -99 Coupons diff --git a/dev/resources/iso-normes/QR code for invoices.txt b/dev/resources/iso-normes/barcodes/QR code for invoices.txt similarity index 88% rename from dev/resources/iso-normes/QR code for invoices.txt rename to dev/resources/iso-normes/barcodes/QR code for invoices.txt index f03351f453f..639435238f9 100644 --- a/dev/resources/iso-normes/QR code for invoices.txt +++ b/dev/resources/iso-normes/barcodes/QR code for invoices.txt @@ -1,3 +1,8 @@ +QR-Code = Quick Response Code - is a two-dimensional / 2D- / Matrix-Barcode + +ISO/IEC 18004 + + List of QR Code format we found on some invoices ------------------------------------------------ diff --git a/dev/resources/iso-normes/barcodes/barcode_EAN13.txt b/dev/resources/iso-normes/barcodes/barcode_EAN13.txt new file mode 100644 index 00000000000..e8000035788 --- /dev/null +++ b/dev/resources/iso-normes/barcodes/barcode_EAN13.txt @@ -0,0 +1,129 @@ +Barcode EAN 13 + +FR +== +Signification des chiffres. + +- 2 chiffres pour le code pays ou code systeme +- 5 chiffres pour l'identificateur de societe +- 5 chiffres pour l'identificateur d'article +- 1 chiffre pour la somme de controle + +Cette regle subit de nombreuses entorses pour ameliorer l'usage des chiffres disponibles. +Voici la liste des codes pays ou systeme : + + + +EN +== +Meaning of the numbers: + +- first 2-3 digits for the country code or system code +- 5 digits for the company identifier +- 5 digits for item identifier +- 1 digit for checksum + +This rule has been twisted many times to improve the use of the available numbers. + +Here is the list of country codes or system: + + +List +==== + +00 - 13 UCC (U.S.A / États-Unis & Canada) +20 - 29 Flag for internal numbering / Codification interne en magasin +30 - 37 GENCOD-EAN France +380 BCCI (Bulgaria) +383 SANA (Slovenia) +385 CRO-EAN (Croatia) +387 EAN-BIH (Bosnia-Herzegovina) +400-440 CCG (DE/Germany/Allemagne) +45 + 49 Distribution Code Center - DCC (Japan) +460-469 UNISCAN - EAN Russia (Federation de Russie) +471 CAN Taiwan +474 EAN Estonia +475 EAN Latvia +476 EAN Azerbaijan +477 EAN Lithuania +478 EAN Uzbekistan +479 EAN Sri Lanka +480 PANC Philippines +481 EAN Belarus +482 EAN Ukraine +484 EAN Moldova +485 EAN Armenia +486 EAN Georgia +487 EAN Kazakhstan +489 HKANA Hong Kong +50 E Centre UK - United Kingdom +520 HELLCAN-EAN HELLAS - Greece +528 EAN Lebanon +529 EAN Cyprus +531 EAN-MAC (FYR Macedonia) +535 EAN Malta +539 EAN Ireland +54 ICODIF/EAN Belgium & Luxembourg +560 CODIPOR (Portugal) +569 EAN Iceland/Islande +57 EAN Denmark +590 EAN Poland +594 EAN Romania +599 H.A.P.M.H. (Hungary) +600-601 EAN South Africa +609 EAN Mauritius Island +611 EAN Morocco +613 EAN Algeria +619 Tunicode (Tunisia) +621 EAN Syria +622 EAN Egypt +625 EAN Jordan/Jordanie +626 EAN Iran +628 EAN Saudi Arabia +64 EAN Finland +690-693 ANCC - Article Numbering Centre of China +70 EAN Norge (Norvege) +729 Israeli Bar Code Association - EAN Israel +73 EAN Suede +740 EAN Guatemala +741 EAN El Salvador +742 ICCC (Honduras) +743 EAN Nicaragua +744 EAN Costa Rica Panama +746 746 EAN Republique Dominicaine +750 AMECE (Mexique) +759 EAN Venezuela +76 EAN (Schweiz, Suisse, Svizzera) +770 IAC (Colombie) +773 EAN Uruguay +775 APC - EAN Peru (Perou) +777 EAN Bolivie +779 CODIGO - EAN Argentine +780 EAN Chili +784 EAN Paraguay +786 ECOP (Equateur) +789 EAN Bresil +80 - 83 INDICOD (Italy) +84 AECOC (Espagne) +850 Camera de Comercio de la Republica de Cuba (Cuba) +858 EAN Slovaquie +859 EAN Republique Tcheque +860 EAN YU (Yougoslavie) +867 EAN DPR Korea (Coree du Nord) +869 Union of Chambers of Commerce of Turkey (Turquie) +87 EAN Nederland (Hollande) +880 EAN Korea (Coree du Sud) +885 EAN Thailande +888 SANC (Singapour) +890 EAN Inde +893 EAN Vietnam +899 EAN Indonesie +90 - 91 EAN Autriche +93 EAN Australie +94 EAN Nouvelle Zelande +955 Malaysian Article Numbering Council (MANC) - Malaisie +977 Publications sirielles (ISSN) +978 - 979 Livres (ISBN) +980 Refus de remboursement +981 - 982 Coupons (monnaie courante) +99 Coupons diff --git a/dev/resources/iso-normes/currencies_iso-4217.txt b/dev/resources/iso-normes/currencies_iso-4217.txt index bc392b72e9c..e24faa4283e 100644 --- a/dev/resources/iso-normes/currencies_iso-4217.txt +++ b/dev/resources/iso-normes/currencies_iso-4217.txt @@ -1,8 +1,12 @@ # File of all ISO-4217 currencies codes -# http://en.wikipedia.org/wiki/ISO_4217 -# http://fx.sauder.ubc.ca/currency_table.html for symbols for 2 letter code # -# Code,Name,Nb decimals +# https://en.wikipedia.org/wiki/ISO_4217 +# https://en.wikipedia.org/wiki/Currency_symbol for symbols for 2 letter code +# + + +# Code, Currency Name, Nb decimals + AED,UAE Dirham,2 AFN,Afghanistan Afghani,2 ALL,Albanian Lek,2 diff --git a/dev/setup/apache/virtualhost b/dev/setup/apache/virtualhost index c3a2dff3e43..8c7682fe3d9 100644 --- a/dev/setup/apache/virtualhost +++ b/dev/setup/apache/virtualhost @@ -1,62 +1,93 @@ -#php_admin_value sendmail_path "/usr/sbin/sendmail -t -i" -#php_admin_value mail.force_extra_parameters "-f postmaster@mydomain.com" -php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f postmaster@mydomain.com" -php_admin_value open_basedir /tmp/:/home/../htdocs + #php_admin_value sendmail_path "/usr/sbin/sendmail -t -i" + #php_admin_value mail.force_extra_parameters "-f postmaster@mydomain.com" + php_admin_value sendmail_path "/usr/sbin/sendmail -t -i -f postmaster@mydomain.com" + php_admin_value open_basedir /tmp/:/home/.../htdocs:/home/.../dolibarr_documents: + + ServerName myvirtualalias + ServerAlias myvirtualalias + + UseCanonicalName On + + KeepAlive On + KeepAliveTimeout 5 + MaxKeepAliveRequests 20 + + AddDefaultCharset UTF-8 + + DocumentRoot "/home/.../htdocs" + + + AllowOverride None + Options -Indexes -MultiViews +FollowSymLinks -ExecCGI + Require all granted -ServerName myvirtualalias -ServerAlias myvirtualalias + # To restrict access by a HTTP basic auth + #AuthType Basic + #AuthName "Authenticate to backoffice" + #AuthUserFile /etc/apache2/.htpasswd + #require valid-user + + + # Leaving /public and /api, /dav, .well_known but also wrappers for document and viewimage accessible to everyone + + AuthType None + Require all granted + Satisfy any + + + AuthType None + Require all granted + Satisfy any + + + AuthType None + Require all granted + Satisfy any + + + AuthType None + Require all granted + Satisfy any + + + AuthType None + Require all granted + Satisfy any + -UseCanonicalName On - -AddDefaultCharset UTF-8 - -DocumentRoot "/home/.../htdocs" - - - AllowOverride None - Options -Indexes -MultiViews +FollowSymLinks -ExecCGI - Require all granted - - - - Deny from all - RemoveHandler .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml - AddType application/x-httpd-php-source .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml - - - -ErrorLog /var/log/apache2/myvirtualalias_error_log -TransferLog /var/log/apache2/myvirtualalias_access_log - -# Compress returned resources of type php pages, text file export, css and javascript -AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/x-javascript - -AddType text/javascript .jgz -AddEncoding gzip .jgz -ExpiresActive On -ExpiresByType image/x-icon A2592000 -ExpiresByType image/gif A2592000 -ExpiresByType image/png A2592000 -ExpiresByType image/jpeg A2592000 -ExpiresByType text/css A2592000 -ExpiresByType text/javascript A2592000 -ExpiresByType application/x-javascript A2592000 -ExpiresByType application/javascript A2592000 - -SSLEngine On - -# A self-signed (snakeoil) certificate can be created by installing -# the ssl-cert package. See -# /usr/share/doc/apache2.2-common/README.Debian.gz for more info. -# If both key and certificate are stored in the same file, only the -# SSLCertificateFile directive is needed. -SSLCertificateFile /etc/letsencrypt/live/www.mydomain.com/cert.pem -SSLCertificateKeyFile /etc/letsencrypt/live/www.mydomain.com/privkey.pem -SSLCertificateChainFile /etc/letsencrypt/live/www.mydomain.com/chain.pem - -#RewriteEngine on -#RewriteCond %{SERVER_PORT} ^80$ -#RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [L,R] + + ErrorLog /var/log/apache2/myvirtualalias_error_log + TransferLog /var/log/apache2/myvirtualalias_access_log + + # Compress returned resources of type php pages, text file export, css and javascript + AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/x-javascript + + AddType text/javascript .jgz + AddEncoding gzip .jgz + ExpiresActive On + ExpiresByType image/x-icon A2592000 + ExpiresByType image/gif A2592000 + ExpiresByType image/png A2592000 + ExpiresByType image/jpeg A2592000 + ExpiresByType text/css A2592000 + ExpiresByType text/javascript A2592000 + ExpiresByType application/x-javascript A2592000 + ExpiresByType application/javascript A2592000 + + SSLEngine On + + # A self-signed (snakeoil) certificate can be created by installing + # the ssl-cert package. See + # /usr/share/doc/apache2.2-common/README.Debian.gz for more info. + # If both key and certificate are stored in the same file, only the + # SSLCertificateFile directive is needed. + SSLCertificateFile /etc/letsencrypt/live/www.mydomain.com/cert.pem + SSLCertificateKeyFile /etc/letsencrypt/live/www.mydomain.com/privkey.pem + SSLCertificateChainFile /etc/letsencrypt/live/www.mydomain.com/chain.pem + + #RewriteEngine on + #RewriteCond %{SERVER_PORT} ^80$ + #RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [L,R] diff --git a/dev/tools/test/namespacemig/main.inc.php b/dev/tools/test/namespacemig/main.inc.php index 555a4b36ff5..d46d8e38c1c 100644 --- a/dev/tools/test/namespacemig/main.inc.php +++ b/dev/tools/test/namespacemig/main.inc.php @@ -1,7 +1,7 @@ transnoentities('ErrorCodeCantContainZero'), null, 'errors'); } - /*if (!is_numeric($_POST['code'])) // disabled, code may not be in numeric base - { - $ok = 0; - $msg .= $langs->transnoentities('ErrorFieldFormat', $langs->transnoentities('Code')).'
'; - }*/ } if (GETPOSTISSET("country") && (GETPOST("country") == '0') && ($id != 2)) { $ok = 0; @@ -228,17 +223,17 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { $i = 0; foreach ($listfieldinsert as $f => $value) { if ($value == 'price' || preg_match('/^amount/i', $value) || $value == 'taux') { - $_POST[$listfieldvalue[$i]] = price2num($_POST[$listfieldvalue[$i]], 'MU'); + $_POST[$listfieldvalue[$i]] = price2num(GETPOST($listfieldvalue[$i]), 'MU'); } elseif ($value == 'entity') { $_POST[$listfieldvalue[$i]] = $conf->entity; } if ($i) { $sql .= ","; } - if ($_POST[$listfieldvalue[$i]] == '') { + if (GETPOST($listfieldvalue[$i]) == '') { $sql .= "null"; } else { - $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; } $i++; } @@ -276,7 +271,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { $i = 0; foreach ($listfieldmodify as $field) { if ($field == 'price' || preg_match('/^amount/i', $field) || $field == 'taux') { - $_POST[$listfieldvalue[$i]] = price2num($_POST[$listfieldvalue[$i]], 'MU'); + $_POST[$listfieldvalue[$i]] = price2num(GETPOST($listfieldvalue[$i]), 'MU'); } elseif ($field == 'entity') { $_POST[$listfieldvalue[$i]] = $conf->entity; } @@ -284,10 +279,10 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { $sql .= ","; } $sql .= $field."="; - if ($_POST[$listfieldvalue[$i]] == '') { + if (GETPOST($listfieldvalue[$i]) == '') { $sql .= "null"; } else { - $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; } $i++; } diff --git a/htdocs/accountancy/admin/card.php b/htdocs/accountancy/admin/card.php index 91d8257ea7f..f2137d84af9 100644 --- a/htdocs/accountancy/admin/card.php +++ b/htdocs/accountancy/admin/card.php @@ -300,7 +300,7 @@ if ($action == 'create') { // Edit mode if ($action == 'update') { - print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), 0, 'billr'); + print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), 0, 'accounting_account'); print '
'."\n"; print ''; @@ -368,7 +368,7 @@ if ($action == 'create') { // View mode $linkback = ''.$langs->trans("BackToList").''; - print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), -1, 'billr'); + print dol_get_fiche_head($head, 'card', $langs->trans('AccountAccounting'), -1, 'accounting_account'); dol_banner_tab($object, 'ref', $linkback, 1, 'account_number', 'ref'); diff --git a/htdocs/accountancy/admin/categories_list.php b/htdocs/accountancy/admin/categories_list.php index bb629577ab6..c0439445261 100644 --- a/htdocs/accountancy/admin/categories_list.php +++ b/htdocs/accountancy/admin/categories_list.php @@ -148,10 +148,10 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { if ($value == 'formula' && !GETPOST('formula')) { continue; } - if ($value == 'range_account' && empty($_POST['range_account'])) { + if ($value == 'range_account' && !GETPOST('range_account')) { continue; } - if (($value == 'country' || $value == 'country_id') && (!empty($_POST['country_id']))) { + if (($value == 'country' || $value == 'country_id') && GETPOST('country_id')) { continue; } if (!GETPOSTISSET($value) || GETPOST($value) == '') { @@ -195,17 +195,6 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { setEventMessages($langs->transnoentities('ErrorFieldMustBeANumeric', $langs->transnoentities("Position")), null, 'errors'); } - // Clean some parameters - if ($_POST["accountancy_code"] <= 0) { - $_POST["accountancy_code"] = ''; // If empty, we force to null - } - if ($_POST["accountancy_code_sell"] <= 0) { - $_POST["accountancy_code_sell"] = ''; // If empty, we force to null - } - if ($_POST["accountancy_code_buy"] <= 0) { - $_POST["accountancy_code_buy"] = ''; // If empty, we force to null - } - // Si verif ok et action add, on ajoute la ligne if ($ok && GETPOST('actionadd', 'alpha')) { if ($tabrowid[$id]) { @@ -243,7 +232,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { if ($i) { $sql .= ","; } - if ($_POST[$listfieldvalue[$i]] == '' && !$listfieldvalue[$i] == 'formula') { + if (GETPOST($listfieldvalue[$i]) == '' && !$listfieldvalue[$i] == 'formula') { $sql .= "null"; // For vat, we want/accept code = '' } else { $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; @@ -283,8 +272,8 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { } $i = 0; foreach ($listfieldmodify as $field) { - if ($field == 'fk_country' && $_POST['country'] > 0) { - $_POST[$listfieldvalue[$i]] = $_POST['country']; + if ($field == 'fk_country' && GETPOST('country') > 0) { + $_POST[$listfieldvalue[$i]] = GETPOST('country'); } elseif ($field == 'entity') { $_POST[$listfieldvalue[$i]] = $conf->entity; } @@ -292,10 +281,10 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { $sql .= ","; } $sql .= $field."="; - if ($_POST[$listfieldvalue[$i]] == '' && !$listfieldvalue[$i] == 'range_account') { + if (GETPOST($listfieldvalue[$i]) == '' && !$listfieldvalue[$i] == 'range_account') { $sql .= "null"; // For range_account, we want/accept code = '' } else { - $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; } $i++; } diff --git a/htdocs/accountancy/admin/defaultaccounts.php b/htdocs/accountancy/admin/defaultaccounts.php index c99503f95f6..583b12368dc 100644 --- a/htdocs/accountancy/admin/defaultaccounts.php +++ b/htdocs/accountancy/admin/defaultaccounts.php @@ -81,24 +81,25 @@ $list_account[] = '---Others---'; $list_account[] = 'ACCOUNTING_VAT_BUY_ACCOUNT'; $list_account[] = 'ACCOUNTING_VAT_SOLD_ACCOUNT'; $list_account[] = 'ACCOUNTING_VAT_PAY_ACCOUNT'; -if ($conf->banque->enabled) { +if (!empty($conf->banque->enabled)) { $list_account[] = 'ACCOUNTING_ACCOUNT_TRANSFER_CASH'; } -if ($conf->don->enabled) { +if (!empty($conf->don->enabled)) { $list_account[] = 'DONATION_ACCOUNTINGACCOUNT'; } -if ($conf->adherent->enabled) { +if (!empty($conf->adherent->enabled)) { $list_account[] = 'ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT'; } -if ($conf->loan->enabled) { +if (!empty($conf->loan->enabled)) { $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_CAPITAL'; $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INTEREST'; $list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INSURANCE'; } -if ($conf->societe->enabled) { +$list_account[] = 'ACCOUNTING_ACCOUNT_SUSPENSE'; +if (!empty($conf->societe->enabled)) { + $list_account[] = '---Deposits---'; $list_account[] = 'ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT'; } -$list_account[] = 'ACCOUNTING_ACCOUNT_SUSPENSE'; /* * Actions @@ -134,6 +135,20 @@ if ($action == 'update') { } } +if ($action == 'setdisableauxiliaryaccountoncustomerdeposit') { + $setDisableAuxiliaryAccountOnCustomerDeposit = GETPOST('value', 'int'); + $res = dolibarr_set_const($db, "ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT", $setDisableAuxiliaryAccountOnCustomerDeposit, 'yesno', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } + + if (!$error) { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } else { + setEventMessages($langs->trans("Error"), null, 'mesgs'); + } +} + /* * View @@ -231,6 +246,20 @@ foreach ($list_account as $key) { } } +if (!empty($conf->societe->enabled)) { + print ''; + print '' . img_picto('', 'bill', 'class="pictofixedwidth"') . $langs->trans("UseAuxiliaryAccountOnCustomerDeposit") . ''; + if (!empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT)) { + print ''; + print img_picto($langs->trans("Activated"), 'switch_on', '', false, 0, 0, '', 'warning'); + print ''; + } else { + print ''; + print img_picto($langs->trans("Disabled"), 'switch_off'); + print ''; + } + print ''; +} print "\n"; print "\n"; diff --git a/htdocs/accountancy/admin/export.php b/htdocs/accountancy/admin/export.php index 8cef3a05cf4..430c7b6abae 100644 --- a/htdocs/accountancy/admin/export.php +++ b/htdocs/accountancy/admin/export.php @@ -24,7 +24,7 @@ /** * \file htdocs/accountancy/admin/export.php * \ingroup Accountancy (Double entries) - * \brief Setup page to configure accounting expert module + * \brief Setup page to configure accounting export module */ require '../../main.inc.php'; @@ -47,7 +47,8 @@ $main_option = array( 'ACCOUNTING_EXPORT_PREFIX_SPEC', ); -$configuration = AccountancyExport::getTypeConfig(); +$accountancyexport = new AccountancyExport($db); +$configuration = $accountancyexport->getTypeConfig(); $listparam = $configuration['param']; @@ -117,7 +118,7 @@ if ($action == 'update') { if (!$error) { // reload - $configuration = AccountancyExport::getTypeConfig(); + $configuration = $accountancyexport->getTypeConfig(); $listparam = $configuration['param']; setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); } else { @@ -237,7 +238,7 @@ if (!$conf->use_javascript_ajax) { print ""; } else { print ''; - $listmodelcsv = AccountancyExport::getType(); + $listmodelcsv = $accountancyexport->getType(); print $form->selectarray("ACCOUNTING_EXPORT_MODELCSV", $listmodelcsv, $conf->global->ACCOUNTING_EXPORT_MODELCSV, 0, 0, 0, '', 0, 0, 0, '', '', 1); print ''; diff --git a/htdocs/accountancy/admin/productaccount.php b/htdocs/accountancy/admin/productaccount.php index 847891c949b..c8cb62cd7e0 100644 --- a/htdocs/accountancy/admin/productaccount.php +++ b/htdocs/accountancy/admin/productaccount.php @@ -1,10 +1,10 @@ - * Copyright (C) 2013-2021 Alexandre Spangaro - * Copyright (C) 2014 Florian Henry - * Copyright (C) 2014 Juanjo Menent - * Copyright (C) 2015 Ari Elbaz (elarifr) - * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2013-2022 Alexandre Spangaro + * Copyright (C) 2014 Florian Henry + * Copyright (C) 2014 Juanjo Menent + * Copyright (C) 2015 Ari Elbaz (elarifr) + * Copyright (C) 2021 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,6 +34,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +if (!empty($conf->categorie->enabled)) { + require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; +} // Load translation files required by the page $langs->loadLangs(array("companies", "compta", "accountancy", "products")); @@ -59,6 +62,8 @@ $account_number_sell = GETPOST('account_number_sell'); $changeaccount = GETPOST('changeaccount', 'array'); $changeaccount_buy = GETPOST('changeaccount_buy', 'array'); $changeaccount_sell = GETPOST('changeaccount_sell', 'array'); +$searchCategoryProductOperator = (GETPOST('search_category_product_operator', 'int') ? GETPOST('search_category_product_operator', 'int') : 0); +$searchCategoryProductList = GETPOST('search_category_product_list', 'array'); $search_ref = GETPOST('search_ref', 'alpha'); $search_label = GETPOST('search_label', 'alpha'); $search_desc = GETPOST('search_desc', 'alpha'); @@ -144,6 +149,8 @@ if ($reshook < 0) { // Purge search criteria if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All test are required to be compatible with all browsers + $searchCategoryProductOperator = 0; + $searchCategoryProductList = array(); $search_ref = ''; $search_label = ''; $search_desc = ''; @@ -283,7 +290,16 @@ $aacompta_prodsell = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_ACCOUN $aacompta_prodsell_intra = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT', $langs->trans("CodeNotDef")); $aacompta_prodsell_export = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT', $langs->trans("CodeNotDef")); -llxHeader('', $langs->trans("ProductsBinding")); + +$title = $langs->trans("ProductsBinding"); +$helpurl = ''; + +$paramsCat = ''; +foreach ($searchCategoryProductList as $searchCategoryProduct) { + $paramsCat .= "&search_category_product_list[]=".urlencode($searchCategoryProduct); +} + +llxHeader('', $title, $helpurl, '', 0, 0, array(), array(), $paramsCat, ''); $pcgverid = getDolGlobalString('CHARTOFACCOUNTS'); $pcgvercode = dol_getIdFromCode($db, $pcgverid, 'accounting_system', 'rowid', 'pcg_version'); @@ -308,6 +324,9 @@ if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) { } else { $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.account_number = p." . $accountancy_field_name . " AND aa.fk_pcg_version = '" . $db->escape($pcgvercode) . "'"; } +if (!empty($searchCategoryProductList)) { + $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_product as cp ON p.rowid = cp.fk_product"; // We'll need this table joined to the select in order to filter by categ +} $sql .= ' WHERE p.entity IN ('.getEntity('product').')'; if (strlen(trim($search_current_account))) { $sql .= natural_search((empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED) ? "p." : "ppe.") . $accountancy_field_name, $search_current_account); @@ -318,6 +337,30 @@ if ($search_current_account_valid == 'withoutvalidaccount') { if ($search_current_account_valid == 'withvalidaccount') { $sql .= " AND aa.account_number IS NOT NULL"; } +$searchCategoryProductSqlList = array(); +if ($searchCategoryProductOperator == 1) { + foreach ($searchCategoryProductList as $searchCategoryProduct) { + if (intval($searchCategoryProduct) == -2) { + $searchCategoryProductSqlList[] = "cp.fk_categorie IS NULL"; + } elseif (intval($searchCategoryProduct) > 0) { + $searchCategoryProductSqlList[] = "cp.fk_categorie = ".$db->escape($searchCategoryProduct); + } + } + if (!empty($searchCategoryProductSqlList)) { + $sql .= " AND (".implode(' OR ', $searchCategoryProductSqlList).")"; + } +} else { + foreach ($searchCategoryProductList as $searchCategoryProduct) { + if (intval($searchCategoryProduct) == -2) { + $searchCategoryProductSqlList[] = "cp.fk_categorie IS NULL"; + } elseif (intval($searchCategoryProduct) > 0) { + $searchCategoryProductSqlList[] = "p.rowid IN (SELECT fk_product FROM ".MAIN_DB_PREFIX."categorie_product WHERE fk_categorie = ".((int) $searchCategoryProduct).")"; + } + } + if (!empty($searchCategoryProductSqlList)) { + $sql .= " AND (".implode(' AND ', $searchCategoryProductSqlList).")"; + } +} // Add search filter like if (strlen(trim($search_ref))) { $sql .= natural_search("p.ref", $search_ref); @@ -338,12 +381,22 @@ if ($search_onpurchase != '' && $search_onpurchase != '-1') { $sql .= natural_search('p.tobuy', $search_onpurchase, 1); } +$sql .= " GROUP BY p.rowid, p.ref, p.label, p.description, p.tosell, p.tobuy, p.tva_tx,"; +$sql .= " p.fk_product_type,"; +$sql .= ' p.tms,'; +$sql .= ' aa.rowid,'; +if (empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) { + $sql .= " p.accountancy_code_sell, p.accountancy_code_sell_intra, p.accountancy_code_sell_export, p.accountancy_code_buy, p.accountancy_code_buy_intra, p.accountancy_code_buy_export"; +} else { + $sql .= " ppe.accountancy_code_sell, ppe.accountancy_code_sell_intra, ppe.accountancy_code_sell_export, ppe.accountancy_code_buy, ppe.accountancy_code_buy_intra, ppe.accountancy_code_buy_export"; +} + $sql .= $db->order($sortfield, $sortorder); $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + $resql = $db->query($sql); + $nbtotalofrecords = $db->num_rows($resql); if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; @@ -353,9 +406,9 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $sql .= $db->plimit($limit + 1, $offset); dol_syslog("/accountancy/admin/productaccount.php", LOG_DEBUG); -$result = $db->query($sql); -if ($result) { - $num = $db->num_rows($result); +$resql = $db->query($sql); +if ($resql) { + $num = $db->num_rows($resql); $i = 0; $param = ''; @@ -365,11 +418,17 @@ if ($result) { if ($limit > 0 && $limit != $conf->liste_limit) { $param .= '&limit='.urlencode($limit); } + if ($searchCategoryProductOperator == 1) { + $param .= "&search_category_product_operator=".urlencode($searchCategoryProductOperator); + } + foreach ($searchCategoryProductList as $searchCategoryProduct) { + $param .= "&search_category_product_list[]=".urlencode($searchCategoryProduct); + } if ($search_ref > 0) { - $param .= "&search_desc=".urlencode($search_ref); + $param .= "&search_ref=".urlencode($search_ref); } if ($search_label > 0) { - $param .= "&search_desc=".urlencode($search_label); + $param .= "&search_label=".urlencode($search_label); } if ($search_desc > 0) { $param .= "&search_desc=".urlencode($search_desc); @@ -461,6 +520,40 @@ if ($result) { print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmPreselectAccount"), $langs->trans("ConfirmPreselectAccountQuestion", count($chk_prod)), "confirm_set_default_account", $formquestion, 1, 0, 200, 500, 1); } + // Filter on categories + $moreforfilter = ''; + if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) { + $moreforfilter .= '
'; + $moreforfilter .= img_picto($langs->trans('Categories'), 'category', 'class="pictofixedwidth"'); + $categoriesProductArr = $form->select_all_categories(Categorie::TYPE_PRODUCT, '', '', 64, 0, 1); + $categoriesProductArr[-2] = '- '.$langs->trans('NotCategorized').' -'; + $moreforfilter .= Form::multiselectarray('search_category_product_list', $categoriesProductArr, $searchCategoryProductList, 0, 0, 'minwidth300'); + $moreforfilter .= ' '.$langs->trans('UseOrOperatorForCategories').''; + $moreforfilter .= '
'; + } + + //Show/hide child products. Hidden by default + if (!empty($conf->variants->enabled) && !empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { + $moreforfilter .= '
'; + $moreforfilter .= ''; + $moreforfilter .= ' '; + $moreforfilter .= '
'; + } + + $parameters = array(); + $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + $moreforfilter .= $hookmanager->resPrint; + } else { + $moreforfilter = $hookmanager->resPrint; + } + + if ($moreforfilter) { + print '
'; + print $moreforfilter; + print '
'; + } + print '
'; print ''; @@ -515,7 +608,7 @@ if ($result) { $i = 0; while ($i < min($num, $limit)) { - $obj = $db->fetch_object($result); + $obj = $db->fetch_object($resql); // Ref produit as link $product_static->ref = $obj->ref; @@ -798,7 +891,7 @@ if ($result) { print ''; - $db->free($result); + $db->free($resql); } else { dol_print_error($db); } diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index 0b67327b11c..7a65fa0ffaa 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -237,7 +237,7 @@ if ($action != 'export_csv') { print ''; $parameters = array(); - $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + $reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { $button = 'global->ACCOUNTING_EXPORT_FORMAT.')" />'; @@ -349,7 +349,7 @@ if ($action != 'export_csv') { $sql .= " GROUP BY t.numero_compte"; $resql = $db->query($sql); - $nrows = $resql->num_rows; + $nrows = $db->num_rows($resql); $opening_balances = array(); for ($i = 0; $i < $nrows; $i++) { $arr = $resql->fetch_array(); diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php index 0fd0b719cd7..61e131ff47d 100644 --- a/htdocs/accountancy/bookkeeping/card.php +++ b/htdocs/accountancy/bookkeeping/card.php @@ -669,7 +669,7 @@ if ($action == 'create') { // Also, it is not possible to use a value that is not in the list. // Also, the label is not automatically filled when a value is selected. if (!empty($conf->global->ACCOUNTANCY_COMBO_FOR_AUX)) { - print $formaccounting->select_auxaccount((GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account), 'subledger_account', 1); + print $formaccounting->select_auxaccount((GETPOSTISSET("subledger_account") ? GETPOST("subledger_account", "alpha") : $line->subledger_account), 'subledger_account', 1, 'maxwidth250', '', 'subledger_label'); } else { print 'subledger_account).'" placeholder="'.dol_escape_htmltag($langs->trans("SubledgerAccount")).'">'; } diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index d6236af5d02..2ee947bf720 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -28,6 +28,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancyexport.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/accountancy/class/lettering.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; @@ -42,6 +43,10 @@ $langs->loadLangs(array("accountancy", "compta")); $socid = GETPOST('socid', 'int'); $action = GETPOST('action', 'aZ09'); +$massaction = GETPOST('massaction', 'alpha'); +$confirm = GETPOST('confirm', 'alpha'); +$toselect = GETPOST('toselect', 'array'); +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'bookkeepinglist'; $search_mvt_num = GETPOST('search_mvt_num', 'int'); $search_doc_type = GETPOST("search_doc_type", 'alpha'); $search_doc_ref = GETPOST("search_doc_ref", 'alpha'); @@ -86,6 +91,7 @@ $search_date_validation_endmonth = GETPOST('search_date_validation_endmonth', ' $search_date_validation_endday = GETPOST('search_date_validation_endday', 'int'); $search_date_validation_start = dol_mktime(0, 0, 0, $search_date_validation_startmonth, $search_date_validation_startday, $search_date_validation_startyear); $search_date_validation_end = dol_mktime(23, 59, 59, $search_date_validation_endmonth, $search_date_validation_endday, $search_date_validation_endyear); +$search_import_key = GETPOST("search_import_key", 'alpha'); //var_dump($search_date_start);exit; if (GETPOST("button_delmvt_x") || GETPOST("button_delmvt.x") || GETPOST("button_delmvt")) { @@ -191,13 +197,15 @@ $arrayfields = array( 't.tms'=>array('label'=>$langs->trans("DateModification"), 'checked'=>0), 't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1), 't.date_validated'=>array('label'=>$langs->trans("DateValidationAndLock"), 'checked'=>1), + 't.import_key'=>array('label'=>$langs->trans("ImportId"), 'checked'=>0, 'position'=>1100), ); if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { unset($arrayfields['t.lettering_code']); } -$listofformat = AccountancyExport::getType(); +$accountancyexport = new AccountancyExport($db); +$listofformat = $accountancyexport->getType(); $formatexportset = $conf->global->ACCOUNTING_EXPORT_MODELCSV; if (empty($listofformat[$formatexportset])) { $formatexportset = 1; @@ -220,10 +228,12 @@ if (empty($user->rights->accounting->mouvements->lire)) { * Actions */ +$param = ''; + if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; } -if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { +if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'preunlettering' && $massaction != 'predeletebookkeepingwriting') { $massaction = ''; } @@ -294,10 +304,11 @@ if (empty($reshook)) { $search_credit = ''; $search_lettering_code = ''; $search_not_reconciled = ''; + $search_import_key = ''; + $toselect = array(); } // Must be after the remove filter action, before the export. - $param = ''; $filter = array(); if (!empty($search_date_start)) { $filter['t.doc_date>='] = $search_date_start; @@ -416,77 +427,143 @@ if (empty($reshook)) { $filter['t.reconciled_option'] = $search_not_reconciled; $param .= '&search_not_reconciled='.urlencode($search_not_reconciled); } -} + if (!empty($search_import_key)) { + $filter['t.import_key'] = $search_import_key; + $param .= '&search_import_key='.urlencode($search_import_key); + } -if ($action == 'delbookkeeping' && $user->rights->accounting->mouvements->supprimer) { - $import_key = GETPOST('importkey', 'alpha'); - - if (!empty($import_key)) { - $result = $object->deleteByImportkey($import_key); - if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); + //if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouvements->supprimer_tous) { + // $delmonth = GETPOST('delmonth', 'int'); + // $delyear = GETPOST('delyear', 'int'); + // if ($delyear == -1) { + // $delyear = 0; + // } + // $deljournal = GETPOST('deljournal', 'alpha'); + // if ($deljournal == -1) { + // $deljournal = 0; + // } + // + // if (!empty($delmonth) || !empty($delyear) || !empty($deljournal)) { + // $result = $object->deleteByYearAndJournal($delyear, $deljournal, '', ($delmonth > 0 ? $delmonth : 0)); + // if ($result < 0) { + // setEventMessages($object->error, $object->errors, 'errors'); + // } else { + // setEventMessages("RecordDeleted", null, 'mesgs'); + // } + // + // // Make a redirect to avoid to launch the delete later after a back button + // header("Location: list.php".($param ? '?'.$param : '')); + // exit; + // } else { + // setEventMessages("NoRecordDeleted", null, 'warnings'); + // } + //} + if ($action == 'setreexport') { + $setreexport = GETPOST('value', 'int'); + if (!dolibarr_set_const($db, "ACCOUNTING_REEXPORT", $setreexport, 'yesno', 0, '', $conf->entity)) { + $error++; } - // Make a redirect to avoid to launch the delete later after a back button - header("Location: list.php".($param ? '?'.$param : '')); - exit; - } -} -if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouvements->supprimer_tous) { - $delmonth = GETPOST('delmonth', 'int'); - $delyear = GETPOST('delyear', 'int'); - if ($delyear == -1) { - $delyear = 0; - } - $deljournal = GETPOST('deljournal', 'alpha'); - if ($deljournal == -1) { - $deljournal = 0; - } - - if (!empty($delmonth) || !empty($delyear) || !empty($deljournal)) { - $result = $object->deleteByYearAndJournal($delyear, $deljournal, '', ($delmonth > 0 ? $delmonth : 0)); - if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); + if (!$error) { + if ($conf->global->ACCOUNTING_REEXPORT == 1) { + setEventMessages($langs->trans("ExportOfPiecesAlreadyExportedIsEnable"), null, 'mesgs'); + } else { + setEventMessages($langs->trans("ExportOfPiecesAlreadyExportedIsDisable"), null, 'mesgs'); + } } else { - setEventMessages("RecordDeleted", null, 'mesgs'); + setEventMessages($langs->trans("Error"), null, 'errors'); } - - // Make a redirect to avoid to launch the delete later after a back button - header("Location: list.php".($param ? '?'.$param : '')); - exit; - } else { - setEventMessages("NoRecordDeleted", null, 'warnings'); - } -} -if ($action == 'delmouvconfirm' && $user->rights->accounting->mouvements->supprimer) { - $mvt_num = GETPOST('mvt_num', 'int'); - - if (!empty($mvt_num)) { - $result = $object->deleteMvtNum($mvt_num); - if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); - } else { - setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs'); - } - - header("Location: list.php?noreset=1".($param ? '&'.$param : '')); - exit; - } -} -if ($action == 'setreexport') { - $setreexport = GETPOST('value', 'int'); - if (!dolibarr_set_const($db, "ACCOUNTING_REEXPORT", $setreexport, 'yesno', 0, '', $conf->entity)) { - $error++; } - if (!$error) { - if ($conf->global->ACCOUNTING_REEXPORT == 1) { - setEventMessages($langs->trans("ExportOfPiecesAlreadyExportedIsEnable"), null, 'mesgs'); - } else { - setEventMessages($langs->trans("ExportOfPiecesAlreadyExportedIsDisable"), null, 'mesgs'); + // Mass actions + $objectclass = 'Bookkeeping'; + $objectlabel = 'Bookkeeping'; + $permissiontoread = $user->rights->societe->lire; + $permissiontodelete = $user->rights->societe->supprimer; + $permissiontoadd = $user->rights->societe->creer; + $uploaddir = $conf->societe->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + + if (!$error && $action == 'deletebookkeepingwriting' && $confirm == "yes" && $user->rights->accounting->mouvements->supprimer) { + $nbok = 0; + foreach ($toselect as $toselectid) { + $result = $object->fetch($toselectid); + if ($result > 0 && (!isset($object->date_validation) || $object->date_validation === '')) { + $result = $object->deleteMvtNum($object->piece_num); + if ($result > 0) { + $nbok++; + } else { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + break; + } + } elseif ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + break; + } + } + + // Message for elements well deleted + if ($nbok > 1) { + setEventMessages($langs->trans("RecordsDeleted", $nbok), null, 'mesgs'); + } elseif ($nbok > 0) { + setEventMessages($langs->trans("RecordDeleted", $nbok), null, 'mesgs'); + } elseif (!$error) { + setEventMessages($langs->trans("NoRecordDeleted"), null, 'mesgs'); + } + + if (!$error) { + header("Location: ".$_SERVER["PHP_SELF"]."?noreset=1".($param ? '&'.$param : '')); + exit; + } + } + + // others mass actions + if (!$error && getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && $user->rights->accounting->mouvements->creer) { + if ($massaction == 'lettering') { + $lettering = new Lettering($db); + $nb_lettering = $lettering->bookkeepingLetteringAll($toselect); + if ($nb_lettering < 0) { + setEventMessages('', $lettering->errors, 'errors'); + $error++; + $nb_lettering = max(0, abs($nb_lettering) - 2); + } elseif ($nb_lettering == 0) { + $nb_lettering = 0; + setEventMessages($langs->trans('AccountancyNoLetteringModified'), array(), 'mesgs'); + } + if ($nb_lettering == 1) { + setEventMessages($langs->trans('AccountancyOneLetteringModifiedSuccessfully'), array(), 'mesgs'); + } elseif ($nb_lettering > 1) { + setEventMessages($langs->trans('AccountancyLetteringModifiedSuccessfully', $nb_lettering), array(), 'mesgs'); + } + + if (!$error) { + header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param); + exit(); + } + } elseif ($action == 'unlettering' && $confirm == "yes") { + $lettering = new Lettering($db); + $nb_lettering = $lettering->bookkeepingLetteringAll($toselect, true); + if ($nb_lettering < 0) { + setEventMessages('', $lettering->errors, 'errors'); + $error++; + $nb_lettering = max(0, abs($nb_lettering) - 2); + } elseif ($nb_lettering == 0) { + $nb_lettering = 0; + setEventMessages($langs->trans('AccountancyNoUnletteringModified'), array(), 'mesgs'); + } + if ($nb_lettering == 1) { + setEventMessages($langs->trans('AccountancyOneUnletteringModifiedSuccessfully'), array(), 'mesgs'); + } elseif ($nb_lettering > 1) { + setEventMessages($langs->trans('AccountancyUnletteringModifiedSuccessfully', $nb_lettering), array(), 'mesgs'); + } + + if (!$error) { + header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param); + exit(); + } } - } else { - setEventMessages($langs->trans("Error"), null, 'errors'); } } @@ -520,7 +597,8 @@ $sql .= " t.piece_num,"; $sql .= " t.date_creation,"; $sql .= " t.tms as date_modification,"; $sql .= " t.date_export,"; -$sql .= " t.date_validated as date_validation"; +$sql .= " t.date_validated as date_validation,"; +$sql .= " t.import_key"; $sql .= ' FROM '.MAIN_DB_PREFIX.$object->table_element.' as t'; // Manage filter $sqlwhere = array(); @@ -667,6 +745,7 @@ if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) { $num = $db->num_rows($resql); } +$arrayofselected = is_array($toselect) ? $toselect : array(); // Output page // -------------------------------------------------------------------- @@ -684,7 +763,7 @@ if ($action == 'export_file') { 'name' => 'notifiedexportdate', 'type' => 'checkbox', 'label' => $langs->trans('NotifiedExportDate'), - 'value' => $checked, + 'value' => (!empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) ? 'false' : 'true'), ); $form_question['separator'] = array('name'=>'separator', 'type'=>'separator'); @@ -703,50 +782,46 @@ if ($action == 'export_file') { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', $langs->trans('ConfirmExportFile'), 'export_fileconfirm', $form_question, '', 1, 300, 600); } -if ($action == 'delmouv') { - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?mvt_num='.urlencode(GETPOST('mvt_num')).$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvtPartial'), 'delmouvconfirm', '', 0, 1); -} - -if ($action == 'delbookkeepingyear') { - $form_question = array(); - $delyear = GETPOST('delyear', 'int'); - $deljournal = GETPOST('deljournal', 'alpha'); - - if (empty($delyear)) { - $delyear = dol_print_date(dol_now(), '%Y'); - } - $month_array = array(); - for ($i = 1; $i <= 12; $i++) { - $month_array[$i] = $langs->trans("Month".sprintf("%02d", $i)); - } - $year_array = $formaccounting->selectyear_accountancy_bookkepping($delyear, 'delyear', 0, 'array'); - $journal_array = $formaccounting->select_journal($deljournal, 'deljournal', '', 1, 1, 1, '', 0, 1); - - $form_question['delmonth'] = array( - 'name' => 'delmonth', - 'type' => 'select', - 'label' => $langs->trans('DelMonth'), - 'values' => $month_array, - 'morecss' => 'minwidth150', - 'default' => '' - ); - $form_question['delyear'] = array( - 'name' => 'delyear', - 'type' => 'select', - 'label' => $langs->trans('DelYear'), - 'values' => $year_array, - 'default' => $delyear - ); - $form_question['deljournal'] = array( - 'name' => 'deljournal', - 'type' => 'other', // We don't use select here, the journal_array is already a select html component - 'label' => $langs->trans('DelJournal'), - 'value' => $journal_array, - 'default' => $deljournal - ); - - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'delbookkeepingyearconfirm', $form_question, '', 1, 320); -} +//if ($action == 'delbookkeepingyear') { +// $form_question = array(); +// $delyear = GETPOST('delyear', 'int'); +// $deljournal = GETPOST('deljournal', 'alpha'); +// +// if (empty($delyear)) { +// $delyear = dol_print_date(dol_now(), '%Y'); +// } +// $month_array = array(); +// for ($i = 1; $i <= 12; $i++) { +// $month_array[$i] = $langs->trans("Month".sprintf("%02d", $i)); +// } +// $year_array = $formaccounting->selectyear_accountancy_bookkepping($delyear, 'delyear', 0, 'array'); +// $journal_array = $formaccounting->select_journal($deljournal, 'deljournal', '', 1, 1, 1, '', 0, 1); +// +// $form_question['delmonth'] = array( +// 'name' => 'delmonth', +// 'type' => 'select', +// 'label' => $langs->trans('DelMonth'), +// 'values' => $month_array, +// 'morecss' => 'minwidth150', +// 'default' => '' +// ); +// $form_question['delyear'] = array( +// 'name' => 'delyear', +// 'type' => 'select', +// 'label' => $langs->trans('DelYear'), +// 'values' => $year_array, +// 'default' => $delyear +// ); +// $form_question['deljournal'] = array( +// 'name' => 'deljournal', +// 'type' => 'other', // We don't use select here, the journal_array is already a select html component +// 'label' => $langs->trans('DelJournal'), +// 'value' => $journal_array, +// 'default' => $deljournal +// ); +// +// $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'delbookkeepingyearconfirm', $form_question, '', 1, 320); +//} // Print form confirm print $formconfirm; @@ -759,6 +834,22 @@ if ($limit > 0 && $limit != $conf->liste_limit) { $param .= '&limit='.urlencode($limit); } +// List of mass actions available +$arrayofmassactions = array(); +/* +if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && $user->rights->accounting->mouvements->creer) { + $arrayofmassactions['lettering'] = img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans('Lettering'); + $arrayofmassactions['preunlettering'] = img_picto('', 'uncheck', 'class="pictofixedwidth"') . $langs->trans('Unlettering'); +} +*/ +if ($user->rights->accounting->mouvements->supprimer) { + $arrayofmassactions['predeletebookkeepingwriting'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); +} +if (GETPOST('nomassaction', 'int') || in_array($massaction, array('preunlettering', 'predeletebookkeepingwriting'))) { + $arrayofmassactions = array(); +} +$massactionbutton = $form->selectMassAction($massaction, $arrayofmassactions); + print ''; print ''; print ''; @@ -768,8 +859,7 @@ if ($optioncss != '') { print ''; print ''; print ''; - -$massactionbutton = ''; +print ''; if (count($filter)) { $buttonLabel = $langs->trans("ExportFilteredList"); @@ -778,7 +868,7 @@ if (count($filter)) { } $parameters = array(); -$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { // Button re-export if (!empty($conf->global->ACCOUNTING_REEXPORT)) { @@ -794,7 +884,7 @@ if (empty($reshook)) { $newcardbutton .= dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly')); - $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly')); + $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?type=sub'.$param, '', 1, array('morecss' => 'marginleftonly')); $url = './card.php?action=create'; if (!empty($socid)) { @@ -805,9 +895,21 @@ if (empty($reshook)) { print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1); +if ($massaction == 'preunlettering') { + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassUnlettering"), $langs->trans("ConfirmMassUnletteringQuestion", count($toselect)), "unlettering", null, '', 0, 200, 500, 1); +} elseif ($massaction == 'predeletebookkeepingwriting') { + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassDeleteBookkeepingWriting"), $langs->trans("ConfirmMassDeleteBookkeepingWritingQuestion", count($toselect)), "deletebookkeepingwriting", null, '', 0, 200, 500, 1); +} + +//$topicmail = "Information"; +//$modelmail = "accountingbookkeeping"; +//$objecttmp = new BookKeeping($db); +//$trackid = 'bk'.$object->id; +include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; + $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields -if ($massactionbutton) { +if ($massactionbutton && $contextpage != 'poslist') { $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); } @@ -954,6 +1056,11 @@ if (!empty($arrayfields['t.date_validated']['checked'])) { print ''; print ''; } +if (!empty($arrayfields['t.import_key']['checked'])) { + print ''; +} // Action column print '\n"; @@ -1252,17 +1362,21 @@ while ($i < min($num, $limit)) { } } - // Action column - print '\n"; + if (!$i) { + $totalarray['nbfield']++; } } - if (empty($line->date_validation)) { - if ($user->rights->accounting->mouvements->supprimer) { - print ''.img_delete().''; + + // Action column + print ''; @@ -1283,11 +1397,11 @@ print "
'; + print ''; + print ''; $searchpicto = $form->showFilterButtons(); @@ -1008,6 +1115,9 @@ if (!empty($arrayfields['t.date_export']['checked'])) { if (!empty($arrayfields['t.date_validated']['checked'])) { print_liste_field_titre($arrayfields['t.date_validated']['label'], $_SERVER['PHP_SELF'], "t.date_validated", "", $param, '', $sortfield, $sortorder, 'center '); } +if (!empty($arrayfields['t.import_key']['checked'])) { + print_liste_field_titre($arrayfields['t.import_key']['label'], $_SERVER["PHP_SELF"], "t.import_key", "", $param, '', $sortfield, $sortorder, 'center '); +} print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); print "
'; - if (empty($line->date_export) && empty($line->date_validation)) { - if ($user->rights->accounting->mouvements->creer) { - print '' . img_edit() . ''; + if (!empty($arrayfields['t.import_key']['checked'])) { + print ''.$obj->import_key."'; + if (($massactionbutton || $massaction) && $contextpage != 'poslist') { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($line->id, $arrayofselected)) { + $selected = 1; } + print ''; } print '
"; print '
'; // TODO Replace this with mass delete action -if ($user->rights->accounting->mouvements->supprimer_tous) { - print '
'."\n"; - print ''.$langs->trans("DeleteMvt").''; - print '
'; -} +//if ($user->rights->accounting->mouvements->supprimer_tous) { +// print '
'."\n"; +// print ''.$langs->trans("DeleteMvt").''; +// print '
'; +//} print ''; diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index d73f4228f97..80b2efe7050 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -28,6 +28,7 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/accountancy/class/lettering.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; @@ -39,6 +40,16 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; $langs->loadLangs(array("accountancy", "compta")); $action = GETPOST('action', 'aZ09'); +$massaction = GETPOST('massaction', 'alpha'); +$confirm = GETPOST('confirm', 'alpha'); +$toselect = GETPOST('toselect', 'array'); +$type = GETPOST('type', 'alpha'); +if ($type == 'sub') { + $context_default = 'bookkeepingbysubaccountlist'; +} else { + $context_default = 'bookkeepingbyaccountlist'; +} +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : $context_default; $search_date_startyear = GETPOST('search_date_startyear', 'int'); $search_date_startmonth = GETPOST('search_date_startmonth', 'int'); $search_date_startday = GETPOST('search_date_startday', 'int'); @@ -64,6 +75,7 @@ $search_date_validation_endmonth = GETPOST('search_date_validation_endmonth', ' $search_date_validation_endday = GETPOST('search_date_validation_endday', 'int'); $search_date_validation_start = dol_mktime(0, 0, 0, $search_date_validation_startmonth, $search_date_validation_startday, $search_date_validation_startyear); $search_date_validation_end = dol_mktime(23, 59, 59, $search_date_validation_endmonth, $search_date_validation_endday, $search_date_validation_endyear); +$search_import_key = GETPOST("search_import_key", 'alpha'); $search_accountancy_code = GETPOST("search_accountancy_code"); $search_accountancy_code_start = GETPOST('search_accountancy_code_start', 'alpha'); @@ -109,7 +121,7 @@ if ($sortfield == "") { // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $object = new BookKeeping($db); $formfile = new FormFile($db); -$hookmanager->initHooks(array('bookkeepingbyaccountlist')); +$hookmanager->initHooks(array($context_default)); $formaccounting = new FormAccounting($db); $form = new Form($db); @@ -153,6 +165,7 @@ $arrayfields = array( 't.lettering_code'=>array('label'=>$langs->trans("LetteringCode"), 'checked'=>1), 't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1), 't.date_validated'=>array('label'=>$langs->trans("DateValidation"), 'checked'=>1), + 't.import_key'=>array('label'=>$langs->trans("ImportId"), 'checked'=>0, 'position'=>1100), ); if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { @@ -187,10 +200,13 @@ if (empty($user->rights->accounting->mouvements->lire)) { * Action */ +$param = ''; + if (GETPOST('cancel', 'alpha')) { - $action = 'list'; $massaction = ''; + $action = 'list'; + $massaction = ''; } -if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { +if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'preunlettering' && $massaction != 'predeletebookkeepingwriting') { $massaction = ''; } @@ -242,10 +258,11 @@ if (empty($reshook)) { $search_credit = ''; $search_lettering_code = ''; $search_not_reconciled = ''; + $search_import_key = ''; + $toselect = array(); } // Must be after the remove filter action, before the export. - $param = ''; $filter = array(); if (!empty($search_date_start)) { @@ -261,12 +278,20 @@ if (empty($reshook)) { $param .= '&doc_datemonth='.GETPOST('doc_datemonth', 'int').'&doc_dateday='.GETPOST('doc_dateday', 'int').'&doc_dateyear='.GETPOST('doc_dateyear', 'int'); } if (!empty($search_accountancy_code_start)) { - $filter['t.numero_compte>='] = $search_accountancy_code_start; - $param .= '&search_accountancy_code_start='.urlencode($search_accountancy_code_start); + if ($type == 'sub') { + $filter['t.subledger_account>='] = $search_accountancy_code_start; + } else { + $filter['t.numero_compte>='] = $search_accountancy_code_start; + } + $param .= '&search_accountancy_code_start=' . urlencode($search_accountancy_code_start); } if (!empty($search_accountancy_code_end)) { - $filter['t.numero_compte<='] = $search_accountancy_code_end; - $param .= '&search_accountancy_code_end='.urlencode($search_accountancy_code_end); + if ($type == 'sub') { + $filter['t.subledger_account<='] = $search_accountancy_code_end; + } else { + $filter['t.numero_compte<='] = $search_accountancy_code_end; + } + $param .= '&search_accountancy_code_end=' . urlencode($search_accountancy_code_end); } if (!empty($search_label_account)) { $filter['t.label_compte'] = $search_label_account; @@ -326,61 +351,133 @@ if (empty($reshook)) { $filter['t.date_validated<='] = $search_date_validation_end; $param .= '&search_date_validation_endmonth='.$search_date_validation_endmonth.'&search_date_validation_endday='.$search_date_validation_endday.'&search_date_validation_endyear='.$search_date_validation_endyear; } -} + if (!empty($search_import_key)) { + $filter['t.import_key'] = $search_import_key; + $param .= '&search_import_key='.urlencode($search_import_key); + } -if ($action == 'delbookkeeping' && $user->rights->accounting->mouvements->supprimer) { - $import_key = GETPOST('importkey', 'alpha'); + // param with type of list + $url_param = substr($param, 1); // remove first "&" + if (!empty($type)) { + $param = '&type='.$type.$param; + } - if (!empty($import_key)) { - $result = $object->deleteByImportkey($import_key); - if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); + //if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouvements->supprimer_tous) { + // $delmonth = GETPOST('delmonth', 'int'); + // $delyear = GETPOST('delyear', 'int'); + // if ($delyear == -1) { + // $delyear = 0; + // } + // $deljournal = GETPOST('deljournal', 'alpha'); + // if ($deljournal == -1) { + // $deljournal = 0; + // } + // + // if (!empty($delmonth) || !empty($delyear) || !empty($deljournal)) { + // $result = $object->deleteByYearAndJournal($delyear, $deljournal, '', ($delmonth > 0 ? $delmonth : 0)); + // if ($result < 0) { + // setEventMessages($object->error, $object->errors, 'errors'); + // } else { + // setEventMessages("RecordDeleted", null, 'mesgs'); + // } + // + // // Make a redirect to avoid to launch the delete later after a back button + // header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : '')); + // exit; + // } else { + // setEventMessages("NoRecordDeleted", null, 'warnings'); + // } + //} + + // Mass actions + $objectclass = 'Bookkeeping'; + $objectlabel = 'Bookkeeping'; + $permissiontoread = $user->rights->societe->lire; + $permissiontodelete = $user->rights->societe->supprimer; + $permissiontoadd = $user->rights->societe->creer; + $uploaddir = $conf->societe->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + + if (!$error && $action == 'deletebookkeepingwriting' && $confirm == "yes" && $user->rights->accounting->mouvements->supprimer) { + $nbok = 0; + foreach ($toselect as $toselectid) { + $result = $object->fetch($toselectid); + if ($result > 0 && (!isset($object->date_validation) || $object->date_validation === '')) { + $result = $object->deleteMvtNum($object->piece_num); + if ($result > 0) { + $nbok++; + } else { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + break; + } + } elseif ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + $error++; + break; + } } - // Make a redirect to avoid to launch the delete later after a back button - header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : '')); - exit; - } -} -if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouvements->supprimer_tous) { - $delmonth = GETPOST('delmonth', 'int'); - $delyear = GETPOST('delyear', 'int'); - if ($delyear == -1) { - $delyear = 0; - } - $deljournal = GETPOST('deljournal', 'alpha'); - if ($deljournal == -1) { - $deljournal = 0; - } - - if (!empty($delmonth) || !empty($delyear) || !empty($deljournal)) { - $result = $object->deleteByYearAndJournal($delyear, $deljournal, '', ($delmonth > 0 ? $delmonth : 0)); - if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); - } else { - setEventMessages("RecordDeleted", null, 'mesgs'); + // Message for elements well deleted + if ($nbok > 1) { + setEventMessages($langs->trans("RecordsDeleted", $nbok), null, 'mesgs'); + } elseif ($nbok > 0) { + setEventMessages($langs->trans("RecordDeleted", $nbok), null, 'mesgs'); + } elseif (!$error) { + setEventMessages($langs->trans("NoRecordDeleted"), null, 'mesgs'); } - // Make a redirect to avoid to launch the delete later after a back button - header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : '')); - exit; - } else { - setEventMessages("NoRecordDeleted", null, 'warnings'); - } -} -if ($action == 'delmouvconfirm' && $user->rights->accounting->mouvements->supprimer) { - $mvt_num = GETPOST('mvt_num', 'int'); - - if (!empty($mvt_num)) { - $result = $object->deleteMvtNum($mvt_num); - if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); - } else { - setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs'); + if (!$error) { + header("Location: ".$_SERVER["PHP_SELF"]."?noreset=1".($param ? '&'.$param : '')); + exit; } + } - header("Location: ".$_SERVER["PHP_SELF"]."?noreset=1".($param ? '&'.$param : '')); - exit; + // others mass actions + if (!$error && getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && $user->rights->accounting->mouvements->creer) { + if ($massaction == 'lettering') { + $lettering = new Lettering($db); + $nb_lettering = $lettering->bookkeepingLetteringAll($toselect); + if ($nb_lettering < 0) { + setEventMessages('', $lettering->errors, 'errors'); + $error++; + $nb_lettering = max(0, abs($nb_lettering) - 2); + } elseif ($nb_lettering == 0) { + $nb_lettering = 0; + setEventMessages($langs->trans('AccountancyNoLetteringModified'), array(), 'mesgs'); + } + if ($nb_lettering == 1) { + setEventMessages($langs->trans('AccountancyOneLetteringModifiedSuccessfully'), array(), 'mesgs'); + } elseif ($nb_lettering > 1) { + setEventMessages($langs->trans('AccountancyLetteringModifiedSuccessfully', $nb_lettering), array(), 'mesgs'); + } + + if (!$error) { + header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param); + exit(); + } + } elseif ($action == 'unlettering' && $confirm == "yes") { + $lettering = new Lettering($db); + $nb_lettering = $lettering->bookkeepingLetteringAll($toselect, true); + if ($nb_lettering < 0) { + setEventMessages('', $lettering->errors, 'errors'); + $error++; + $nb_lettering = max(0, abs($nb_lettering) - 2); + } elseif ($nb_lettering == 0) { + $nb_lettering = 0; + setEventMessages($langs->trans('AccountancyNoUnletteringModified'), array(), 'mesgs'); + } + if ($nb_lettering == 1) { + setEventMessages($langs->trans('AccountancyOneUnletteringModifiedSuccessfully'), array(), 'mesgs'); + } elseif ($nb_lettering > 1) { + setEventMessages($langs->trans('AccountancyUnletteringModifiedSuccessfully', $nb_lettering), array(), 'mesgs'); + } + + if (!$error) { + header('Location: ' . $_SERVER['PHP_SELF'] . '?noreset=1' . $param); + exit(); + } + } } } @@ -394,73 +491,101 @@ $formfile = new FormFile($db); $formother = new FormOther($db); $form = new Form($db); -$title_page = $langs->trans("Operations").' - '.$langs->trans("VueByAccountAccounting").' ('.$langs->trans("Bookkeeping").')'; +$title_page = $langs->trans("Operations").' - '.$langs->trans("VueByAccountAccounting").' ('; +if ($type == 'sub') { + $title_page .= $langs->trans("BookkeepingSubAccount"); +} else { + $title_page .= $langs->trans("Bookkeeping"); +} +$title_page .= ')'; llxHeader('', $title_page); // List $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter); + if ($type == 'sub') { + $nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter, 'AND', 1); + } else { + $nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter); + } + if ($nbtotalofrecords < 0) { setEventMessages($object->error, $object->errors, 'errors'); } } -$result = $object->fetchAllByAccount($sortorder, $sortfield, $limit, $offset, $filter); +if ($type == 'sub') { + $result = $object->fetchAllByAccount($sortorder, $sortfield, $limit, $offset, $filter, 'AND', 1); +} else { + $result = $object->fetchAllByAccount($sortorder, $sortfield, $limit, $offset, $filter); +} if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); } +$arrayofselected = is_array($toselect) ? $toselect : array(); + $num = count($object->lines); -if ($action == 'delmouv') { - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?mvt_num='.GETPOST('mvt_num'), $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvtPartial'), 'delmouvconfirm', '', 0, 1); - print $formconfirm; +///if ($action == 'delbookkeepingyear') { +// $form_question = array(); +// $delyear = GETPOST('delyear', 'int'); +// $deljournal = GETPOST('deljournal', 'alpha'); +// +// if (empty($delyear)) { +// $delyear = dol_print_date(dol_now(), '%Y'); +// } +// $month_array = array(); +// for ($i = 1; $i <= 12; $i++) { +// $month_array[$i] = $langs->trans("Month".sprintf("%02d", $i)); +// } +// $year_array = $formaccounting->selectyear_accountancy_bookkepping($delyear, 'delyear', 0, 'array'); +// $journal_array = $formaccounting->select_journal($deljournal, 'deljournal', '', 1, 1, 1, '', 0, 1); +// +// $form_question['delmonth'] = array( +// 'name' => 'delmonth', +// 'type' => 'select', +// 'label' => $langs->trans('DelMonth'), +// 'values' => $month_array, +// 'default' => '' +// ); +// $form_question['delyear'] = array( +// 'name' => 'delyear', +// 'type' => 'select', +// 'label' => $langs->trans('DelYear'), +// 'values' => $year_array, +// 'default' => $delyear +// ); +// $form_question['deljournal'] = array( +// 'name' => 'deljournal', +// 'type' => 'other', // We don't use select here, the journal_array is already a select html component +// 'label' => $langs->trans('DelJournal'), +// 'value' => $journal_array, +// 'default' => $deljournal +// ); +// +// $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'delbookkeepingyearconfirm', $form_question, '', 1, 300); +//} + +// Print form confirm +print $formconfirm; + +// List of mass actions available +$arrayofmassactions = array(); +if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && $user->rights->accounting->mouvements->creer) { + $arrayofmassactions['lettering'] = img_picto('', 'check', 'class="pictofixedwidth"') . $langs->trans('Lettering'); + $arrayofmassactions['preunlettering'] = img_picto('', 'uncheck', 'class="pictofixedwidth"') . $langs->trans('Unlettering'); } -if ($action == 'delbookkeepingyear') { - $form_question = array(); - $delyear = GETPOST('delyear', 'int'); - $deljournal = GETPOST('deljournal', 'alpha'); - - if (empty($delyear)) { - $delyear = dol_print_date(dol_now(), '%Y'); - } - $month_array = array(); - for ($i = 1; $i <= 12; $i++) { - $month_array[$i] = $langs->trans("Month".sprintf("%02d", $i)); - } - $year_array = $formaccounting->selectyear_accountancy_bookkepping($delyear, 'delyear', 0, 'array'); - $journal_array = $formaccounting->select_journal($deljournal, 'deljournal', '', 1, 1, 1, '', 0, 1); - - $form_question['delmonth'] = array( - 'name' => 'delmonth', - 'type' => 'select', - 'label' => $langs->trans('DelMonth'), - 'values' => $month_array, - 'default' => '' - ); - $form_question['delyear'] = array( - 'name' => 'delyear', - 'type' => 'select', - 'label' => $langs->trans('DelYear'), - 'values' => $year_array, - 'default' => $delyear - ); - $form_question['deljournal'] = array( - 'name' => 'deljournal', - 'type' => 'other', // We don't use select here, the journal_array is already a select html component - 'label' => $langs->trans('DelJournal'), - 'value' => $journal_array, - 'default' => $deljournal - ); - - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'delbookkeepingyearconfirm', $form_question, '', 1, 300); - print $formconfirm; +if ($user->rights->accounting->mouvements->supprimer) { + $arrayofmassactions['predeletebookkeepingwriting'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } - +if (GETPOST('nomassaction', 'int') || in_array($massaction, array('preunlettering', 'predeletebookkeepingwriting'))) { + $arrayofmassactions = array(); +} +$massactionbutton = $form->selectMassAction($massaction, $arrayofmassactions); print '
'; print ''; @@ -469,15 +594,22 @@ if ($optioncss != '') { print ''; } print ''; +print ''; print ''; print ''; +print ''; $parameters = array(); -$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('addMoreActionsButtonsList', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { $newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param); - $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); - $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly')); + if ($type == 'sub') { + $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?' . $url_param, '', 1, array('morecss' => 'marginleftonly')); + $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?type=sub&' . $url_param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); + } else { + $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?' . $url_param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); + $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?type=sub&' . $url_param, '', 1, array('morecss' => 'marginleftonly')); + } $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'); } @@ -488,11 +620,29 @@ if ($limit > 0 && $limit != $conf->liste_limit) { $param .= '&limit='.urlencode($limit); } -print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1); +print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1); + +if ($massaction == 'preunlettering') { + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassUnlettering"), $langs->trans("ConfirmMassUnletteringQuestion", count($toselect)), "unlettering", null, '', 0, 200, 500, 1); +} elseif ($massaction == 'predeletebookkeepingwriting') { + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassDeleteBookkeepingWriting"), $langs->trans("ConfirmMassDeleteBookkeepingWritingQuestion", count($toselect)), "deletebookkeepingwriting", null, '', 0, 200, 500, 1); +} +//DeleteMvt=Supprimer des lignes d'opérations de la comptabilité +//DelMonth=Mois à effacer +//DelYear=Année à supprimer +//DelJournal=Journal à supprimer +//ConfirmDeleteMvt=Cette action supprime les lignes des opérations pour l'année/mois et/ou pour le journal sélectionné (au moins un critère est requis). Vous devrez utiliser de nouveau la fonctionnalité '%s' pour retrouver vos écritures dans la comptabilité. +//ConfirmDeleteMvtPartial=Cette action supprime l'écriture de la comptabilité (toutes les lignes opérations liées à une même écriture seront effacées). + +//$topicmail = "Information"; +//$modelmail = "accountingbookkeeping"; +//$objecttmp = new BookKeeping($db); +//$trackid = 'bk'.$object->id; +include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields -if ($massactionbutton) { +if ($massactionbutton && $contextpage != 'poslist') { $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); } @@ -503,15 +653,28 @@ if (preg_match('/^asc/i', $sortorder)) { $sortorder = "desc"; } +// Warning to explain why list of record is not consistent with the other list view (missing a lot of lines) +if ($type == 'sub') { + print info_admin($langs->trans("WarningRecordWithoutSubledgerAreExcluded")); +} + $moreforfilter = ''; // Accountancy account $moreforfilter .= '
'; $moreforfilter .= $langs->trans('AccountAccounting').': '; $moreforfilter .= '
'; -$moreforfilter .= $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth200'); +if ($type == 'sub') { + $moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), 'maxwidth200'); +} else { + $moreforfilter .= $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth200'); +} $moreforfilter .= ' '; -$moreforfilter .= $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth200'); +if ($type == 'sub') { + $moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), 'maxwidth200'); +} else { + $moreforfilter .= $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth200'); +} $moreforfilter .= '
'; $moreforfilter .= '
'; @@ -599,6 +762,11 @@ if (!empty($arrayfields['t.date_validated']['checked'])) { print ''; print ''; } +if (!empty($arrayfields['t.import_key']['checked'])) { + print ''; + print ''; + print ''; +} // Fields from hook $parameters = array('arrayfields'=>$arrayfields); @@ -643,6 +811,9 @@ if (!empty($arrayfields['t.date_export']['checked'])) { if (!empty($arrayfields['t.date_validated']['checked'])) { print_liste_field_titre($arrayfields['t.date_validated']['label'], $_SERVER['PHP_SELF'], "t.date_validated", "", $param, '', $sortfield, $sortorder, 'center '); } +if (!empty($arrayfields['t.import_key']['checked'])) { + print_liste_field_titre($arrayfields['t.import_key']['label'], $_SERVER["PHP_SELF"], "t.import_key", "", $param, '', $sortfield, $sortorder, 'center '); +} // Hook fields $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook @@ -667,7 +838,11 @@ while ($i < min($num, $limit)) { $total_debit += $line->debit; $total_credit += $line->credit; - $accountg = length_accountg($line->numero_compte); + if ($type == 'sub') { + $accountg = length_accounta($line->subledger_account); + } else { + $accountg = length_accountg($line->numero_compte); + } //if (empty($accountg)) $accountg = '-'; $colspan = 0; // colspan before field 'label of operation' @@ -686,7 +861,11 @@ while ($i < min($num, $limit)) { // Show a subtotal by accounting account if (isset($displayed_account_number)) { print ''; - print ''.$langs->trans("TotalForAccount").' '.length_accountg($displayed_account_number).':'; + if ($type == 'sub') { + print '' . $langs->trans("TotalForAccount") . ' ' . length_accounta($displayed_account_number) . ':'; + } else { + print '' . $langs->trans("TotalForAccount") . ' ' . length_accountg($displayed_account_number) . ':'; + } print ''.price($sous_total_debit).''; print ''.price($sous_total_credit).''; print ''; @@ -712,11 +891,28 @@ while ($i < min($num, $limit)) { // Show the break account print ''; - print ''; - if ($line->numero_compte != "" && $line->numero_compte != '-1') { - print length_accountg($line->numero_compte).' : '.$object->get_compte_desc($line->numero_compte); + print ''; + if ($type == 'sub') { + if ($line->subledger_account != "" && $line->subledger_account != '-1') { + print $line->subledger_label . ' : ' . length_accounta($line->subledger_account); + } else { + // Should not happen: subledger account must be null or a non empty value + print '' . $langs->trans("Unknown"); + if ($line->subledger_label) { + print ' (' . $line->subledger_label . ')'; + $htmltext = 'EmptyStringForSubledgerAccountButSubledgerLabelDefined'; + } else { + $htmltext = 'EmptyStringForSubledgerAccountAndSubledgerLabel'; + } + print $form->textwithpicto('', $htmltext); + print ''; + } } else { - print ''.$langs->trans("Unknown").''; + if ($line->numero_compte != "" && $line->numero_compte != '-1') { + print length_accountg($line->numero_compte) . ' : ' . $object->get_compte_desc($line->numero_compte); + } else { + print '' . $langs->trans("Unknown") . ''; + } } print ''; print ''; @@ -890,22 +1086,26 @@ while ($i < min($num, $limit)) { } } + if (!empty($arrayfields['t.import_key']['checked'])) { + print ''.$line->import_key."\n"; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$line); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column print ''; - if (empty($line->date_export) && empty($line->date_validation)) { - if ($user->rights->accounting->mouvements->creer) { - print '' . img_edit() . ''; - } - } - if (empty($line->date_validation)) { - if ($user->rights->accounting->mouvements->supprimer) { - print ''.img_delete().''; + if (($massactionbutton || $massaction) && $contextpage != 'poslist') { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($line->id, $arrayofselected)) { + $selected = 1; } + print ''; } print ''; if (!$i) { @@ -955,11 +1155,11 @@ print ""; print ''; // TODO Replace this with mass delete action -if ($user->rights->accounting->mouvements->supprimer_tous) { - print '
'."\n"; - print ''.$langs->trans("DeleteMvt").''; - print '
'; -} +//if ($user->rights->accounting->mouvements->supprimer_tous) { +// print '
'."\n"; +// print ''.$langs->trans("DeleteMvt").''; +// print '
'; +//} print '
'; diff --git a/htdocs/accountancy/bookkeeping/listbysubaccount.php b/htdocs/accountancy/bookkeeping/listbysubaccount.php deleted file mode 100644 index e529126d8ce..00000000000 --- a/htdocs/accountancy/bookkeeping/listbysubaccount.php +++ /dev/null @@ -1,979 +0,0 @@ - - * Copyright (C) 2013-2016 Olivier Geffroy - * Copyright (C) 2013-2020 Florian Henry - * Copyright (C) 2013-2021 Alexandre Spangaro - * Copyright (C) 2018-2020 Frédéric France - * - * 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 . - */ - -/** - * \file htdocs/accountancy/bookkeeping/listbysubaccount.php - * \ingroup Accountancy (Double entries) - * \brief List operation of ledger ordered by subaccount number - */ - -require '../../main.inc.php'; - -require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; - -// Load translation files required by the page -$langs->loadLangs(array("accountancy", "compta")); - -$action = GETPOST('action', 'aZ09'); -$search_date_startyear = GETPOST('search_date_startyear', 'int'); -$search_date_startmonth = GETPOST('search_date_startmonth', 'int'); -$search_date_startday = GETPOST('search_date_startday', 'int'); -$search_date_endyear = GETPOST('search_date_endyear', 'int'); -$search_date_endmonth = GETPOST('search_date_endmonth', 'int'); -$search_date_endday = GETPOST('search_date_endday', 'int'); -$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); -$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear); -$search_doc_date = dol_mktime(0, 0, 0, GETPOST('doc_datemonth', 'int'), GETPOST('doc_dateday', 'int'), GETPOST('doc_dateyear', 'int')); -$search_date_export_startyear = GETPOST('search_date_export_startyear', 'int'); -$search_date_export_startmonth = GETPOST('search_date_export_startmonth', 'int'); -$search_date_export_startday = GETPOST('search_date_export_startday', 'int'); -$search_date_export_endyear = GETPOST('search_date_export_endyear', 'int'); -$search_date_export_endmonth = GETPOST('search_date_export_endmonth', 'int'); -$search_date_export_endday = GETPOST('search_date_export_endday', 'int'); -$search_date_export_start = dol_mktime(0, 0, 0, $search_date_export_startmonth, $search_date_export_startday, $search_date_export_startyear); -$search_date_export_end = dol_mktime(23, 59, 59, $search_date_export_endmonth, $search_date_export_endday, $search_date_export_endyear); -$search_date_validation_startyear = GETPOST('search_date_validation_startyear', 'int'); -$search_date_validation_startmonth = GETPOST('search_date_validation_startmonth', 'int'); -$search_date_validation_startday = GETPOST('search_date_validation_startday', 'int'); -$search_date_validation_endyear = GETPOST('search_date_validation_endyear', 'int'); -$search_date_validation_endmonth = GETPOST('search_date_validation_endmonth', 'int'); -$search_date_validation_endday = GETPOST('search_date_validation_endday', 'int'); -$search_date_validation_start = dol_mktime(0, 0, 0, $search_date_validation_startmonth, $search_date_validation_startday, $search_date_validation_startyear); -$search_date_validation_end = dol_mktime(23, 59, 59, $search_date_validation_endmonth, $search_date_validation_endday, $search_date_validation_endyear); - -$search_accountancy_code = GETPOST("search_accountancy_code"); -$search_accountancy_code_start = GETPOST('search_accountancy_code_start', 'alpha'); -if ($search_accountancy_code_start == - 1) { - $search_accountancy_code_start = ''; -} -$search_accountancy_code_end = GETPOST('search_accountancy_code_end', 'alpha'); -if ($search_accountancy_code_end == - 1) { - $search_accountancy_code_end = ''; -} -$search_doc_ref = GETPOST('search_doc_ref', 'alpha'); -$search_label_operation = GETPOST('search_label_operation', 'alpha'); -$search_mvt_num = GETPOST('search_mvt_num', 'int'); -$search_direction = GETPOST('search_direction', 'alpha'); -$search_ledger_code = GETPOST('search_ledger_code', 'array'); -$search_debit = GETPOST('search_debit', 'alpha'); -$search_credit = GETPOST('search_credit', 'alpha'); -$search_lettering_code = GETPOST('search_lettering_code', 'alpha'); -$search_not_reconciled = GETPOST('search_not_reconciled', 'alpha'); - -if (GETPOST("button_delmvt_x") || GETPOST("button_delmvt.x") || GETPOST("button_delmvt")) { - $action = 'delbookkeepingyear'; -} - -// Load variable for pagination -$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); -$sortfield = GETPOST('sortfield', 'aZ09comma'); -$sortorder = GETPOST('sortorder', 'aZ09comma'); -$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); -if (empty($page) || $page < 0) { - $page = 0; -} -$offset = $limit * $page; -$pageprev = $page - 1; -$pagenext = $page + 1; -if ($sortorder == "") { - $sortorder = "ASC"; -} -if ($sortfield == "") { - $sortfield = "t.doc_date,t.rowid"; -} - -// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$object = new BookKeeping($db); -$formfile = new FormFile($db); -$hookmanager->initHooks(array('bookkeepingbysubaccountlist')); - -$formaccounting = new FormAccounting($db); -$form = new Form($db); - -if (empty($search_date_start) && empty($search_date_end) && !GETPOSTISSET('search_date_startday') && !GETPOSTISSET('search_date_startmonth') && !GETPOSTISSET('search_date_starthour')) { - $sql = "SELECT date_start, date_end from ".MAIN_DB_PREFIX."accounting_fiscalyear "; - $sql .= " where date_start < '".$db->idate(dol_now())."' and date_end > '".$db->idate(dol_now())."'"; - $sql .= $db->plimit(1); - $res = $db->query($sql); - - if ($res->num_rows > 0) { - $fiscalYear = $db->fetch_object($res); - $search_date_start = strtotime($fiscalYear->date_start); - $search_date_end = strtotime($fiscalYear->date_end); - } else { - $month_start = ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1); - $year_start = dol_print_date(dol_now(), '%Y'); - if (dol_print_date(dol_now(), '%m') < $month_start) { - $year_start--; // If current month is lower that starting fiscal month, we start last year - } - $year_end = $year_start + 1; - $month_end = $month_start - 1; - if ($month_end < 1) { - $month_end = 12; - $year_end--; - } - $search_date_start = dol_mktime(0, 0, 0, $month_start, 1, $year_start); - $search_date_end = dol_get_last_day($year_end, $month_end); - } -} - -$arrayfields = array( - // 't.subledger_account'=>array('label'=>$langs->trans("SubledgerAccount"), 'checked'=>1), - 't.piece_num'=>array('label'=>$langs->trans("TransactionNumShort"), 'checked'=>1), - 't.code_journal'=>array('label'=>$langs->trans("Codejournal"), 'checked'=>1), - 't.doc_date'=>array('label'=>$langs->trans("Docdate"), 'checked'=>1), - 't.doc_ref'=>array('label'=>$langs->trans("Piece"), 'checked'=>1), - 't.label_operation'=>array('label'=>$langs->trans("Label"), 'checked'=>1), - 't.debit'=>array('label'=>$langs->trans("Debit"), 'checked'=>1), - 't.credit'=>array('label'=>$langs->trans("Credit"), 'checked'=>1), - 't.lettering_code'=>array('label'=>$langs->trans("LetteringCode"), 'checked'=>1), - 't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1), - 't.date_validated'=>array('label'=>$langs->trans("DateValidation"), 'checked'=>1), -); - -if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { - unset($arrayfields['t.lettering_code']); -} - -if ($search_date_start && empty($search_date_startyear)) { - $tmparray = dol_getdate($search_date_start); - $search_date_startyear = $tmparray['year']; - $search_date_startmonth = $tmparray['mon']; - $search_date_startday = $tmparray['mday']; -} -if ($search_date_end && empty($search_date_endyear)) { - $tmparray = dol_getdate($search_date_end); - $search_date_endyear = $tmparray['year']; - $search_date_endmonth = $tmparray['mon']; - $search_date_endday = $tmparray['mday']; -} - -if (empty($conf->accounting->enabled)) { - accessforbidden(); -} -if ($user->socid > 0) { - accessforbidden(); -} -if (empty($user->rights->accounting->mouvements->lire)) { - accessforbidden(); -} - - -/* - * Action - */ - -if (GETPOST('cancel', 'alpha')) { - $action = 'list'; $massaction = ''; -} -if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { - $massaction = ''; -} - -$parameters = array('socid'=>$socid); -$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks -if ($reshook < 0) { - setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); -} - -if (empty($reshook)) { - include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; - - if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers - $search_doc_date = ''; - $search_accountancy_code = ''; - $search_accountancy_code_start = ''; - $search_accountancy_code_end = ''; - $search_label_account = ''; - $search_doc_ref = ''; - $search_label_operation = ''; - $search_mvt_num = ''; - $search_direction = ''; - $search_ledger_code = array(); - $search_date_start = ''; - $search_date_end = ''; - $search_date_startyear = ''; - $search_date_startmonth = ''; - $search_date_startday = ''; - $search_date_endyear = ''; - $search_date_endmonth = ''; - $search_date_endday = ''; - $search_date_export_start = ''; - $search_date_export_end = ''; - $search_date_export_startyear = ''; - $search_date_export_startmonth = ''; - $search_date_export_startday = ''; - $search_date_export_endyear = ''; - $search_date_export_endmonth = ''; - $search_date_export_endday = ''; - $search_date_validation_start = ''; - $search_date_validation_end = ''; - $search_date_validation_startyear = ''; - $search_date_validation_startmonth = ''; - $search_date_validation_startday = ''; - $search_date_validation_endyear = ''; - $search_date_validation_endmonth = ''; - $search_date_validation_endday = ''; - $search_debit = ''; - $search_credit = ''; - $search_lettering_code = ''; - $search_not_reconciled = ''; - } - - // Must be after the remove filter action, before the export. - $param = ''; - $filter = array(); - - if (!empty($search_date_start)) { - $filter['t.doc_date>='] = $search_date_start; - $param .= '&search_date_startmonth='.$search_date_startmonth.'&search_date_startday='.$search_date_startday.'&search_date_startyear='.$search_date_startyear; - } - if (!empty($search_date_end)) { - $filter['t.doc_date<='] = $search_date_end; - $param .= '&search_date_endmonth='.$search_date_endmonth.'&search_date_endday='.$search_date_endday.'&search_date_endyear='.$search_date_endyear; - } - if (!empty($search_doc_date)) { - $filter['t.doc_date'] = $search_doc_date; - $param .= '&doc_datemonth='.GETPOST('doc_datemonth', 'int').'&doc_dateday='.GETPOST('doc_dateday', 'int').'&doc_dateyear='.GETPOST('doc_dateyear', 'int'); - } - if (!empty($search_accountancy_code_start)) { - $filter['t.subledger_account>='] = $search_accountancy_code_start; - $param .= '&search_accountancy_code_start='.urlencode($search_accountancy_code_start); - } - if (!empty($search_accountancy_code_end)) { - $filter['t.subledger_account<='] = $search_accountancy_code_end; - $param .= '&search_accountancy_code_end='.urlencode($search_accountancy_code_end); - } - if (!empty($search_label_account)) { - $filter['t.label_compte'] = $search_label_account; - $param .= '&search_label_compte='.urlencode($search_label_account); - } - if (!empty($search_mvt_num)) { - $filter['t.piece_num'] = $search_mvt_num; - $param .= '&search_mvt_num='.urlencode($search_mvt_num); - } - if (!empty($search_doc_ref)) { - $filter['t.doc_ref'] = $search_doc_ref; - $param .= '&search_doc_ref='.urlencode($search_doc_ref); - } - if (!empty($search_label_operation)) { - $filter['t.label_operation'] = $search_label_operation; - $param .= '&search_label_operation='.urlencode($search_label_operation); - } - if (!empty($search_direction)) { - $filter['t.sens'] = $search_direction; - $param .= '&search_direction='.urlencode($search_direction); - } - if (!empty($search_ledger_code)) { - $filter['t.code_journal'] = $search_ledger_code; - foreach ($search_ledger_code as $code) { - $param .= '&search_ledger_code[]='.urlencode($code); - } - } - if (!empty($search_debit)) { - $filter['t.debit'] = $search_debit; - $param .= '&search_debit='.urlencode($search_debit); - } - if (!empty($search_credit)) { - $filter['t.credit'] = $search_credit; - $param .= '&search_credit='.urlencode($search_credit); - } - if (!empty($search_lettering_code)) { - $filter['t.lettering_code'] = $search_lettering_code; - $param .= '&search_lettering_code='.urlencode($search_lettering_code); - } - if (!empty($search_not_reconciled)) { - $filter['t.reconciled_option'] = $search_not_reconciled; - $param .= '&search_not_reconciled='.urlencode($search_not_reconciled); - } - if (!empty($search_date_export_start)) { - $filter['t.date_export>='] = $search_date_export_start; - $param .= '&search_date_export_startmonth='.$search_date_export_startmonth.'&search_date_export_startday='.$search_date_export_startday.'&search_date_export_startyear='.$search_date_export_startyear; - } - if (!empty($search_date_export_end)) { - $filter['t.date_export<='] = $search_date_export_end; - $param .= '&search_date_export_endmonth='.$search_date_export_endmonth.'&search_date_export_endday='.$search_date_export_endday.'&search_date_export_endyear='.$search_date_export_endyear; - } - if (!empty($search_date_validation_start)) { - $filter['t.date_validated>='] = $search_date_validation_start; - $param .= '&search_date_validation_startmonth='.$search_date_validation_startmonth.'&search_date_validation_startday='.$search_date_validation_startday.'&search_date_validation_startyear='.$search_date_validation_startyear; - } - if (!empty($search_date_validation_end)) { - $filter['t.date_validated<='] = $search_date_validation_end; - $param .= '&search_date_validation_endmonth='.$search_date_validation_endmonth.'&search_date_validation_endday='.$search_date_validation_endday.'&search_date_validation_endyear='.$search_date_validation_endyear; - } -} - -if ($action == 'delbookkeeping' && $user->rights->accounting->mouvements->supprimer) { - $import_key = GETPOST('importkey', 'alpha'); - - if (!empty($import_key)) { - $result = $object->deleteByImportkey($import_key); - if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); - } - - // Make a redirect to avoid to launch the delete later after a back button - header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : '')); - exit; - } -} -if ($action == 'delbookkeepingyearconfirm' && $user->rights->accounting->mouvements->supprimer_tous) { - $delmonth = GETPOST('delmonth', 'int'); - $delyear = GETPOST('delyear', 'int'); - if ($delyear == -1) { - $delyear = 0; - } - $deljournal = GETPOST('deljournal', 'alpha'); - if ($deljournal == -1) { - $deljournal = 0; - } - - if (!empty($delmonth) || !empty($delyear) || !empty($deljournal)) { - $result = $object->deleteByYearAndJournal($delyear, $deljournal, '', ($delmonth > 0 ? $delmonth : 0)); - if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); - } else { - setEventMessages("RecordDeleted", null, 'mesgs'); - } - - // Make a redirect to avoid to launch the delete later after a back button - header("Location: ".$_SERVER["PHP_SELF"].($param ? '?'.$param : '')); - exit; - } else { - setEventMessages("NoRecordDeleted", null, 'warnings'); - } -} -if ($action == 'delmouvconfirm' && $user->rights->accounting->mouvements->supprimer) { - $mvt_num = GETPOST('mvt_num', 'int'); - - if (!empty($mvt_num)) { - $result = $object->deleteMvtNum($mvt_num); - if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); - } else { - setEventMessages($langs->trans("RecordDeleted"), null, 'mesgs'); - } - - header("Location: ".$_SERVER["PHP_SELF"]."?noreset=1".($param ? '&'.$param : '')); - exit; - } -} - - -/* - * View - */ - -$formaccounting = new FormAccounting($db); -$formfile = new FormFile($db); -$formother = new FormOther($db); -$form = new Form($db); - -$title_page = $langs->trans("Operations").' - '.$langs->trans("VueByAccountAccounting").' ('.$langs->trans("BookkeepingSubAccount").')'; - -llxHeader('', $title_page); - -// List -$nbtotalofrecords = ''; -if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $nbtotalofrecords = $object->fetchAllByAccount($sortorder, $sortfield, 0, 0, $filter, 'AND', 1); - if ($nbtotalofrecords < 0) { - setEventMessages($object->error, $object->errors, 'errors'); - } -} - -$result = $object->fetchAllByAccount($sortorder, $sortfield, $limit, $offset, $filter, 'AND', 1); - -if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); -} - -$num = count($object->lines); - - -if ($action == 'delmouv') { - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?mvt_num='.GETPOST('mvt_num'), $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvtPartial'), 'delmouvconfirm', '', 0, 1); - print $formconfirm; -} -if ($action == 'delbookkeepingyear') { - $form_question = array(); - $delyear = GETPOST('delyear', 'int'); - $deljournal = GETPOST('deljournal', 'alpha'); - - if (empty($delyear)) { - $delyear = dol_print_date(dol_now(), '%Y'); - } - $month_array = array(); - for ($i = 1; $i <= 12; $i++) { - $month_array[$i] = $langs->trans("Month".sprintf("%02d", $i)); - } - $year_array = $formaccounting->selectyear_accountancy_bookkepping($delyear, 'delyear', 0, 'array'); - $journal_array = $formaccounting->select_journal($deljournal, 'deljournal', '', 1, 1, 1, '', 0, 1); - - $form_question['delmonth'] = array( - 'name' => 'delmonth', - 'type' => 'select', - 'label' => $langs->trans('DelMonth'), - 'values' => $month_array, - 'default' => '' - ); - $form_question['delyear'] = array( - 'name' => 'delyear', - 'type' => 'select', - 'label' => $langs->trans('DelYear'), - 'values' => $year_array, - 'default' => $delyear - ); - $form_question['deljournal'] = array( - 'name' => 'deljournal', - 'type' => 'other', // We don't use select here, the journal_array is already a select html component - 'label' => $langs->trans('DelJournal'), - 'value' => $journal_array, - 'default' => $deljournal - ); - - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'delbookkeepingyearconfirm', $form_question, '', 1, 300); - print $formconfirm; -} - - -print '
'; -print ''; -print ''; -if ($optioncss != '') { - print ''; -} -print ''; -print ''; -print ''; - -$parameters = array(); -$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook -if (empty($reshook)) { - $newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param); - $newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly')); - $newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/listbysubaccount.php?'.$param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected')); - $newcardbutton .= dolGetButtonTitle($langs->trans('NewAccountingMvt'), '', 'fa fa-plus-circle paddingleft', DOL_URL_ROOT.'/accountancy/bookkeeping/card.php?action=create'); -} - -if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { - $param .= '&contextpage='.urlencode($contextpage); -} -if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); -} - -print_barre_liste($title_page, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $result, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit, 0, 0, 1); - -print info_admin($langs->trans("WarningRecordWithoutSubledgerAreExcluded")); - -$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; -$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields -if ($massactionbutton) { - $selectedfields .= $form->showCheckAddButtons('checkforselect', 1); -} - -// Reverse sort order -if (preg_match('/^asc/i', $sortorder)) { - $sortorder = "asc"; -} else { - $sortorder = "desc"; -} - -$moreforfilter = ''; - -// Accountancy account -$moreforfilter .= '
'; -$moreforfilter .= $langs->trans('AccountAccounting').': '; -$moreforfilter .= '
'; -$moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), 'maxwidth200'); -$moreforfilter .= ' '; -$moreforfilter .= $formaccounting->select_auxaccount($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), 'maxwidth200'); -$moreforfilter .= '
'; -$moreforfilter .= '
'; - -$parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook -if (empty($reshook)) { - $moreforfilter .= $hookmanager->resPrint; -} else { - $moreforfilter = $hookmanager->resPrint; -} - -print '
'; -print $moreforfilter; -print '
'; - -print '
'; -print ''; - -// Filters lines -print ''; - -// Movement number -if (!empty($arrayfields['t.piece_num']['checked'])) { - print ''; -} -// Code journal -if (!empty($arrayfields['t.code_journal']['checked'])) { - print ''; -} -// Date document -if (!empty($arrayfields['t.doc_date']['checked'])) { - print ''; -} -// Ref document -if (!empty($arrayfields['t.doc_ref']['checked'])) { - print ''; -} -// Label operation -if (!empty($arrayfields['t.label_operation']['checked'])) { - print ''; -} -// Debit -if (!empty($arrayfields['t.debit']['checked'])) { - print ''; -} -// Credit -if (!empty($arrayfields['t.credit']['checked'])) { - print ''; -} -// Lettering code -if (!empty($arrayfields['t.lettering_code']['checked'])) { - print ''; -} -// Date export -if (!empty($arrayfields['t.date_export']['checked'])) { - print ''; -} -// Date validation -if (!empty($arrayfields['t.date_validated']['checked'])) { - print ''; -} - -// Fields from hook -$parameters = array('arrayfields'=>$arrayfields); -$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; - -// Action column -print ''; -print "\n"; - -print ''; -if (!empty($arrayfields['t.piece_num']['checked'])) { - print_liste_field_titre($arrayfields['t.piece_num']['label'], $_SERVER['PHP_SELF'], "t.piece_num", "", $param, '', $sortfield, $sortorder); -} -if (!empty($arrayfields['t.code_journal']['checked'])) { - print_liste_field_titre($arrayfields['t.code_journal']['label'], $_SERVER['PHP_SELF'], "t.code_journal", "", $param, '', $sortfield, $sortorder, 'center '); -} -if (!empty($arrayfields['t.doc_date']['checked'])) { - print_liste_field_titre($arrayfields['t.doc_date']['label'], $_SERVER['PHP_SELF'], "t.doc_date", "", $param, '', $sortfield, $sortorder, 'center '); -} -if (!empty($arrayfields['t.doc_ref']['checked'])) { - print_liste_field_titre($arrayfields['t.doc_ref']['label'], $_SERVER['PHP_SELF'], "t.doc_ref", "", $param, "", $sortfield, $sortorder); -} -if (!empty($arrayfields['t.label_operation']['checked'])) { - print_liste_field_titre($arrayfields['t.label_operation']['label'], $_SERVER['PHP_SELF'], "t.label_operation", "", $param, "", $sortfield, $sortorder); -} -if (!empty($arrayfields['t.debit']['checked'])) { - print_liste_field_titre($arrayfields['t.debit']['label'], $_SERVER['PHP_SELF'], "t.debit", "", $param, '', $sortfield, $sortorder, 'right '); -} -if (!empty($arrayfields['t.credit']['checked'])) { - print_liste_field_titre($arrayfields['t.credit']['label'], $_SERVER['PHP_SELF'], "t.credit", "", $param, '', $sortfield, $sortorder, 'right '); -} -if (!empty($arrayfields['t.lettering_code']['checked'])) { - print_liste_field_titre($arrayfields['t.lettering_code']['label'], $_SERVER['PHP_SELF'], "t.lettering_code", "", $param, '', $sortfield, $sortorder, 'center '); -} -if (!empty($arrayfields['t.date_export']['checked'])) { - print_liste_field_titre($arrayfields['t.date_export']['label'], $_SERVER['PHP_SELF'], "t.date_export", "", $param, '', $sortfield, $sortorder, 'center '); -} -if (!empty($arrayfields['t.date_validated']['checked'])) { - print_liste_field_titre($arrayfields['t.date_validated']['label'], $_SERVER['PHP_SELF'], "t.date_validated", "", $param, '', $sortfield, $sortorder, 'center '); -} -// Hook fields -$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); -$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook -print $hookmanager->resPrint; -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); -print "\n"; - - -$total_debit = 0; -$total_credit = 0; -$sous_total_debit = 0; -$sous_total_credit = 0; -$displayed_account_number = null; // Start with undefined to be able to distinguish with empty - -// Loop on record -// -------------------------------------------------------------------- -$i = 0; -$totalarray = array(); -while ($i < min($num, $limit)) { - $line = $object->lines[$i]; - - $total_debit += $line->debit; - $total_credit += $line->credit; - - $accountg = length_accounta($line->subledger_account); - //if (empty($accountg)) $accountg = '-'; - - $colspan = 0; // colspan before field 'label of operation' - $colspanend = 3; // colspan after debit/credit - if (!empty($arrayfields['t.piece_num']['checked'])) { $colspan++; } - if (!empty($arrayfields['t.code_journal']['checked'])) { $colspan++; } - if (!empty($arrayfields['t.doc_date']['checked'])) { $colspan++; } - if (!empty($arrayfields['t.doc_ref']['checked'])) { $colspan++; } - if (!empty($arrayfields['t.label_operation']['checked'])) { $colspan++; } - if (!empty($arrayfields['t.date_export']['checked'])) { $colspanend++; } - if (!empty($arrayfields['t.date_validating']['checked'])) { $colspanend++; } - if (!empty($arrayfields['t.lettering_code']['checked'])) { $colspanend++; } - - // Is it a break ? - if ($accountg != $displayed_account_number || !isset($displayed_account_number)) { - // Show a subtotal by accounting account - if (isset($displayed_account_number)) { - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - // Show balance of last shown account - $balance = $sous_total_debit - $sous_total_credit; - print ''; - print ''; - if ($balance > 0) { - print ''; - print ''; - } else { - print ''; - print ''; - } - print ''; - print ''; - } - - // Show the break account - print ''; - print ''; - print ''; - - $displayed_account_number = $accountg; - //if (empty($displayed_account_number)) $displayed_account_number='-'; - $sous_total_debit = 0; - $sous_total_credit = 0; - - $colspan = 0; - } - - print ''; - - // Piece number - if (!empty($arrayfields['t.piece_num']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - - // Journal code - if (!empty($arrayfields['t.code_journal']['checked'])) { - $accountingjournal = new AccountingJournal($db); - $result = $accountingjournal->fetch('', $line->code_journal); - $journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $line->code_journal); - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - - // Document date - if (!empty($arrayfields['t.doc_date']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - - // Document ref - if (!empty($arrayfields['t.doc_ref']['checked'])) { - if ($line->doc_type == 'customer_invoice') { - $langs->loadLangs(array('bills')); - - require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; - $objectstatic = new Facture($db); - $objectstatic->fetch($line->fk_doc); - //$modulepart = 'facture'; - - $filename = dol_sanitizeFileName($line->doc_ref); - $filedir = $conf->facture->dir_output.'/'.dol_sanitizeFileName($line->doc_ref); - $urlsource = $_SERVER['PHP_SELF'].'?id='.$objectstatic->id; - $documentlink = $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir); - } elseif ($line->doc_type == 'supplier_invoice') { - $langs->loadLangs(array('bills')); - - require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; - $objectstatic = new FactureFournisseur($db); - $objectstatic->fetch($line->fk_doc); - //$modulepart = 'invoice_supplier'; - - $filename = dol_sanitizeFileName($line->doc_ref); - $filedir = $conf->fournisseur->facture->dir_output.'/'.get_exdir($line->fk_doc, 2, 0, 0, $objectstatic, $modulepart).dol_sanitizeFileName($line->doc_ref); - $subdir = get_exdir($objectstatic->id, 2, 0, 0, $objectstatic, $modulepart).dol_sanitizeFileName($line->doc_ref); - $documentlink = $formfile->getDocumentsLink($objectstatic->element, $subdir, $filedir); - } elseif ($line->doc_type == 'expense_report') { - $langs->loadLangs(array('trips')); - - require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; - $objectstatic = new ExpenseReport($db); - $objectstatic->fetch($line->fk_doc); - //$modulepart = 'expensereport'; - - $filename = dol_sanitizeFileName($line->doc_ref); - $filedir = $conf->expensereport->dir_output.'/'.dol_sanitizeFileName($line->doc_ref); - $urlsource = $_SERVER['PHP_SELF'].'?id='.$objectstatic->id; - $documentlink = $formfile->getDocumentsLink($objectstatic->element, $filename, $filedir); - } elseif ($line->doc_type == 'bank') { - require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; - $objectstatic = new AccountLine($db); - $objectstatic->fetch($line->fk_doc); - } else { - // Other type - } - - print '\n"; - if (!$i) { - $totalarray['nbfield']++; - } - } - - // Label operation - if (!empty($arrayfields['t.label_operation']['checked'])) { - // Affiche un lien vers la facture client/fournisseur - $doc_ref = preg_replace('/\(.*\)/', '', $line->doc_ref); - print strlen(length_accounta($line->subledger_account)) == 0 ? '' : ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - - // Amount debit - if (!empty($arrayfields['t.debit']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - if (!$i) { - $totalarray['pos'][$totalarray['nbfield']] = 'totaldebit'; - } - $totalarray['val']['totaldebit'] += $line->debit; - } - - // Amount credit - if (!empty($arrayfields['t.credit']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - if (!$i) { - $totalarray['pos'][$totalarray['nbfield']] = 'totalcredit'; - } - $totalarray['val']['totalcredit'] += $line->credit; - } - - // Lettering code - if (!empty($arrayfields['t.lettering_code']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - - // Exported operation date - if (!empty($arrayfields['t.date_export']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - - // Validated operation date - if (!empty($arrayfields['t.date_validated']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - - // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); - $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - - // Action column - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - - // Comptabilise le sous-total - $sous_total_debit += $line->debit; - $sous_total_credit += $line->credit; - - print "\n"; - - $i++; -} - -if ($num > 0 && $colspan > 0) { - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - // Show balance of last shown account - $balance = $sous_total_debit - $sous_total_credit; - print ''; - print ''; - if ($balance > 0) { - print ''; - print ''; - } else { - print ''; - print ''; - } - print ''; - print ''; -} - -// Show total line -include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; - - -print "
'; - print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1); - print ''; - print '
'; - print $form->selectDate($search_date_start, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); - print '
'; - print '
'; - print $form->selectDate($search_date_end, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); - print '
'; - print '
'; - print ''; - print '
'.$langs->trans("NotReconciled").''; - print '
'; - print '
'; - print $form->selectDate($search_date_export_start, 'search_date_export_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); - print '
'; - print '
'; - print $form->selectDate($search_date_export_end, 'search_date_export_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); - print '
'; - print '
'; - print '
'; - print $form->selectDate($search_date_validation_start, 'search_date_validation_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From")); - print '
'; - print '
'; - print $form->selectDate($search_date_validation_end, 'search_date_validation_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to")); - print '
'; - print '
'; -$searchpicto = $form->showFilterButtons(); -print $searchpicto; -print '
'.$langs->trans("TotalForAccount").' '.length_accounta($displayed_account_number).':'.price($sous_total_debit).''.price($sous_total_credit).'
'.$langs->trans("Balance").':'; - print price($sous_total_debit - $sous_total_credit); - print ''; - print price($sous_total_credit - $sous_total_debit); - print '
'; - if ($line->subledger_account != "" && $line->subledger_account != '-1') { - print $line->subledger_label.' : '.length_accounta($line->subledger_account); - } else { - // Should not happen: subledger account must be null or a non empty value - print ''.$langs->trans("Unknown"); - if ($line->subledger_label) { - print ' ('.$line->subledger_label.')'; - $htmltext = 'EmptyStringForSubledgerAccountButSubledgerLabelDefined'; - } else { - $htmltext = 'EmptyStringForSubledgerAccountAndSubledgerLabel'; - } - print $form->textwithpicto('', $htmltext); - print ''; - } - print '
'; - $object->id = $line->id; - $object->piece_num = $line->piece_num; - print $object->getNomUrl(1, '', 0, '', 1); - print ''.$journaltoshow.''.dol_print_date($line->doc_date, 'day').''; - - print ''; - // Picto + Ref - print '
'; - - if ($line->doc_type == 'customer_invoice' || $line->doc_type == 'supplier_invoice' || $line->doc_type == 'expense_report') { - print $objectstatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1); - print $documentlink; - } elseif ($line->doc_type == 'bank') { - print $objectstatic->getNomUrl(1); - $bank_ref = strstr($line->doc_ref, '-'); - print " " . $bank_ref; - } else { - print $line->doc_ref; - } - print '
'; - - print "
'.$line->label_operation.''.$line->label_operation.'
('.length_accounta($line->subledger_account).')
'.($line->debit ? price($line->debit) : '').''.($line->credit ? price($line->credit) : '').''.$line->lettering_code.''.dol_print_date($line->date_export, 'dayhour').''.dol_print_date($line->date_validation, 'dayhour').''; - if (empty($line->date_export) && empty($line->date_validation)) { - if ($user->rights->accounting->mouvements->creer) { - print '' . img_edit() . ''; - } - } - if (empty($line->date_validation)) { - if ($user->rights->accounting->mouvements->supprimer) { - print ''.img_delete().''; - } - } - print '
'.$langs->trans("TotalForAccount").' '.$accountg.':'.price($sous_total_debit).''.price($sous_total_credit).'
'.$langs->trans("Balance").':'; - print price($sous_total_debit - $sous_total_credit); - print ''; - print price($sous_total_credit - $sous_total_debit); - print '
"; -print '
'; - -// TODO Replace this with mass delete action -if ($user->rights->accounting->mouvements->supprimer_tous) { - print '
'."\n"; - print ''.$langs->trans("DeleteMvt").''; - print '
'; -} - -print '
'; - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php deleted file mode 100644 index a563b653ac1..00000000000 --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php +++ /dev/null @@ -1,325 +0,0 @@ - - * Copyright (C) 2005 Laurent Destailleur - * Copyright (C) 2013 Olivier Geffroy - * Copyright (C) 2013 Florian Henry - * Copyright (C) 2013-2019 Alexandre Spangaro - * Copyright (C) 2018-2020 Frédéric France - * - * 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 . - * - */ - -/** - * \file htdocs/accountancy/bookkeeping/thirdparty_lettering_customer.php - * \ingroup accountancy - * \brief Tab to manage customer lettering - */ -require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/lettering.class.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; -require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; - -// Load translation files required by the page -$langs->loadLangs(array("compta", "accountancy")); - -$action = GETPOST('action', 'aZ09'); -$massaction = GETPOST('massaction', 'alpha'); -$show_files = GETPOST('show_files', 'int'); -$confirm = GETPOST('confirm', 'alpha'); -$toselect = GETPOST('toselect', 'array'); -// $socid = GETPOST('socid', 'int') ?GETPOST('socid', 'int') : GETPOST('id', 'int'); -// Security check -$socid = GETPOSTINT("socid"); -// if ($user->socid) $socid=$user->socid; - -$limit = GETPOSTISSET('limit') ? GETPOST('limit', 'int') : $conf->liste_limit; -$sortfield = GETPOST('sortfield', '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 ($sortorder == "") { - $sortorder = "ASC"; -} -if ($sortfield == "") { - $sortfield = "bk.doc_date"; -} - -/* -$search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); -$search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int')); -//$search_doc_type = GETPOST("search_doc_type", 'alpha'); -$search_doc_ref = GETPOST("search_doc_ref", 'alpha'); -*/ - -$lettering = GETPOST('lettering', 'alpha'); -if (!empty($lettering)) { - $action = $lettering; -} - -/* -if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers -{ - $search_date_start = ''; - $search_date_end = ''; - //$search_doc_type = ''; - $search_doc_ref = ''; -} -*/ - -$lettering = new Lettering($db); -$object = new Societe($db); -$object->id = $socid; -$result = $object->fetch($socid); -if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); -} - -if (empty($conf->accounting->enabled)) { - accessforbidden(); -} -if ($user->socid > 0) { - accessforbidden(); -} -if (empty($user->rights->accounting->mouvements->lire)) { - accessforbidden(); -} - - -/* - * Action - */ - -if ($action == 'lettering') { - $result = $lettering->updateLettering($toselect); - - if ($result < 0) { - setEventMessages('', $lettering->errors, 'errors'); - $error++; - } -} - -/* -if ($action == 'autolettrage') { - - $result = $lettering->letteringThirdparty($socid); - - if ($result < 0) { - setEventMessages('', $lettering->errors, 'errors'); - $error++; - } -} -*/ - -/* - * View - */ - -$form = new Form($db); -$formaccounting = new FormAccounting($db); - -$title = $object->name." - ".$langs->trans('TabLetteringCustomer'); -$help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas|DE:Modul_Geschäftspartner'; -llxHeader('', $title, $help_url); - -$head = societe_prepare_head($object); - -dol_htmloutput_mesg(is_numeric($error) ? '' : $error, $errors, 'error'); - -print dol_get_fiche_head($head, 'lettering_customer', $langs->trans("ThirdParty"), 0, 'company'); - -$linkback = ''.$langs->trans("BackToList").''; - -dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom', '', '', 0, '', '', 'arearefnobottom'); - -print dol_get_fiche_end(); - -$sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, "; -$sql .= " bk.subledger_account, bk.numero_compte , bk.label_compte, bk.debit, "; -$sql .= " bk.credit, bk.montant, bk.sens, bk.code_journal, bk.piece_num, bk.lettering_code"; -$sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as bk"; -$sql .= " WHERE (bk.subledger_account = '".$db->escape($object->code_compta)."' AND bk.numero_compte = '".$db->escape($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER)."' )"; - -/* -if (dol_strlen($search_date_start) || dol_strlen($search_date_end)) { - $sql .= " AND ( bk.doc_date BETWEEN '" . $db->idate($search_date_start) . "' AND '" . $db->idate($search_date_end) . "' )"; -} -*/ - -$sql .= ' AND bk.entity IN ('.getEntity('accountingbookkeeping').')'; -$sql .= $db->order($sortfield, $sortorder); - -$debit = 0; -$credit = 0; -$solde = 0; -// Count total nb of records and calc total sum -$nbtotalofrecords = ''; -$resql = $db->query($sql); -if (!$resql) { - dol_print_error($db); - exit(); -} -$nbtotalofrecords = $db->num_rows($resql); - -while ($obj = $db->fetch_object($resql)) { - $debit += $obj->debit; - $credit += $obj->credit; - - $solde += ($obj->credit - $obj->debit); -} - -$sql .= $db->plimit($limit + 1, $offset); - -dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_customer.php", LOG_DEBUG); -$resql = $db->query($sql); -if (!$resql) { - dol_print_error($db); - exit(); -} - -$param = ''; -$param .= "&socid=".urlencode($socid); - -$num = $db->num_rows($resql); - -dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_customer.php", LOG_DEBUG); -if ($resql) { - $i = 0; - - $param = "&socid=".$socid; - print '
'; - print ''; - print ''; - - $letteringbutton = ''; - - print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, $letteringbutton, '', $limit); - - print '
'; - print ''."\n"; - - /* - print ''; - //print ''; - - // Date - print ''; - - // Piece - print ''; - print ''; - print ''; - print ''; - */ - - print ''; - //print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder, 'center '); - print_liste_field_titre("Piece", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder, 'center '); - print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder, 'center '); - print_liste_field_titre("", "", "", '', '', "", $sortfield, $sortorder, 'maxwidthsearch center '); - print "\n"; - - $solde = 0; - $tmp = ''; - - while ($obj = $db->fetch_object($resql)) { - if ($tmp != $obj->lettering_code || empty($tmp)) { - $tmp = $obj->lettering_code; - } - /*if ($tmp != $obj->lettering_code || empty($obj->lettering_code))*/ $solde += ($obj->credit - $obj->debit); - - print ''; - - //print '' . "\n"; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - // Journal - $accountingjournal = new AccountingJournal($db); - $result = $accountingjournal->fetch('', $obj->code_journal); - $journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $obj->code_journal); - print ''; - - if (empty($obj->lettering_code) && empty($obj->date_validated)) { - print ''; - print ''."\n"; - } else { - print ''; - print ''; - } - - print "\n"; - } - - print ''; - print ''."\n"; - print ''; - print ''; - print ''; - print "\n"; - - print ''; - print ''."\n"; - print ''; - print ''; - print ''; - print "\n"; - - print "
'; - print '
'; - print $langs->trans('From') . ' '; - print $form->selectDate($search_date_start, 'date_creation_start', 0, 0, 1); - print '
'; - print '
'; - print $langs->trans('to') . ' '; - print $form->selectDate($search_date_end, 'date_creation_end', 0, 0, 1); - print '
'; - print '
 '; - $searchpicto = $form->showFilterButtons(); - print $searchpicto; - print '
' . $obj->doc_type . ''.dol_print_date($db->jdate($obj->doc_date), 'day').''.$obj->doc_ref.''.$obj->label_compte.''.price($obj->debit).''.price($obj->credit).''.price(round($solde, 2)).''.$journaltoshow.''; - print img_edit(); - print ''.$obj->lettering_code.'
'.$langs->trans("Total").':'.price($debit).''.price($credit).'
'.$langs->trans("Balancing").': '.price($credit - $debit).'
"; - - print '
'."\n"; - print $letteringbutton; - print '
'; - - print ""; - $db->free($resql); -} else { - dol_print_error($db); -} - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php b/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php deleted file mode 100644 index 5c315bee9fc..00000000000 --- a/htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php +++ /dev/null @@ -1,322 +0,0 @@ - - * Copyright (C) 2005 Laurent Destailleur - * Copyright (C) 2013 Olivier Geffroy - * Copyright (C) 2013 Florian Henry - * Copyright (C) 2013-2019 Alexandre Spangaro - * Copyright (C) 2018-2020 Frédéric France - * - * 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 . - */ - -/** - * \file htdocs/accountancy/bookkeeping/thirdparty_lettering_supplier.php - * \ingroup Accountancy (Double entries) - * \brief Tab to setup lettering - */ -require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/lettering.class.php'; -require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; -require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; - -// Load translation files required by the page -$langs->loadLangs(array("compta", "accountancy")); - -$action = GETPOST('action', 'aZ09'); -$massaction = GETPOST('massaction', 'alpha'); -$show_files = GETPOST('show_files', 'int'); -$confirm = GETPOST('confirm', 'alpha'); -$toselect = GETPOST('toselect', 'array'); -// $socid = GETPOST('socid', 'int') ? ((int) GETPOST('socid', 'int')) : ((int) GETPOST('id', 'int')); -// Security check -$socid = GETPOSTINT("socid"); -// if ($user->socid) $socid=$user->socid; - - -$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; -$sortfield = GETPOST('sortfield', '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 ($sortorder == "") { - $sortorder = "ASC"; -} -if ($sortfield == "") { - $sortfield = "bk.doc_date"; -} - -/* -$search_date_start = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); -$search_date_end = dol_mktime(0, 0, 0, GETPOST('date_endmonth', 'int'), GETPOST('date_endday', 'int'), GETPOST('date_endyear', 'int')); -//$search_doc_type = GETPOST("search_doc_type",'alpha'); -$search_doc_ref = GETPOST("search_doc_ref",'alpha'); -*/ - -$lettering = GETPOST('lettering', 'alpha'); -if (!empty($lettering)) { - $action = $lettering; -} - -/* -if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers -{ - $search_date_start = ''; - $search_date_end = ''; - //$search_doc_type=''; - $search_doc_ref=''; -} -*/ - -$lettering = new Lettering($db); -$object = new Societe($db); -$object->id = $socid; -$result = $object->fetch($socid); -if ($result < 0) { - setEventMessages($object->error, $object->errors, 'errors'); -} - -if (empty($conf->accounting->enabled)) { - accessforbidden(); -} -if ($user->socid > 0) { - accessforbidden(); -} -if (empty($user->rights->accounting->mouvements->lire)) { - accessforbidden(); -} - - -/* - * Action - */ - -if ($action == 'lettering') { - $result = $lettering->updateLettering($toselect); - - if ($result < 0) { - setEventMessages('', $lettering->errors, 'errors'); - $error++; - } -} - -/* -if ($action == 'autolettrage') { - - $result = $lettering->letteringThirdparty($socid); - - if ($result < 0) { - setEventMessages('', $lettering->errors, 'errors'); - $error++; - } -} -*/ - -/* - * View - */ - -$form = new Form($db); -$formaccounting = new FormAccounting($db); - -$title = $object->name." - ".$langs->trans('TabLetteringSupplier'); -$help_url = 'EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas|DE:Modul_Geschäftspartner'; -llxHeader('', $title, $help_url); - -$head = societe_prepare_head($object); - -dol_htmloutput_mesg(is_numeric($error) ? '' : $error, $errors, 'error'); - -print dol_get_fiche_head($head, 'lettering_supplier', $langs->trans("ThirdParty"), 0, 'company'); - -$linkback = ''.$langs->trans("BackToList").''; - -dol_banner_tab($object, 'socid', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom', '', '', 0, '', '', 'arearefnobottom'); - -print dol_get_fiche_end(); - -$sql = "SELECT bk.rowid, bk.doc_date, bk.doc_type, bk.doc_ref, "; -$sql .= " bk.subledger_account, bk.numero_compte , bk.label_compte, bk.debit, "; -$sql .= " bk.credit, bk.montant, bk.sens, bk.code_journal, bk.piece_num, bk.lettering_code, bk.date_validated "; -$sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as bk"; -$sql .= " WHERE (bk.subledger_account = '".$db->escape($object->code_compta_fournisseur)."' AND bk.numero_compte = '".$db->escape($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER)."' )"; -if (dol_strlen($search_date_start) || dol_strlen($search_date_end)) { - $sql .= " AND (bk.doc_date BETWEEN '".$db->idate($search_date_start)."' AND '".$db->idate($search_date_end)."' )"; -} -$sql .= ' AND bk.entity IN ('.getEntity('accountingbookkeeping').')'; -$sql .= $db->order($sortfield, $sortorder); - -$debit = 0; -$credit = 0; -$solde = 0; -// Count total nb of records and calc total sum -$nbtotalofrecords = ''; -$resql = $db->query($sql); -if (!$resql) { - dol_print_error($db); - exit; -} -$nbtotalofrecords = $db->num_rows($resql); - -while ($obj = $db->fetch_object($resql)) { - $debit += $obj->debit; - $credit += $obj->credit; - - $solde += ($obj->credit - $obj->debit); -} - -$sql .= $db->plimit($limit + 1, $offset); - -dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_supplier.php", LOG_DEBUG); -$resql = $db->query($sql); -if (!$resql) { - dol_print_error($db); - exit; -} - -$param = ''; -$param .= "&socid=".urlencode($socid); - -$num = $db->num_rows($resql); - -dol_syslog("/accountancy/bookkeeping/thirdparty_lettering_supplier.php", LOG_DEBUG); -$resql = $db->query($sql); -if ($resql) { - $num = $db->num_rows($resql); - $i = 0; - - $param = "&socid=".$socid; - print '
'; - print ''; - print ''; - - $letteringbutton = ''; - - print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies', 0, $letteringbutton, '', $limit); - - print '
'; - print ''."\n"; - - /* - print ''; - //print ''; - - // Date - print ''; - - // Piece - print ''; - print ''; - print ''; - print ''; - */ - - print ''; - //print_liste_field_titre("Doctype", $_SERVER["PHP_SELF"], "bk.doc_type", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Docdate", $_SERVER["PHP_SELF"], "bk.doc_date", "", $param, "", $sortfield, $sortorder, 'center '); - print_liste_field_titre("Piece", $_SERVER["PHP_SELF"], "bk.doc_ref", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("LabelAccount", $_SERVER["PHP_SELF"], "bk.label_compte", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Debit", $_SERVER["PHP_SELF"], "bk.debit", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Credit", $_SERVER["PHP_SELF"], "bk.credit", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Balancing", $_SERVER["PHP_SELF"], "", "", $param, "", $sortfield, $sortorder); - print_liste_field_titre("Codejournal", $_SERVER["PHP_SELF"], "bk.code_journal", "", $param, "", $sortfield, $sortorder, 'center '); - print_liste_field_titre("LetteringCode", $_SERVER["PHP_SELF"], "bk.lettering_code", "", $param, "", $sortfield, $sortorder, 'center '); - print_liste_field_titre("", "", "", '', '', "", $sortfield, $sortorder, 'maxwidthsearch center '); - print "\n"; - - $solde = 0; - $tmp = ''; - while ($obj = $db->fetch_object($resql)) { - if ($tmp != $obj->lettering_code || empty($tmp)) { - $tmp = $obj->lettering_code; - } - /*if ($tmp != $obj->lettering_code || empty($obj->lettering_code))*/ $solde += ($obj->credit - $obj->debit); - - print ''; - - //print '' . "\n"; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - // Journal - $accountingjournal = new AccountingJournal($db); - $result = $accountingjournal->fetch('', $obj->code_journal); - $journaltoshow = (($result > 0) ? $accountingjournal->getNomUrl(0, 0, 0, '', 0) : $obj->code_journal); - print ''; - - if (empty($obj->lettering_code) && empty($obj->date_validated)) { - print ''; - print ''."\n"; - } else { - print ''; - print ''; - } - - print "\n"; - } - - print ''; - print ''."\n"; - print ''; - print ''; - print ''; - print "\n"; - - print ''; - print ''."\n"; - print ''; - print ''; - print ''; - print "\n"; - - print "
'; - print '
'; - print $langs->trans('From') . ' '; - print $form->selectDate($search_date_start, 'date_creation_start', 0, 0, 1); - print '
'; - print '
'; - print $langs->trans('to') . ' '; - print $form->selectDate($search_date_end, 'date_creation_end', 0, 0, 1); - print '
'; - print '
 '; - $searchpicto = $form->showFilterButtons(); - print $searchpicto; - print '
' . $obj->doc_type . ''.dol_print_date($db->jdate($obj->doc_date), 'day').''.$obj->doc_ref.''.$obj->label_compte.''.price($obj->debit).''.price($obj->credit).''.price(round($solde, 2)).''.$journaltoshow.''; - print img_edit(); - print ''.$obj->lettering_code.'
'.$langs->trans("Total").':'.price($debit).''.price($credit).'
'.$langs->trans("Balancing").': '.price($credit - $debit).'
"; - - print '
'."\n"; - print $letteringbutton; - print '
'; - - print ""; - $db->free($resql); -} else { - dol_print_error($db); -} - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index 3c30200c130..c8c4099e67e 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -11,6 +11,7 @@ * Copyright (C) 2017-2019 Frédéric France * Copyright (C) 2017 André Schild * Copyright (C) 2020 Guillaume Alexandre + * Copyright (C) 2022 Joachim Kueter * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,6 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; /** @@ -93,11 +95,13 @@ class AccountancyExport */ public function __construct(DoliDB $db) { - global $conf; + global $conf, $hookmanager; $this->db = $db; $this->separator = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV; $this->end_line = empty($conf->global->ACCOUNTING_EXPORT_ENDLINE) ? "\n" : ($conf->global->ACCOUNTING_EXPORT_ENDLINE == 1 ? "\n" : "\r\n"); + + $hookmanager->initHooks(array('accountancyexport')); } /** @@ -105,9 +109,9 @@ class AccountancyExport * * @return array of type */ - public static function getType() + public function getType() { - global $langs; + global $langs, $hookmanager; $listofexporttypes = array( self::$EXPORT_TYPE_CONFIGURABLE => $langs->trans('Modelcsv_configurable'), @@ -132,6 +136,10 @@ class AccountancyExport self::$EXPORT_TYPE_ISUITEEXPERT => 'Export iSuite Expert', ); + // allow modules to define export formats + $parameters = array(); + $reshook = $hookmanager->executeHooks('getType', $parameters, $listofexporttypes); + ksort($listofexporttypes, SORT_NUMERIC); return $listofexporttypes; @@ -168,7 +176,12 @@ class AccountancyExport self::$EXPORT_TYPE_ISUITEEXPERT => 'isuiteexpert', ); - return $formatcode[$type]; + global $hookmanager; + $code = $formatcode[$type]; + $parameters = array('type' => $type); + $reshook = $hookmanager->executeHooks('getFormatCode', $parameters, $code); + + return $code; } /** @@ -176,11 +189,11 @@ class AccountancyExport * * @return array of type */ - public static function getTypeConfig() + public function getTypeConfig() { global $conf, $langs; - return array( + $exporttypes = array( 'param' => array( self::$EXPORT_TYPE_CONFIGURABLE => array( 'label' => $langs->trans('Modelcsv_configurable'), @@ -265,6 +278,11 @@ class AccountancyExport 'txt' => $langs->trans("txt") ), ); + + global $hookmanager; + $parameters = array(); + $reshook = $hookmanager->executeHooks('getTypeConfig', $parameters, $exporttypes); + return $exporttypes; } @@ -350,7 +368,13 @@ class AccountancyExport $this->exportiSuiteExpert($TData); break; default: - $this->errors[] = $langs->trans('accountancy_error_modelnotfound'); + global $hookmanager; + $parameters = array('format' => $formatexportset); + // file contents will be created in the hooked function via print + $reshook = $hookmanager->executeHooks('export', $parameters, $TData); + if ($reshook != 1) { + $this->errors[] = $langs->trans('accountancy_error_modelnotfound'); + } break; } } @@ -980,6 +1004,8 @@ class AccountancyExport print dol_string_unaccent($date_creation) . $separator; // FEC:EcritureLib + // Clean label operation to prevent problem on export with tab separator & other character + $line->label_operation = str_replace(array("\t", "\n", "\r"), " ", $line->label_operation); print dol_string_unaccent($line->label_operation) . $separator; // FEC:Debit @@ -1007,6 +1033,8 @@ class AccountancyExport print $date_limit_payment . $separator; // FEC_suppl:NumFacture + // Clean ref invoice to prevent problem on export with tab separator & other character + $refInvoice = str_replace(array("\t", "\n", "\r"), " ", $refInvoice); print dol_trunc(self::toAnsi($refInvoice), 17, 'right', 'UTF-8', 1); print $end_line; @@ -1107,6 +1135,8 @@ class AccountancyExport print $date_document . $separator; // FEC:EcritureLib + // Clean label operation to prevent problem on export with tab separator & other character + $line->label_operation = str_replace(array("\t", "\n", "\r"), " ", $line->label_operation); print dol_string_unaccent($line->label_operation) . $separator; // FEC:Debit @@ -1134,6 +1164,8 @@ class AccountancyExport print $date_limit_payment . $separator; // FEC_suppl:NumFacture + // Clean ref invoice to prevent problem on export with tab separator & other character + $refInvoice = str_replace(array("\t", "\n", "\r"), " ", $refInvoice); print dol_trunc(self::toAnsi($refInvoice), 17, 'right', 'UTF-8', 1); @@ -1712,6 +1744,8 @@ class AccountancyExport print self::trunc($line->label_compte, 60).$separator; //Account label print self::trunc($line->doc_ref, 20).$separator; //Piece + // Clean label operation to prevent problem on export with tab separator & other character + $line->label_operation = str_replace(array("\t", "\n", "\r"), " ", $line->label_operation); print self::trunc($line->label_operation, 60).$separator; //Operation label print price(abs($line->debit - $line->credit)).$separator; //Amount print $line->sens.$separator; //Direction diff --git a/htdocs/accountancy/class/accountancyimport.class.php b/htdocs/accountancy/class/accountancyimport.class.php index 8ca60e37796..5f4d76bc4c5 100644 --- a/htdocs/accountancy/class/accountancyimport.class.php +++ b/htdocs/accountancy/class/accountancyimport.class.php @@ -29,7 +29,7 @@ /** * \file htdocs/accountancy/class/accountancyimport.class.php * \ingroup Accountancy (Double entries) - * \brief Class accountancy import + * \brief Class with methods for accountancy import */ @@ -52,68 +52,91 @@ class AccountancyImport */ public function __construct(DoliDB $db) { - global $conf; - $this->db = $db; } + /** + * Clean amount + * + * @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... + * @param array $listfields Fields list to add + * @param int $record_key Record key + * @return mixed Value + */ + public function cleanAmount(&$arrayrecord, $listfields, $record_key) + { + $value_trim = trim($arrayrecord[$record_key]['val']); + return floatval($value_trim); + } + + /** + * Clean value with trim + * + * @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... + * @param array $listfields Fields list to add + * @param int $record_key Record key + * @return mixed Value + */ + public function cleanValue(&$arrayrecord, $listfields, $record_key) + { + return trim($arrayrecord[$record_key]['val']); + } + /** * Compute amount * * @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... - * @param string $fieldname Field name with alias * @param array $listfields Fields list to add - * @param array $listvalues Values list to add - * @return int <0 if KO, >0 if OK + * @param int $record_key Record key + * @return mixed Value */ - public function computeAmount(&$arrayrecord, $fieldname, &$listfields, &$listvalues) + public function computeAmount(&$arrayrecord, $listfields, $record_key) { - $fieldArr = explode('.', $fieldname); - if (count($fieldArr) > 0) { - $fieldname = $fieldArr[1]; + // get fields indexes + $field_index_list = array_flip($listfields); + if (isset($field_index_list['debit']) && isset($field_index_list['credit'])) { + $debit_index = $field_index_list['debit']; + $credit_index = $field_index_list['credit']; + + $debit = floatval($arrayrecord[$debit_index]['val']); + $credit = floatval($arrayrecord[$credit_index]['val']); + if (!empty($debit)) { + $amount = $debit; + } else { + $amount = $credit; + } + + return "'" . $this->db->escape(abs($amount)) . "'"; } - $debit = floatval(trim($arrayrecord[11]['val'])); - $credit = floatval(trim($arrayrecord[12]['val'])); - if (!empty($debit)) { - $amount = $debit; - } else { - $amount = $credit; - } - - $listfields[] = $fieldname; - $listvalues[] = "'" . abs($amount) . "'"; - - return 1; + return "''"; } /** - * Compute sens + * Compute direction * * @param array $arrayrecord Array of read values: [fieldpos] => (['val']=>val, ['type']=>-1=null,0=blank,1=string), [fieldpos+1]... - * @param string $fieldname Field name with alias * @param array $listfields Fields list to add - * @param array $listvalues Values list to add - * @return int <0 if KO, >0 if OK + * @param int $record_key Record key + * @return mixed Value */ - public function computeDirection(&$arrayrecord, $fieldname, &$listfields, &$listvalues) + public function computeDirection(&$arrayrecord, $listfields, $record_key) { - $fieldArr = explode('.', $fieldname); - if (count($fieldArr) > 0) { - $fieldname = $fieldArr[1]; + $field_index_list = array_flip($listfields); + if (isset($field_index_list['debit'])) { + $debit_index = $field_index_list['debit']; + + $debit = floatval($arrayrecord[$debit_index]['val']); + if (!empty($debit)) { + $sens = 'D'; + } else { + $sens = 'C'; + } + + return "'" . $this->db->escape($sens) . "'"; } - $debit = floatval(trim($arrayrecord[11]['val'])); - if (!empty($debit)) { - $sens = 'D'; - } else { - $sens = 'C'; - } - - $listfields[] = $fieldname; - $listvalues[] = "'" . $sens . "'"; - - return 1; + return "''"; } } diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index b50139a2d76..8cccef2d342 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -476,7 +476,7 @@ class AccountingAccount extends CommonObject */ public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1, $withcompletelabel = 0, $option = '') { - global $langs, $conf; + global $langs, $conf, $hookmanager; require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; if (!empty($conf->dol_no_mouse_hover)) { @@ -561,6 +561,15 @@ class AccountingAccount extends CommonObject if ($withpicto != 2) { $result .= $linkstart . $label_link . $linkend; } + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } @@ -577,11 +586,11 @@ class AccountingAccount extends CommonObject $sql .= ' WHERE a.rowid = ' . ((int) $id); dol_syslog(get_class($this) . '::info sql=' . $sql); - $result = $this->db->query($sql); + $resql = $this->db->query($sql); - if ($result) { - if ($this->db->num_rows($result)) { - $obj = $this->db->fetch_object($result); + if ($resql) { + if ($this->db->num_rows($resql)) { + $obj = $this->db->fetch_object($resql); $this->id = $obj->rowid; if ($obj->fk_user_author) { $cuser = new User($this->db); @@ -596,7 +605,7 @@ class AccountingAccount extends CommonObject $this->date_creation = $this->db->jdate($obj->datec); $this->date_modification = $this->db->jdate($obj->tms); } - $this->db->free($result); + $this->db->free($resql); } else { dol_print_error($this->db); } @@ -739,6 +748,7 @@ class AccountingAccount extends CommonObject $reshook = $hookmanager->executeHooks('accountancyBindingCalculation', $parameters); // Note that $action and $object may have been modified by some hooks if (empty($reshook)) { + $const_name = ''; if ($type == 'customer') { $const_name = "SOLD"; } elseif ($type == 'supplier') { diff --git a/htdocs/accountancy/class/accountingjournal.class.php b/htdocs/accountancy/class/accountingjournal.class.php index 376178b45ba..d805838566f 100644 --- a/htdocs/accountancy/class/accountingjournal.class.php +++ b/htdocs/accountancy/class/accountingjournal.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2017-2022 OpenDSI * * 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 @@ -81,6 +81,24 @@ class AccountingJournal extends CommonObject */ public $lines; + /** + * @var array Accounting account cached + */ + static public $accounting_account_cached = array(); + + /** + * @var array Nature mapping + */ + static public $nature_maps = array( + 1 => 'variousoperations', + 2 => 'sells', + 3 => 'purchases', + 4 => 'bank', + 5 => 'expensereports', + 8 => 'inventories', + 9 => 'hasnew', + ); + /** * Constructor * @@ -221,7 +239,7 @@ class AccountingJournal extends CommonObject */ public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0) { - global $langs, $conf, $user; + global $langs, $conf, $user, $hookmanager; if (!empty($conf->dol_no_mouse_hover)) { $notooltip = 1; // Force disable tooltips @@ -276,6 +294,15 @@ class AccountingJournal extends CommonObject } $result .= $linkend; + global $action; + $hookmanager->initHooks(array('accountingjournaldao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } @@ -336,4 +363,680 @@ class AccountingJournal extends CommonObject } } } + + + /** + * Get journal data + * + * @param User $user User who get infos + * @param string $type Type data returned ('view', 'bookkeeping', 'csv') + * @param int $date_start Filter 'start date' + * @param int $date_end Filter 'end date' + * @param string $in_bookkeeping Filter 'in bookkeeping' ('already', 'notyet') + * @return array|int <0 if KO, >0 if OK + */ + public function getData(User $user, $type = 'view', $date_start = null, $date_end = null, $in_bookkeeping = 'notyet') + { + global $hookmanager; + + // Clean parameters + if (empty($type)) $type = 'view'; + if (empty($in_bookkeeping)) $in_bookkeeping = 'notyet'; + + // Hook + if (!is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + + $data = array(); + + $hookmanager->initHooks(array('accountingjournaldao')); + $parameters = array('data' => &$data, 'user' => $user, 'type' => $type, 'date_start' => $date_start, 'date_end' => $date_end, 'in_bookkeeping' => $in_bookkeeping); + $reshook = $hookmanager->executeHooks('getData', $parameters, $this); // Note that $action and $object may have been + if ($reshook < 0) { + $this->error = $hookmanager->error; + $this->errors = $hookmanager->errors; + return -1; + } elseif (empty($reshook)) { + switch ($this->nature) { + case 1: // Various Journal + $data = $this->getAssetData($user, $type, $date_start, $date_end, $in_bookkeeping); + break; + // case 2: // Sells Journal + // case 3: // Purchases Journal + // case 4: // Bank Journal + // case 5: // Expense reports Journal + // case 8: // Inventory Journal + // case 9: // hasnew Journal + } + } + + return $data; + } + + /** + * Get asset data for various journal + * + * @param User $user User who get infos + * @param string $type Type data returned ('view', 'bookkeeping', 'csv') + * @param int $date_start Filter 'start date' + * @param int $date_end Filter 'end date' + * @param string $in_bookkeeping Filter 'in bookkeeping' ('already', 'notyet') + * @return array|int <0 if KO, >0 if OK + */ + public function getAssetData(User $user, $type = 'view', $date_start = null, $date_end = null, $in_bookkeeping = 'notyet') + { + global $conf, $langs; + + if (empty($conf->asset->enabled)) { + return array(); + } + + require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php'; + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php'; + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php'; + + $langs->loadLangs(array("assets")); + + // Clean parameters + if (empty($type)) $type = 'view'; + if (empty($in_bookkeeping)) $in_bookkeeping = 'notyet'; + + $sql = ""; + if ($in_bookkeeping == 'already' || $in_bookkeeping == 'notyet') { + $sql .= "WITH in_accounting_bookkeeping(fk_docdet) AS ("; + $sql .= " SELECT DISTINCT fk_docdet"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping"; + $sql .= " WHERE doc_type = 'asset'"; + $sql .= ")"; + } + $sql .= "SELECT ad.fk_asset AS rowid, a.ref AS asset_ref, a.label AS asset_label, a.acquisition_value_ht AS asset_acquisition_value_ht"; + $sql .= ", a.disposal_date AS asset_disposal_date, a.disposal_amount_ht AS asset_disposal_amount_ht, a.disposal_subject_to_vat AS asset_disposal_subject_to_vat"; + $sql .= ", ad.rowid AS depreciation_id, ad.depreciation_mode, ad.ref AS depreciation_ref, ad.depreciation_date, ad.depreciation_ht, ad.accountancy_code_debit, ad.accountancy_code_credit"; + $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation as ad"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "asset as a ON a.rowid = ad.fk_asset"; + if ($in_bookkeeping == 'already' || $in_bookkeeping == 'notyet') { + $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid"; + } + $sql .= " WHERE a.entity IN (" . getEntity('asset', 0) . ')'; // We don't share object for accountancy, we use source object sharing + $sql .= " AND ad.ref != ''"; // not reversal lines + if ($date_start && $date_end) { + $sql .= " AND ad.depreciation_date >= '" . $this->db->idate($date_start) . "' AND ad.depreciation_date <= '" . $this->db->idate($date_end) . "'"; + } + // Define begin binding date + if (!empty($conf->global->ACCOUNTING_DATE_START_BINDING)) { + $sql .= " AND ad.depreciation_date >= '" . $this->db->idate($conf->global->ACCOUNTING_DATE_START_BINDING) . "'"; + } + // Already in bookkeeping or not + if ($in_bookkeeping == 'already' || $in_bookkeeping == 'notyet') { + $sql .= " AND iab.fk_docdet IS" . ($in_bookkeeping == 'already' ? " NOT" : "") . " NULL"; + } + $sql .= " ORDER BY ad.depreciation_date"; + + dol_syslog(__METHOD__, LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $this->db->lasterror(); + return -1; + } + + $pre_data = array( + 'elements' => array(), + ); + while ($obj = $this->db->fetch_object($resql)) { + if (!isset($pre_data['elements'][$obj->rowid])) { + $pre_data['elements'][$obj->rowid] = array( + 'ref' => $obj->asset_ref, + 'label' => $obj->asset_label, + 'acquisition_value_ht' => $obj->asset_acquisition_value_ht, + 'depreciation' => array(), + ); + + // Disposal infos + if (isset($obj->asset_disposal_date)) { + $pre_data['elements'][$obj->rowid]['disposal'] = array( + 'date' => $this->db->jdate($obj->asset_disposal_date), + 'amount' => $obj->asset_disposal_amount_ht, + 'subject_to_vat' => !empty($obj->asset_disposal_subject_to_vat), + ); + } + } + + $compta_debit = empty($obj->accountancy_code_debit) ? 'NotDefined' : $obj->accountancy_code_debit; + $compta_credit = empty($obj->accountancy_code_credit) ? 'NotDefined' : $obj->accountancy_code_credit; + + $pre_data['elements'][$obj->rowid]['depreciation'][$obj->depreciation_id] = array( + 'date' => $this->db->jdate($obj->depreciation_date), + 'ref' => $obj->depreciation_ref, + 'lines' => array( + $compta_debit => -$obj->depreciation_ht, + $compta_credit => $obj->depreciation_ht, + ), + ); + } + + $disposal_ref = $langs->transnoentitiesnoconv('AssetDisposal'); + $journal = $this->code; + $journal_label = $this->label; + $journal_label_formatted = $langs->transnoentities($journal_label); + $now = dol_now(); + + $element_static = new Asset($this->db); + + $journal_data = array(); + foreach ($pre_data['elements'] as $pre_data_id => $pre_data_info) { + $element_static->id = $pre_data_id; + $element_static->ref = (string) $pre_data_info["ref"]; + $element_static->label = (string) $pre_data_info["label"]; + $element_static->acquisition_value_ht = $pre_data_info["acquisition_value_ht"]; + $element_link = $element_static->getNomUrl(1, 'with_label'); + + $element_name_formatted_0 = dol_trunc($element_static->label, 16); + $element_name_formatted_1 = utf8_decode(dol_trunc($element_static->label, 32)); + $element_name_formatted_2 = utf8_decode(dol_trunc($element_static->label, 16)); + $label_operation = $element_static->getNomUrl(0, 'label', 16); + + $element = array( + 'ref' => dol_trunc($element_static->ref, 16, 'right', 'UTF-8', 1), + 'error' => $pre_data_info['error'], + 'blocks' => array(), + ); + + // Depreciation lines + //-------------------- + foreach ($pre_data_info['depreciation'] as $depreciation_id => $line) { + $depreciation_ref = $line["ref"]; + $depreciation_date = $line["date"]; + $depreciation_date_formatted = dol_print_date($depreciation_date, 'day'); + + // lines + $blocks = array(); + foreach ($line['lines'] as $account => $mt) { + $account_infos = $this->getAccountingAccountInfos($account); + + if ($type == 'view') { + $account_to_show = length_accounta($account); + if (($account_to_show == "") || $account_to_show == 'NotDefined') { + $account_to_show = '' . $langs->trans("AssetInAccountNotDefined") . ''; + } + + $blocks[] = array( + 'date' => $depreciation_date_formatted, + 'piece' => $element_link, + 'account_accounting' => $account_to_show, + 'subledger_account' => '', + 'label_operation' => $label_operation . ' - ' . $depreciation_ref, + 'debit' => $mt < 0 ? price(-$mt) : '', + 'credit' => $mt >= 0 ? price($mt) : '', + ); + } elseif ($type == 'bookkeeping') { + if ($account_infos['found']) { + $blocks[] = array( + 'doc_date' => $depreciation_date, + 'date_lim_reglement' => '', + 'doc_ref' => $element_static->ref, + 'date_creation' => $now, + 'doc_type' => 'asset', + 'fk_doc' => $element_static->id, + 'fk_docdet' => $depreciation_id, // Useless, can be several lines that are source of this record to add + 'thirdparty_code' => '', + 'subledger_account' => '', + 'subledger_label' => '', + 'numero_compte' => $account, + 'label_compte' => $account_infos['label'], + 'label_operation' => $element_name_formatted_0 . ' - ' . $depreciation_ref, + 'montant' => $mt, + 'sens' => $mt < 0 ? 'D' : 'C', + 'debit' => $mt < 0 ? -$mt : 0, + 'credit' => $mt >= 0 ? $mt : 0, + 'code_journal' => $journal, + 'journal_label' => $journal_label_formatted, + 'piece_num' => '', + 'import_key' => '', + 'fk_user_author' => $user->id, + 'entity' => $conf->entity, + ); + } + } else { // $type == 'csv' + $blocks[] = array( + $depreciation_date, // Date + $element_static->ref, // Piece + $account_infos['code_formatted_1'], // AccountAccounting + $element_name_formatted_0 . ' - ' . $depreciation_ref, // LabelOperation + $mt < 0 ? price(-$mt) : '', // Debit + $mt >= 0 ? price($mt) : '', // Credit + ); + } + } + $element['blocks'][] = $blocks; + } + + // Disposal line + //-------------------- + if (!empty($pre_data_info['disposal'])) { + $disposal_date = $pre_data_info['disposal']['date']; + + if ((!($date_start && $date_end) || ($date_start <= $disposal_date && $disposal_date <= $date_end)) && + (empty($conf->global->ACCOUNTING_DATE_START_BINDING) || $conf->global->ACCOUNTING_DATE_START_BINDING <= $disposal_date) + ) { + $disposal_amount = $pre_data_info['disposal']['amount']; + $disposal_subject_to_vat = $pre_data_info['disposal']['subject_to_vat']; + $disposal_date_formatted = dol_print_date($disposal_date, 'day'); + $disposal_vat = $conf->global->ASSET_DISPOSAL_VAT > 0 ? $conf->global->ASSET_DISPOSAL_VAT : 20; + + // Get accountancy codes + //--------------------------- + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php'; + $accountancy_codes = new AssetAccountancyCodes($this->db); + $result = $accountancy_codes->fetchAccountancyCodes($element_static->id); + if ($result < 0) { + $element['error'] = $accountancy_codes->errorsToString(); + } else { + // Get last depreciation cumulative amount + $element_static->fetchDepreciationLines(); + foreach ($element_static->depreciation_lines as $mode_key => $depreciation_lines) { + $accountancy_codes_list = $accountancy_codes->accountancy_codes[$mode_key]; + + if (!isset($accountancy_codes_list['value_asset_sold'])) { + continue; + } + + $accountancy_code_value_asset_sold = empty($accountancy_codes_list['value_asset_sold']) ? 'NotDefined' : $accountancy_codes_list['value_asset_sold']; + $accountancy_code_depreciation_asset = empty($accountancy_codes_list['depreciation_asset']) ? 'NotDefined' : $accountancy_codes_list['depreciation_asset']; + $accountancy_code_asset = empty($accountancy_codes_list['asset']) ? 'NotDefined' : $accountancy_codes_list['asset']; + $accountancy_code_receivable_on_assignment = empty($accountancy_codes_list['receivable_on_assignment']) ? 'NotDefined' : $accountancy_codes_list['receivable_on_assignment']; + $accountancy_code_vat_collected = empty($accountancy_codes_list['vat_collected']) ? 'NotDefined' : $accountancy_codes_list['vat_collected']; + $accountancy_code_proceeds_from_sales = empty($accountancy_codes_list['proceeds_from_sales']) ? 'NotDefined' : $accountancy_codes_list['proceeds_from_sales']; + + $last_cumulative_amount_ht = 0; + $depreciated_ids = array_keys($pre_data_info['depreciation']); + foreach ($depreciation_lines as $line) { + $last_cumulative_amount_ht = $line['cumulative_depreciation_ht']; + if (!in_array($line['id'], $depreciated_ids) && empty($line['bookkeeping']) && !empty($line['ref'])) { + break; + } + } + + $lines = array(); + $lines[0][$accountancy_code_value_asset_sold] = -($element_static->acquisition_value_ht - $last_cumulative_amount_ht); + $lines[0][$accountancy_code_depreciation_asset] = -$last_cumulative_amount_ht; + $lines[0][$accountancy_code_asset] = $element_static->acquisition_value_ht; + + $disposal_amount_vat = $disposal_subject_to_vat ? (double) price2num($disposal_amount * $disposal_vat / 100, 'MT') : 0; + $lines[1][$accountancy_code_receivable_on_assignment] = -($disposal_amount + $disposal_amount_vat); + if ($disposal_subject_to_vat) $lines[1][$accountancy_code_vat_collected] = $disposal_amount_vat; + $lines[1][$accountancy_code_proceeds_from_sales] = $disposal_amount; + + foreach ($lines as $lines_block) { + $blocks = array(); + foreach ($lines_block as $account => $mt) { + $account_infos = $this->getAccountingAccountInfos($account); + + if ($type == 'view') { + $account_to_show = length_accounta($account); + if (($account_to_show == "") || $account_to_show == 'NotDefined') { + $account_to_show = '' . $langs->trans("AssetInAccountNotDefined") . ''; + } + + $blocks[] = array( + 'date' => $disposal_date_formatted, + 'piece' => $element_link, + 'account_accounting' => $account_to_show, + 'subledger_account' => '', + 'label_operation' => $label_operation . ' - ' . $disposal_ref, + 'debit' => $mt < 0 ? price(-$mt) : '', + 'credit' => $mt >= 0 ? price($mt) : '', + ); + } elseif ($type == 'bookkeeping') { + if ($account_infos['found']) { + $blocks[] = array( + 'doc_date' => $disposal_date, + 'date_lim_reglement' => '', + 'doc_ref' => $element_static->ref, + 'date_creation' => $now, + 'doc_type' => 'asset', + 'fk_doc' => $element_static->id, + 'fk_docdet' => 0, // Useless, can be several lines that are source of this record to add + 'thirdparty_code' => '', + 'subledger_account' => '', + 'subledger_label' => '', + 'numero_compte' => $account, + 'label_compte' => $account_infos['label'], + 'label_operation' => $element_name_formatted_0 . ' - ' . $disposal_ref, + 'montant' => $mt, + 'sens' => $mt < 0 ? 'D' : 'C', + 'debit' => $mt < 0 ? -$mt : 0, + 'credit' => $mt >= 0 ? $mt : 0, + 'code_journal' => $journal, + 'journal_label' => $journal_label_formatted, + 'piece_num' => '', + 'import_key' => '', + 'fk_user_author' => $user->id, + 'entity' => $conf->entity, + ); + } + } else { // $type == 'csv' + $blocks[] = array( + $disposal_date, // Date + $element_static->ref, // Piece + $account_infos['code_formatted_1'], // AccountAccounting + $element_name_formatted_0 . ' - ' . $disposal_ref, // LabelOperation + $mt < 0 ? price(-$mt) : '', // Debit + $mt >= 0 ? price($mt) : '', // Credit + ); + } + } + $element['blocks'][] = $blocks; + } + } + } + } + } + + $journal_data[$pre_data_id] = $element; + } + unset($pre_data); + + return $journal_data; + } + + /** + * Write bookkeeping + * + * @param User $user User who write in the bookkeeping + * @param array $journal_data Journal data to write in the bookkeeping + * $journal_data = array( + * id_element => array( + * 'ref' => 'ref', + * 'error' => '', + * 'blocks' => array( + * pos_block => array( + * num_line => array( + * 'doc_date' => '', + * 'date_lim_reglement' => '', + * 'doc_ref' => '', + * 'date_creation' => '', + * 'doc_type' => '', + * 'fk_doc' => '', + * 'fk_docdet' => '', + * 'thirdparty_code' => '', + * 'subledger_account' => '', + * 'subledger_label' => '', + * 'numero_compte' => '', + * 'label_compte' => '', + * 'label_operation' => '', + * 'montant' => '', + * 'sens' => '', + * 'debit' => '', + * 'credit' => '', + * 'code_journal' => '', + * 'journal_label' => '', + * 'piece_num' => '', + * 'import_key' => '', + * 'fk_user_author' => '', + * 'entity' => '', + * ), + * ), + * ), + * ), + * ); + * @param int $max_nb_errors Nb error authorized before stop the process + * @return int <0 if KO, >0 if OK + */ + public function writeIntoBookkeeping(User $user, &$journal_data = array(), $max_nb_errors = 10) + { + global $conf, $langs, $hookmanager; + require_once DOL_DOCUMENT_ROOT . '/accountancy/class/bookkeeping.class.php'; + + // Hook + if (!is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + + $error = 0; + + $hookmanager->initHooks(array('accountingjournaldao')); + $parameters = array('journal_data' => &$journal_data); + $reshook = $hookmanager->executeHooks('writeBookkeeping', $parameters, $this); // Note that $action and $object may have been + if ($reshook < 0) { + $this->error = $hookmanager->error; + $this->errors = $hookmanager->errors; + return -1; + } elseif (empty($reshook)) { + // Clean parameters + $journal_data = is_array($journal_data) ? $journal_data : array(); + + foreach ($journal_data as $element_id => $element) { + $error_for_line = 0; + $total_credit = 0; + $total_debit = 0; + + $this->db->begin(); + + if ($element['error'] == 'somelinesarenotbound') { + $error++; + $error_for_line++; + $this->errors[] = $langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $element['ref']); + } + + if (!$error_for_line) { + foreach ($element['blocks'] as $lines) { + foreach ($lines as $line) { + $bookkeeping = new BookKeeping($this->db); + $bookkeeping->doc_date = $line['doc_date']; + $bookkeeping->date_lim_reglement = $line['date_lim_reglement']; + $bookkeeping->doc_ref = $line['doc_ref']; + $bookkeeping->date_creation = $line['date_creation']; // not used + $bookkeeping->doc_type = $line['doc_type']; + $bookkeeping->fk_doc = $line['fk_doc']; + $bookkeeping->fk_docdet = $line['fk_docdet']; + $bookkeeping->thirdparty_code = $line['thirdparty_code']; + $bookkeeping->subledger_account = $line['subledger_account']; + $bookkeeping->subledger_label = $line['subledger_label']; + $bookkeeping->numero_compte = $line['numero_compte']; + $bookkeeping->label_compte = $line['label_compte']; + $bookkeeping->label_operation = $line['label_operation']; + $bookkeeping->montant = $line['montant']; + $bookkeeping->sens = $line['sens']; + $bookkeeping->debit = $line['debit']; + $bookkeeping->credit = $line['credit']; + $bookkeeping->code_journal = $line['code_journal']; + $bookkeeping->journal_label = $line['journal_label']; + $bookkeeping->piece_num = $line['piece_num']; + $bookkeeping->import_key = $line['import_key']; + $bookkeeping->fk_user_author = $user->id; + $bookkeeping->entity = $conf->entity; + + $total_debit += $bookkeeping->debit; + $total_credit += $bookkeeping->credit; + + $result = $bookkeeping->create($user); + if ($result < 0) { + if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists + $error++; + $error_for_line++; + $journal_data[$element_id]['error'] = 'alreadyjournalized'; + } else { + $error++; + $error_for_line++; + $journal_data[$element_id]['error'] = 'other'; + $this->errors[] = $bookkeeping->errorsToString(); + } + } + // + // if (!$error_for_line && !empty($conf->asset->enabled) && $this->nature == 1 && $bookkeeping->fk_doc > 0) { + // // Set last cumulative depreciation + // require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php'; + // $asset = new Asset($this->db); + // $result = $asset->setLastCumulativeDepreciation($bookkeeping->fk_doc); + // if ($result < 0) { + // $error++; + // $error_for_line++; + // $journal_data[$element_id]['error'] = 'other'; + // $this->errors[] = $asset->errorsToString(); + // } + // } + } + + if ($error_for_line) { + break; + } + } + } + + // Protection against a bug on lines before + if (!$error_for_line && (price2num($total_debit, 'MT') != price2num($total_credit, 'MT'))) { + $error++; + $error_for_line++; + $journal_data[$element_id]['error'] = 'amountsnotbalanced'; + $this->errors[] = 'Try to insert a non balanced transaction in book for ' . $element['blocks'] . '. Canceled. Surely a bug.'; + } + + if (!$error_for_line) { + $this->db->commit(); + } else { + $this->db->rollback(); + + if ($error >= $max_nb_errors) { + $this->errors[] = $langs->trans("ErrorTooManyErrorsProcessStopped"); + break; // Break in the foreach + } + } + } + } + + return $error ? -$error : 1; + } + + /** + * Export journal CSV + * ISO and not UTF8 ! + * + * @param array $journal_data Journal data to write in the bookkeeping + * $journal_data = array( + * id_element => array( + * 'continue' => false, + * 'blocks' => array( + * pos_block => array( + * num_line => array( + * data to write in the CSV line + * ), + * ), + * ), + * ), + * ); + * @param int $search_date_end Search date end + * @param string $sep CSV separator + * @return int|string <0 if KO, >0 if OK + */ + public function exportCsv(&$journal_data = array(), $search_date_end = 0, $sep = '') + { + global $conf, $langs, $hookmanager; + + if (empty($sep)) $sep = $conf->global->ACCOUNTING_EXPORT_SEPARATORCSV; + $out = ''; + + // Hook + if (!is_object($hookmanager)) { + include_once DOL_DOCUMENT_ROOT . '/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($this->db); + } + + $hookmanager->initHooks(array('accountingjournaldao')); + $parameters = array('journal_data' => &$journal_data, 'search_date_end' => &$search_date_end, 'sep' => &$sep, 'out' => &$out); + $reshook = $hookmanager->executeHooks('exportCsv', $parameters, $this); // Note that $action and $object may have been + if ($reshook < 0) { + $this->error = $hookmanager->error; + $this->errors = $hookmanager->errors; + return -1; + } elseif (empty($reshook)) { + // Clean parameters + $journal_data = is_array($journal_data) ? $journal_data : array(); + + // CSV header line + $header = array(); + if ($this->nature == 4) { + $header = array( + $langs->transnoentitiesnoconv("BankId"), + $langs->transnoentitiesnoconv("Date"), + $langs->transnoentitiesnoconv("PaymentMode"), + $langs->transnoentitiesnoconv("AccountAccounting"), + $langs->transnoentitiesnoconv("LedgerAccount"), + $langs->transnoentitiesnoconv("SubledgerAccount"), + $langs->transnoentitiesnoconv("Label"), + $langs->transnoentitiesnoconv("Debit"), + $langs->transnoentitiesnoconv("Credit"), + $langs->transnoentitiesnoconv("Journal"), + $langs->transnoentitiesnoconv("Note"), + ); + } elseif ($this->nature == 5) { + $header = array( + $langs->transnoentitiesnoconv("Date"), + $langs->transnoentitiesnoconv("Piece"), + $langs->transnoentitiesnoconv("AccountAccounting"), + $langs->transnoentitiesnoconv("LabelOperation"), + $langs->transnoentitiesnoconv("Debit"), + $langs->transnoentitiesnoconv("Credit"), + ); + } elseif ($this->nature == 1) { + $header = array( + $langs->transnoentitiesnoconv("Date"), + $langs->transnoentitiesnoconv("Piece"), + $langs->transnoentitiesnoconv("AccountAccounting"), + $langs->transnoentitiesnoconv("LabelOperation"), + $langs->transnoentitiesnoconv("Debit"), + $langs->transnoentitiesnoconv("Credit"), + ); + } + + if (!empty($header)) $out .= '"' . implode('"' . $sep . '"', $header) . '"' . "\n"; + foreach ($journal_data as $element_id => $element) { + foreach ($element['blocks'] as $lines) { + foreach ($lines as $line) { + $out .= '"' . implode('"' . $sep . '"', $line) . '"' . "\n"; + } + } + } + } + + return $out; + } + + /** + * Get accounting account infos + * + * @param string $account Accounting account number + * @return array Accounting account infos + */ + public function getAccountingAccountInfos($account) + { + if (!isset(self::$accounting_account_cached[$account])) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php'; + $accountingaccount = new AccountingAccount($this->db); + $result = $accountingaccount->fetch(null, $account, true); + if ($result > 0) { + self::$accounting_account_cached[$account] = array( + 'found' => true, + 'label' => $accountingaccount->label, + 'code_formatted_1' => length_accounta(html_entity_decode($account)), + 'label_formatted_1' => utf8_decode(dol_trunc($accountingaccount->label, 32)), + 'label_formatted_2' => dol_trunc($accountingaccount->label, 32), + ); + } else { + self::$accounting_account_cached[$account] = array( + 'found' => false, + 'label' => '', + 'code_formatted_1' => length_accounta(html_entity_decode($account)), + 'label_formatted_1' => '', + 'label_formatted_2' => '', + ); + } + } + + return self::$accounting_account_cached[$account]; + } } diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 7db9ab237dc..d01ad89293f 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -460,7 +460,7 @@ class BookKeeping extends CommonObject { global $db, $conf, $langs; global $dolibarr_main_authentication, $dolibarr_main_demo; - global $menumanager; + global $menumanager, $hookmanager; if (!empty($conf->dol_no_mouse_hover)) { $notooltip = 1; // Force disable tooltips @@ -512,6 +512,15 @@ class BookKeeping extends CommonObject $result .= $linkend; //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } @@ -843,7 +852,8 @@ class BookKeeping extends CommonObject $sql .= " t.piece_num,"; $sql .= " t.date_creation,"; $sql .= " t.date_export,"; - $sql .= " t.date_validated as date_validation"; + $sql .= " t.date_validated as date_validation,"; + $sql .= " t.import_key"; // Manage filter $sqlwhere = array(); if (count($filter) > 0) { @@ -938,6 +948,7 @@ class BookKeeping extends CommonObject $line->date_creation = $this->db->jdate($obj->date_creation); $line->date_export = $this->db->jdate($obj->date_export); $line->date_validation = $this->db->jdate($obj->date_validation); + $line->import_key = $obj->import_key; $this->lines[] = $line; @@ -1832,8 +1843,8 @@ class BookKeeping extends CommonObject /** * Transform transaction * - * @param number $direction If 0 tmp => real, if 1 real => tmp - * @param string $piece_num Piece num + * @param number $direction If 0: tmp => real, if 1: real => tmp + * @param string $piece_num Piece num = Transaction ref * @return int int <0 if KO, >0 if OK */ public function transformTransaction($direction = 0, $piece_num = '') diff --git a/htdocs/accountancy/class/lettering.class.php b/htdocs/accountancy/class/lettering.class.php index f722a716b79..405a630942e 100644 --- a/htdocs/accountancy/class/lettering.class.php +++ b/htdocs/accountancy/class/lettering.class.php @@ -33,6 +33,12 @@ include_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php"; */ class Lettering extends BookKeeping { + /** + * @var BookKeeping[] Bookkeeping cached + */ + public static $bookkeeping_cached = array(); + + /** * letteringThirdparty * @@ -119,6 +125,7 @@ class Lettering extends BookKeeping $ids[$obj2->rowid] = $obj2->rowid; $ids_fact[] = $obj2->fact_id; } + $this->db->free($resql2); } else { $this->errors[] = $this->db->lasterror; return -1; @@ -146,6 +153,7 @@ class Lettering extends BookKeeping while ($obj2 = $this->db->fetch_object($resql2)) { $ids[$obj2->rowid] = $obj2->rowid; } + $this->db->free($resql2); } else { $this->errors[] = $this->db->lasterror; return -1; @@ -205,6 +213,7 @@ class Lettering extends BookKeeping while ($obj2 = $this->db->fetch_object($resql2)) { $ids[$obj2->rowid] = $obj2->rowid; } + $this->db->free($resql2); } else { $this->errors[] = $this->db->lasterror; return -1; @@ -216,6 +225,7 @@ class Lettering extends BookKeeping $result = $this->updateLettering($ids); } } + $this->db->free($resql); } if ($error) { foreach ($this->errors as $errmsg) { @@ -230,39 +240,55 @@ class Lettering extends BookKeeping /** * - * @param array $ids ids array - * @param boolean $notrigger no trigger - * @return number + * @param array $ids ids array + * @param boolean $notrigger no trigger + * @return int */ public function updateLettering($ids = array(), $notrigger = false) { $error = 0; $lettre = 'AAA'; - $sql = "SELECT DISTINCT lettering_code FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE "; - $sql .= " lettering_code != '' ORDER BY lettering_code DESC limit 1"; + $sql = "SELECT DISTINCT ab2.lettering_code"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping As ab"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url AS bu ON bu.fk_bank = ab.fk_doc"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url AS bu2 ON bu2.url_id = bu.url_id"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab2 ON ab2.fk_doc = bu2.fk_bank"; + $sql .= " WHERE ab.rowid IN (" . $this->db->sanitize(implode(',', $ids)) . ")"; + $sql .= " AND ab.doc_type = 'bank'"; + $sql .= " AND ab2.doc_type = 'bank'"; + $sql .= " AND bu.type = 'company'"; + $sql .= " AND bu2.type = 'company'"; + $sql .= " AND ab.subledger_account != ''"; + $sql .= " AND ab2.subledger_account != ''"; + $sql .= " AND ab.lettering_code IS NULL"; + $sql .= " AND ab2.lettering_code != ''"; + $sql .= " ORDER BY ab2.lettering_code DESC"; + $sql .= " LIMIT 1 "; - $result = $this->db->query($sql); - if ($result) { - $obj = $this->db->fetch_object($result); + $resqla = $this->db->query($sql); + if ($resqla) { + $obj = $this->db->fetch_object($resqla); $lettre = (empty($obj->lettering_code) ? 'AAA' : $obj->lettering_code); if (!empty($obj->lettering_code)) { $lettre++; } + $this->db->free($resqla); } else { $this->errors[] = 'Error'.$this->db->lasterror(); $error++; } $sql = "SELECT SUM(ABS(debit)) as deb, SUM(ABS(credit)) as cred FROM ".MAIN_DB_PREFIX."accounting_bookkeeping WHERE "; - $sql .= " rowid IN (".$this->db->sanitize(implode(',', $ids)).") AND date_validated IS NULL"; - $result = $this->db->query($sql); - if ($result) { - $obj = $this->db->fetch_object($result); + $sql .= " rowid IN (".$this->db->sanitize(implode(',', $ids)).") AND lettering_code IS NULL AND subledger_account != ''"; + $resqlb = $this->db->query($sql); + if ($resqlb) { + $obj = $this->db->fetch_object($resqlb); if (!(round(abs($obj->deb), 2) === round(abs($obj->cred), 2))) { $this->errors[] = 'Total not exacts '.round(abs($obj->deb), 2).' vs '.round(abs($obj->cred), 2); $error++; } + $this->db->free($resqlb); } else { $this->errors[] = 'Erreur sql'.$this->db->lasterror(); $error++; @@ -276,8 +302,7 @@ class Lettering extends BookKeeping $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping SET"; $sql .= " lettering_code='".$this->db->escape($lettre)."'"; $sql .= " , date_lettering = '".$this->db->idate($now)."'"; // todo correct date it's false - $sql .= " WHERE rowid IN (".$this->db->sanitize(implode(',', $ids)).") AND date_validated IS NULL "; - $this->db->begin(); + $sql .= " WHERE rowid IN (".$this->db->sanitize(implode(',', $ids)).") AND lettering_code IS NULL AND subledger_account != ''"; dol_syslog(get_class($this)."::update", LOG_DEBUG); $resql = $this->db->query($sql); @@ -293,11 +318,431 @@ class Lettering extends BookKeeping dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); $this->error .= ($this->error ? ', '.$errmsg : $errmsg); } - $this->db->rollback(); return -1 * $error; } else { - $this->db->commit(); return 1; } } + + /** + * + * @param array $ids ids array + * @param boolean $notrigger no trigger + * @return int + */ + public function deleteLettering($ids, $notrigger = false) + { + $error = 0; + + $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping SET"; + $sql .= " lettering_code = NULL"; + $sql .= " , date_lettering = NULL"; + $sql .= " WHERE rowid IN (".$this->db->sanitize(implode(',', $ids)).")"; + $sql .= " AND subledger_account != ''"; + + dol_syslog(get_class($this)."::update", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = "Error ".$this->db->lasterror(); + } + + // Commit or rollback + if ($error) { + foreach ($this->errors as $errmsg) { + dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); + $this->error .= ($this->error ? ', '.$errmsg : $errmsg); + } + return -1 * $error; + } else { + return 1; + } + } + + /** + * Lettering bookkeeping lines all types + * + * @param array $bookkeeping_ids Lettering specific list of bookkeeping id + * @param bool $unlettering Do unlettering + * @return int <0 if error (nb lettered = result -1), 0 if noting to lettering, >0 if OK (nb lettered) + */ + public function bookkeepingLetteringAll($bookkeeping_ids, $unlettering = false) + { + dol_syslog(__METHOD__ . " - ", LOG_DEBUG); + + $error = 0; + $errors = array(); + $nb_lettering = 0; + + $result = $this->bookkeepingLettering($bookkeeping_ids, 'customer_invoice', $unlettering); + if ($result < 0) { + $error++; + $errors = array_merge($errors, $this->errors); + $nb_lettering += abs($result) - 2; + } else { + $nb_lettering += $result; + } + + $result = $this->bookkeepingLettering($bookkeeping_ids, 'supplier_invoice', $unlettering); + if ($result < 0) { + $error++; + $errors = array_merge($errors, $this->errors); + $nb_lettering += abs($result) - 2; + } else { + $nb_lettering += $result; + } + + if ($error) { + $this->errors = $errors; + return -2 - $nb_lettering; + } else { + return $nb_lettering; + } + } + + /** + * Lettering bookkeeping lines + * + * @param array $bookkeeping_ids Lettering specific list of bookkeeping id + * @param string $type Type of bookkeeping type to lettering ('customer_invoice' or 'supplier_invoice') + * @param bool $unlettering Do unlettering + * @return int <0 if error (nb lettered = result -1), 0 if noting to lettering, >0 if OK (nb lettered) + */ + public function bookkeepingLettering($bookkeeping_ids, $type = 'customer_invoice', $unlettering = false) + { + global $langs; + + $this->errors = array(); + + // Clean parameters + $bookkeeping_ids = is_array($bookkeeping_ids) ? $bookkeeping_ids : array(); + $type = trim($type); + + $error = 0; + $nb_lettering = 0; + $grouped_lines = $this->getLinkedLines($bookkeeping_ids, $type); + foreach ($grouped_lines as $lines) { + $group_error = 0; + $total = 0; + $do_it = !$unlettering; + $lettering_code = null; + $piece_num_lines = array(); + $bookkeeping_lines = array(); + foreach ($lines as $line_infos) { + $bookkeeping_lines[$line_infos['id']] = $line_infos['id']; + $piece_num_lines[$line_infos['piece_num']] = $line_infos['piece_num']; + $total += ($line_infos['credit'] > 0 ? $line_infos['credit'] : -$line_infos['debit']); + + // Check lettering code + if ($unlettering) { + if (isset($lettering_code) && $lettering_code != $line_infos['lettering_code']) { + $this->errors[] = $langs->trans('AccountancyErrorMismatchLetteringCode'); + $group_error++; + break; + } + if (!isset($lettering_code)) $lettering_code = (string) $line_infos['lettering_code']; + if (!empty($line_infos['lettering_code'])) $do_it = true; + } elseif (!empty($line_infos['lettering_code'])) $do_it = false; + } + + // Check balance amount + if (!$group_error && !$unlettering && price2num($total) != 0) { + $this->errors[] = $langs->trans('AccountancyErrorMismatchBalanceAmount', $total); + $group_error++; + } + + // Lettering/Unlettering the group of bookkeeping lines + if (!$group_error && $do_it) { + if ($unlettering) $result = $this->deleteLettering($bookkeeping_lines); + else $result = $this->updateLettering($bookkeeping_lines); + if ($result < 0) { + $group_error++; + } else { + $nb_lettering++; + } + } + + if ($group_error) { + $this->errors[] = $langs->trans('AccountancyErrorLetteringBookkeeping', implode(', ', $piece_num_lines)); + $error++; + } + } + + if ($error) { + return -2 - $nb_lettering; + } else { + return $nb_lettering; + } + } + + /** + * Lettering bookkeeping lines + * + * @param array $bookkeeping_ids Lettering specific list of bookkeeping id + * @param string $type Type of bookkeeping type to lettering ('customer_invoice' or 'supplier_invoice') + * @return array|int <0 if error otherwise all linked lines by block + */ + public function getLinkedLines($bookkeeping_ids, $type = 'customer_invoice') + { + global $conf, $langs; + $this->errors = array(); + + // Clean parameters + $bookkeeping_ids = is_array($bookkeeping_ids) ? $bookkeeping_ids : array(); + $type = trim($type); + + if ($type == 'customer_invoice') { + $doc_type = 'customer_invoice'; + $bank_url_type = 'payment'; + $payment_element = 'paiement_facture'; + $fk_payment_element = 'fk_paiement'; + $fk_element = 'fk_facture'; + $account_number = $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER; + } elseif ($type == 'supplier_invoice') { + $doc_type = 'supplier_invoice'; + $bank_url_type = 'payment_supplier'; + $payment_element = 'paiementfourn_facturefourn'; + $fk_payment_element = 'fk_paiementfourn'; + $fk_element = 'fk_facturefourn'; + $account_number = $conf->global->ACCOUNTING_ACCOUNT_SUPPLIER; + } else { + $langs->load('errors'); + $this->errors[] = $langs->trans('ErrorBadParameters'); + return -1; + } + + $payment_ids = array(); + + // Get all payment id from bank lines + $sql = "SELECT DISTINCT bu.url_id AS payment_id"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "bank_url AS bu ON bu.fk_bank = ab.fk_doc"; + $sql .= " WHERE ab.doc_type = 'bank'"; + // $sql .= " AND ab.subledger_account != ''"; + // $sql .= " AND ab.numero_compte = '" . $this->db->escape($account_number) . "'"; + $sql .= " AND bu.type = '" . $this->db->escape($bank_url_type) . "'"; + if (!empty($bookkeeping_ids)) $sql .= " AND ab.rowid IN (" . $this->db->sanitize(implode(',', $bookkeeping_ids)) . ")"; + + dol_syslog(__METHOD__ . " - Get all payment id from bank lines", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = "Error " . $this->db->lasterror(); + return -1; + } + + while ($obj = $this->db->fetch_object($resql)) { + $payment_ids[$obj->payment_id] = $obj->payment_id; + } + $this->db->free($resql); + + // Get all payment id from payment lines + $sql = "SELECT DISTINCT pe.$fk_payment_element AS payment_id"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "$payment_element AS pe ON pe.$fk_element = ab.fk_doc"; + $sql .= " WHERE ab.doc_type = '" . $this->db->escape($doc_type) . "'"; + // $sql .= " AND ab.subledger_account != ''"; + // $sql .= " AND ab.numero_compte = '" . $this->db->escape($account_number) . "'"; + $sql .= " AND pe.$fk_payment_element IS NOT NULL"; + if (!empty($bookkeeping_ids)) $sql .= " AND ab.rowid IN (" . $this->db->sanitize(implode(',', $bookkeeping_ids)) . ")"; + + dol_syslog(__METHOD__ . " - Get all payment id from bank lines", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = "Error " . $this->db->lasterror(); + return -1; + } + + while ($obj = $this->db->fetch_object($resql)) { + $payment_ids[$obj->payment_id] = $obj->payment_id; + } + $this->db->free($resql); + + if (empty($payment_ids)) { + return array(); + } + + // Get all payments linked by group + $payment_by_group = $this->getLinkedPaymentByGroup($payment_ids, $type); + + $groups = array(); + foreach ($payment_by_group as $payment_list) { + $lines = array(); + + // Get bank lines + $sql = "SELECT DISTINCT ab.rowid, ab.piece_num, ab.lettering_code, ab.debit, ab.credit"; + $sql .= " FROM " . MAIN_DB_PREFIX . "bank_url AS bu"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab ON ab.fk_doc = bu.fk_bank"; + $sql .= " WHERE bu.url_id IN (" . $this->db->sanitize(implode(',', $payment_list)) . ")"; + $sql .= " AND bu.type = '" . $this->db->escape($bank_url_type) . "'"; + $sql .= " AND ab.doc_type = 'bank'"; + $sql .= " AND ab.subledger_account != ''"; + $sql .= " AND ab.numero_compte = '" . $this->db->escape($account_number) . "'"; + + dol_syslog(__METHOD__ . " - Get bank lines", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = "Error " . $this->db->lasterror(); + return -1; + } + + while ($obj = $this->db->fetch_object($resql)) { + $lines[$obj->rowid] = array('id' => $obj->rowid, 'piece_num' => $obj->piece_num, 'lettering_code' => $obj->lettering_code, 'debit' => $obj->debit, 'credit' => $obj->credit); + } + $this->db->free($resql); + + // Get payment lines + $sql = "SELECT DISTINCT ab.rowid, ab.piece_num, ab.lettering_code, ab.debit, ab.credit"; + $sql .= " FROM " . MAIN_DB_PREFIX . "$payment_element AS pe"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_bookkeeping AS ab ON ab.fk_doc = pe.$fk_element"; + $sql .= " WHERE pe.$fk_payment_element IN (" . $this->db->sanitize(implode(',', $payment_list)) . ")"; + $sql .= " AND ab.doc_type = '" . $this->db->escape($doc_type) . "'"; + $sql .= " AND ab.subledger_account != ''"; + $sql .= " AND ab.numero_compte = '" . $this->db->escape($account_number) . "'"; + + dol_syslog(__METHOD__ . " - Get payment lines", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = "Error " . $this->db->lasterror(); + return -1; + } + + while ($obj = $this->db->fetch_object($resql)) { + $lines[$obj->rowid] = array('id' => $obj->rowid, 'piece_num' => $obj->piece_num, 'lettering_code' => $obj->lettering_code, 'debit' => $obj->debit, 'credit' => $obj->credit); + } + $this->db->free($resql); + + if (!empty($lines)) { + $groups[] = $lines; + } + } + + return $groups; + } + + /** + * Linked payment by group + * + * @param array $payment_ids list of payment id + * @param string $type Type of bookkeeping type to lettering ('customer_invoice' or 'supplier_invoice') + * @return array|int <0 if error otherwise all linked lines by block + */ + public function getLinkedPaymentByGroup($payment_ids, $type) + { + global $langs; + + // Clean parameters + $payment_ids = is_array($payment_ids) ? $payment_ids : array(); + $type = trim($type); + + if (empty($payment_ids)) { + return array(); + } + + if ($type == 'customer_invoice') { + $payment_element = 'paiement_facture'; + $fk_payment_element = 'fk_paiement'; + $fk_element = 'fk_facture'; + } elseif ($type == 'supplier_invoice') { + $payment_element = 'paiementfourn_facturefourn'; + $fk_payment_element = 'fk_paiementfourn'; + $fk_element = 'fk_facturefourn'; + } else { + $langs->load('errors'); + $this->errors[] = $langs->trans('ErrorBadParameters'); + return -1; + } + + // Get payment lines + $sql = "SELECT DISTINCT pe2.$fk_payment_element, pe2.$fk_element"; + $sql .= " FROM " . MAIN_DB_PREFIX . "$payment_element AS pe"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "$payment_element AS pe2 ON pe2.$fk_element = pe.$fk_element"; + $sql .= " WHERE pe.$fk_payment_element IN (" . $this->db->sanitize(implode(',', $payment_ids)) . ")"; + + dol_syslog(__METHOD__ . " - Get payment lines", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = "Error " . $this->db->lasterror(); + return -1; + } + + $current_payment_ids = array(); + $payment_by_element = array(); + $element_by_payment = array(); + while ($obj = $this->db->fetch_object($resql)) { + $current_payment_ids[$obj->$fk_payment_element] = $obj->$fk_payment_element; + $element_by_payment[$obj->$fk_payment_element][$obj->$fk_element] = $obj->$fk_element; + $payment_by_element[$obj->$fk_element][$obj->$fk_payment_element] = $obj->$fk_payment_element; + } + $this->db->free($resql); + + if (count(array_diff($payment_ids, $current_payment_ids))) { + return $this->getLinkedPaymentByGroup($current_payment_ids, $type); + } + + return $this->getGroupElements($payment_by_element, $element_by_payment); + } + + /** + * Get payment ids grouped by payment id and element id in common + * + * @param array $payment_by_element List of payment ids by element id + * @param array $element_by_payment List of element ids by payment id + * @param int $element_id Element Id (used for recursive function) + * @param array $current_group Current group (used for recursive function) + * @return array List of payment ids grouped by payment id and element id in common + */ + public function getGroupElements(&$payment_by_element, &$element_by_payment, $element_id = 0, &$current_group = array()) + { + $grouped_payments = array(); + if ($element_id > 0 && !isset($payment_by_element[$element_id])) { + // Return if specific element id not found + return $grouped_payments; + } + + $save_payment_by_element = null; + $save_element_by_payment = null; + if ($element_id == 0) { + // Save list when is the begin of recursive function + $save_payment_by_element = $payment_by_element; + $save_element_by_payment = $element_by_payment; + } + + do { + // Get current element id, get this payment id list and delete the entry + $current_element_id = $element_id > 0 ? $element_id : array_keys($payment_by_element)[0]; + $payment_ids = $payment_by_element[$current_element_id]; + unset($payment_by_element[$current_element_id]); + + foreach ($payment_ids as $payment_id) { + // Continue if payment id in not found + if (!isset($element_by_payment[$payment_id])) continue; + + // Set the payment in the current group + $current_group[$payment_id] = $payment_id; + + // Get current element ids, get this payment id list and delete the entry + $element_ids = $element_by_payment[$payment_id]; + unset($element_by_payment[$payment_id]); + + // Set payment id on the current group for each element id of the payment + foreach ($element_ids as $id) { + $this->getGroupElements($payment_by_element, $element_by_payment, $id, $current_group); + } + } + + if ($element_id == 0) { + // Save current group and reset the current group when is the begin of recursive function + $grouped_payments[] = $current_group; + $current_group = array(); + } + } while (!empty($payment_by_element) && $element_id == 0); + + if ($element_id == 0) { + // Restore list when is the begin of recursive function + $payment_by_element = $save_payment_by_element; + $element_by_payment = $save_element_by_payment; + } + + return $grouped_payments; + } } diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php index 0c55b9e608e..4a8080ab8b4 100644 --- a/htdocs/accountancy/customer/lines.php +++ b/htdocs/accountancy/customer/lines.php @@ -68,7 +68,7 @@ $search_tvaintra = GETPOST('search_tvaintra', 'alpha'); $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); -$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +$page = GETPOSTISSET('pageplusonPour le détail de la facture ref…e') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); if (empty($page) || $page < 0) { $page = 0; } @@ -496,8 +496,8 @@ if ($result) { } print ''; - print ''; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description)); + print ''; + $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description, 1)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description); print ''; diff --git a/htdocs/accountancy/customer/list.php b/htdocs/accountancy/customer/list.php index 80b7bdf2217..b9ea4fc0e54 100644 --- a/htdocs/accountancy/customer/list.php +++ b/htdocs/accountancy/customer/list.php @@ -5,6 +5,7 @@ * Copyright (C) 2013-2021 Florian Henry * Copyright (C) 2014 Juanjo Menent * Copyright (C) 2016 Laurent Destailleur + * Copyright (C) 2021 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -46,6 +47,7 @@ $show_files = GETPOST('show_files', 'int'); $confirm = GETPOST('confirm', 'alpha'); $toselect = GETPOST('toselect', 'array'); $optioncss = GETPOST('optioncss', 'alpha'); +$default_account = GETPOST('default_account', 'int'); // Select Box $mesCasesCochees = GETPOST('toselect', 'array'); @@ -434,12 +436,15 @@ if ($result) { $arrayofmassactions = array( 'ventil'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Ventilate") + ,'set_default_account'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("ConfirmPreselectAccount") //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), ); //if ($user->rights->mymodule->supprimer) $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); //if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); - $massactionbutton = $form->selectMassAction('ventil', $arrayofmassactions, 1); + if ($massaction !== 'set_default_account') { + $massactionbutton = $form->selectMassAction('ventil', $arrayofmassactions, 1); + } print '
'."\n"; print ''; @@ -454,6 +459,14 @@ if ($result) { print_barre_liste($langs->trans("InvoiceLines"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit); + if ($massaction == 'set_default_account') { + $formquestion[]=array('type' => 'other', + 'name' => 'set_default_account', + 'label' => $langs->trans("AccountancyCode"), + 'value' => $formaccounting->select_account('', 'default_account', 1, array(), 0, 0, 'maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone')); + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmPreselectAccount"), $langs->trans("ConfirmPreselectAccountQuestion", count($toselect)), "confirm_set_default_account", $formquestion, 1, 0, 200, 500, 1); + } + print ''.$langs->trans("DescVentilTodoCustomer").'

'; if ($msg) { @@ -637,7 +650,7 @@ if ($result) { // Description print ''; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($facture_static_det->desc)); + $text = dolGetFirstLineOfText(dol_string_nohtmltag($facture_static_det->desc, 1)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; print $form->textwithtooltip(dol_trunc($text, $trunclength), $facture_static_det->desc); print ''; @@ -712,7 +725,7 @@ if ($result) { // Suggested accounting account print ''; - print $formaccounting->select_account($suggestedid, 'codeventil'.$facture_static_det->id, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone'); + print $formaccounting->select_account(($default_account > 0 && $confirm === 'yes' && in_array($objp->rowid."_".$i, $toselect)) ? $default_account : $suggestedid, 'codeventil'.$facture_static_det->id, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone'); print ''; // Column with checkbox @@ -721,6 +734,14 @@ if ($result) { if (!empty($suggestedid) && $suggestedaccountingaccountfor != '' && $suggestedaccountingaccountfor != 'eecwithoutvatnumber') { $ischecked = 1; } + + if (!empty($toselect)) { + $ischecked = 0; + if (in_array($objp->rowid."_".$i, $toselect)) { + $ischecked=1; + } + } + print ''; print ''; diff --git a/htdocs/accountancy/expensereport/lines.php b/htdocs/accountancy/expensereport/lines.php index fb3bf1a6e04..005783ed7a8 100644 --- a/htdocs/accountancy/expensereport/lines.php +++ b/htdocs/accountancy/expensereport/lines.php @@ -1,6 +1,6 @@ - * Copyright (C) 2013-2017 Alexandre Spangaro + * Copyright (C) 2013-2022 Alexandre Spangaro * Copyright (C) 2014-2015 Ari Elbaz (elarifr) * Copyright (C) 2013-2016 Florian Henry * Copyright (C) 2014 Juanjo Menent @@ -26,8 +26,8 @@ */ require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; @@ -49,9 +49,14 @@ $search_desc = GETPOST('search_desc', 'alpha'); $search_amount = GETPOST('search_amount', 'alpha'); $search_account = GETPOST('search_account', 'alpha'); $search_vat = GETPOST('search_vat', 'alpha'); -$search_day = GETPOST("search_day", "int"); -$search_month = GETPOST("search_month", "int"); -$search_year = GETPOST("search_year", "int"); +$search_date_startday = GETPOST('search_date_startday', 'int'); +$search_date_startmonth = GETPOST('search_date_startmonth', 'int'); +$search_date_startyear = GETPOST('search_date_startyear', 'int'); +$search_date_endday = GETPOST('search_date_endday', 'int'); +$search_date_endmonth = GETPOST('search_date_endmonth', 'int'); +$search_date_endyear = GETPOST('search_date_endyear', 'int'); +$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); // Use tzserver +$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear); // Load variable for pagination $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); @@ -61,9 +66,9 @@ $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("pa if (empty($page) || $page < 0) { $page = 0; } +$offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; -$offset = $limit * $page; if (!$sortfield) { $sortfield = "erd.date, erd.rowid"; } @@ -101,9 +106,14 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_amount = ''; $search_account = ''; $search_vat = ''; - $search_day = ''; - $search_month = ''; - $search_year = ''; + $search_date_startday = ''; + $search_date_startmonth = ''; + $search_date_startyear = ''; + $search_date_endday = ''; + $search_date_endmonth = ''; + $search_date_endyear = ''; + $search_date_start = ''; + $search_date_end = ''; } if (is_array($changeaccount) && count($changeaccount) > 0 && $user->rights->accounting->bind->write) { @@ -204,7 +214,12 @@ if (strlen(trim($search_account))) { if (strlen(trim($search_vat))) { $sql .= natural_search("erd.tva_tx", price2num($search_vat), 1); } -$sql .= dolSqlDateFilter('erd.date', $search_day, $search_month, $search_year); +if ($search_date_start) { + $sql .= " AND erd.date >= '".$db->idate($search_date_start)."'"; +} +if ($search_date_end) { + $sql .= " AND erd.date <= '".$db->idate($search_date_end)."'"; +} $sql .= " AND er.entity IN (".getEntity('expensereport', 0).")"; // We don't share object for accountancy $sql .= $db->order($sortfield, $sortorder); @@ -222,9 +237,8 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $sql .= $db->plimit($limit + 1, $offset); -dol_syslog('accountancy/expensereport/lines.php::list'); +dol_syslog("accountancy/expensereport/lines.php", LOG_DEBUG); $result = $db->query($sql); - if ($result) { $num_lines = $db->num_rows($result); $i = 0; @@ -254,14 +268,23 @@ if ($result) { if ($search_vat) { $param .= "&search_vat=".urlencode($search_vat); } - if ($search_day) { - $param .= '&search_day='.urlencode($search_day); + if ($search_date_startday) { + $param .= '&search_date_startday='.urlencode($search_date_startday); } - if ($search_month) { - $param .= '&search_month='.urlencode($search_month); + if ($search_date_startmonth) { + $param .= '&search_date_startmonth='.urlencode($search_date_startmonth); } - if ($search_year) { - $param .= '&search_year='.urlencode($search_year); + if ($search_date_startyear) { + $param .= '&search_date_startyear='.urlencode($search_date_startyear); + } + if ($search_date_endday) { + $param .= '&search_date_endday='.urlencode($search_date_endday); + } + if ($search_date_endmonth) { + $param .= '&search_date_endmonth='.urlencode($search_date_endmonth); + } + if ($search_date_endyear) { + $param .= '&search_date_endyear='.urlencode($search_date_endyear); } print ''."\n"; @@ -276,12 +299,11 @@ if ($result) { print ''; print_barre_liste($langs->trans("ExpenseReportLinesDone"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit); - print ''.$langs->trans("DescVentilDoneExpenseReport").'
'; - print '
'.$langs->trans("ChangeAccount").'
'; + print '
'.$langs->trans("ChangeAccount").' '; print $formaccounting->select_account($account_parent, 'account_parent', 2, array(), 0, 0, 'maxwidth300 maxwidthonsmartphone valignmiddle'); - print '
'; + print '
'; $moreforfilter = ''; @@ -296,11 +318,12 @@ if ($result) { print ''; } print ''; - if (!empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) { - print ''; - } - print ''; - $formother->select_year($search_year, 'search_year', 1, 20, 5); + print '
'; + print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
'; + print '
'; + print $form->selectDate($search_date_end ? $search_date_end : -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
'; print ''; print ''; print ''; @@ -382,7 +405,7 @@ if ($result) { // Fees description -- Can be null print ''; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->comments)); + $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->comments, 1)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->comments); print ''; @@ -394,12 +417,11 @@ if ($result) { print ''.vatrate($objp->tva_tx.($objp->vat_src_code ? ' ('.$objp->vat_src_code.')' : '')).''; // Accounting account affected - print ''; + print ''; print $accountingaccountstatic->getNomUrl(0, 1, 1, '', 1); print ' '; print img_edit(); print ''; - print ''; print ""; diff --git a/htdocs/accountancy/expensereport/list.php b/htdocs/accountancy/expensereport/list.php index 863001c3bc0..033f1164dc7 100644 --- a/htdocs/accountancy/expensereport/list.php +++ b/htdocs/accountancy/expensereport/list.php @@ -1,6 +1,6 @@ - * Copyright (C) 2013-2017 Alexandre Spangaro + * Copyright (C) 2013-2022 Alexandre Spangaro * Copyright (C) 2014-2015 Ari Elbaz (elarifr) * Copyright (C) 2013-2014 Florian Henry * Copyright (C) 2014 Juanjo Menent s @@ -30,9 +30,9 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; // Load translation files required by the page @@ -59,9 +59,14 @@ $search_desc = GETPOST('search_desc', 'alpha'); $search_amount = GETPOST('search_amount', 'alpha'); $search_account = GETPOST('search_account', 'alpha'); $search_vat = GETPOST('search_vat', 'alpha'); -$search_day = GETPOST("search_day", "int"); -$search_month = GETPOST("search_month", "int"); -$search_year = GETPOST("search_year", "int"); +$search_date_startday = GETPOST('search_date_startday', 'int'); +$search_date_startmonth = GETPOST('search_date_startmonth', 'int'); +$search_date_startyear = GETPOST('search_date_startyear', 'int'); +$search_date_endday = GETPOST('search_date_endday', 'int'); +$search_date_endmonth = GETPOST('search_date_endmonth', 'int'); +$search_date_endyear = GETPOST('search_date_endyear', 'int'); +$search_date_start = dol_mktime(0, 0, 0, $search_date_startmonth, $search_date_startday, $search_date_startyear); // Use tzserver +$search_date_end = dol_mktime(23, 59, 59, $search_date_endmonth, $search_date_endday, $search_date_endyear); // Load variable for pagination $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : (empty($conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION) ? $conf->liste_limit : $conf->global->ACCOUNTING_LIMIT_LIST_VENTILATION); @@ -83,6 +88,9 @@ if (!$sortorder) { } } +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('accountancyexpensereportlist')); + $formaccounting = new FormAccounting($db); $accounting = new AccountingAccount($db); @@ -101,7 +109,7 @@ if (empty($user->rights->accounting->mouvements->lire)) { /* - * Action + * Actions */ if (GETPOST('cancel', 'alpha')) { @@ -111,30 +119,47 @@ if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massa $massaction = ''; } -// Purge search criteria -if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All test are required to be compatible with all browsers - $search_login = ''; - $search_expensereport = ''; - $search_label = ''; - $search_desc = ''; - $search_amount = ''; - $search_account = ''; - $search_vat = ''; - $search_day = ''; - $search_month = ''; - $search_year = ''; +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + // Purge search criteria + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All test are required to be compatible with all browsers + $search_login = ''; + $search_expensereport = ''; + $search_label = ''; + $search_desc = ''; + $search_amount = ''; + $search_account = ''; + $search_vat = ''; + $search_date_startday = ''; + $search_date_startmonth = ''; + $search_date_startyear = ''; + $search_date_endday = ''; + $search_date_endmonth = ''; + $search_date_endyear = ''; + $search_date_start = ''; + $search_date_end = ''; + $search_country = ''; + $search_tvaintra = ''; + } + + // Mass actions + $objectclass = 'ExpenseReport'; + $objectlabel = 'ExpenseReport'; + $permissiontoread = $user->rights->expensereport->read; + $permissiontodelete = $user->rights->expensereport->delete; + $uploaddir = $conf->expensereport->dir_output; + include DOL_DOCUMENT_ROOT . '/core/actions_massactions.inc.php'; } -// Mass actions -$objectclass = 'ExpenseReport'; -$objectlabel = 'ExpenseReport'; -$permissiontoread = $user->rights->expensereport->read; -$permissiontodelete = $user->rights->expensereport->delete; -$uploaddir = $conf->expensereport->dir_output; -include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; if ($massaction == 'ventil' && $user->rights->accounting->bind->write) { $msg = ''; + //print '
' . $langs->trans("Processing") . '...
'; if (!empty($mesCasesCochees)) { $msg = '
'.$langs->trans("SelectedLines").': '.count($mesCasesCochees).'
'; @@ -159,7 +184,7 @@ if ($massaction == 'ventil' && $user->rights->accounting->bind->write) { $accountventilated = new AccountingAccount($db); $accountventilated->fetch($monCompte, '', 1); - dol_syslog('accountancy/expensereport/list.php', LOG_DEBUG); + dol_syslog('accountancy/expensereport/list.php:: sql='.$sql, LOG_DEBUG); if ($db->query($sql)) { $msg .= '
'.$langs->trans("LineOfExpenseReport").' '.$monId.' - '.$langs->trans("VentilatedinAccount").' : '.length_accountg($accountventilated->account_number).'
'; $ok++; @@ -201,6 +226,9 @@ $sql .= " erd.rowid, erd.fk_c_type_fees, erd.comments, erd.total_ht as price, er $sql .= " f.id as type_fees_id, f.code as type_fees_code, f.label as type_fees_label, f.accountancy_code as code_buy,"; $sql .= " u.rowid as userid, u.login, u.lastname, u.firstname, u.email, u.gender, u.employee, u.photo, u.statut,"; $sql .= " aa.rowid as aarowid"; +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; $sql .= " FROM ".MAIN_DB_PREFIX."expensereport as er"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."expensereport_det as erd ON er.rowid = erd.fk_expensereport"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_type_fees as f ON f.id = erd.fk_c_type_fees"; @@ -233,9 +261,19 @@ if (strlen(trim($search_account))) { if (strlen(trim($search_vat))) { $sql .= natural_search("erd.tva_tx", $search_vat, 1); } -$sql .= dolSqlDateFilter('erd.date', $search_day, $search_month, $search_year); +if ($search_date_start) { + $sql .= " AND erd.date >= '".$db->idate($search_date_start)."'"; +} +if ($search_date_end) { + $sql .= " AND erd.date <= '".$db->idate($search_date_end)."'"; +} $sql .= " AND er.entity IN (".getEntity('expensereport', 0).")"; // We don't share object for accountancy +// Add where from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; + $sql .= $db->order($sortfield, $sortorder); // Count total nb of records @@ -251,7 +289,13 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $sql .= $db->plimit($limit + 1, $offset); -dol_syslog('accountancy/expensereport/list.php'); +dol_syslog("accountancy/expensereport/list.php", LOG_DEBUG); +// MAX_JOIN_SIZE can be very low (ex: 300000) on some limited configurations (ex: https://www.online.net/fr/hosting/online-perso) +// This big SELECT command may exceed the MAX_JOIN_SIZE limit => Therefore we use SQL_BIG_SELECTS=1 to disable the MAX_JOIN_SIZE security +if ($db->type == 'mysqli') { + $db->query("SET SQL_BIG_SELECTS=1"); +} + $result = $db->query($sql); if ($result) { $num_lines = $db->num_rows($result); @@ -272,14 +316,23 @@ if ($result) { if ($search_lineid) { $param .= '&search_lineid='.urlencode($search_lineid); } - if ($search_day) { - $param .= '&search_day='.urlencode($search_day); + if ($search_date_startday) { + $param .= '&search_date_startday='.urlencode($search_date_startday); } - if ($search_month) { - $param .= '&search_month='.urlencode($search_month); + if ($search_date_startmonth) { + $param .= '&search_date_startmonth='.urlencode($search_date_startmonth); } - if ($search_year) { - $param .= '&search_year='.urlencode($search_year); + if ($search_date_startyear) { + $param .= '&search_date_startyear='.urlencode($search_date_startyear); + } + if ($search_date_endday) { + $param .= '&search_date_endday='.urlencode($search_date_endday); + } + if ($search_date_endmonth) { + $param .= '&search_date_endmonth='.urlencode($search_date_endmonth); + } + if ($search_date_endyear) { + $param .= '&search_date_endyear='.urlencode($search_date_endyear); } if ($search_expensereport) { $param .= '&search_expensereport='.urlencode($search_expensereport); @@ -302,7 +355,6 @@ if ($result) { ); $massactionbutton = $form->selectMassAction('ventil', $arrayofmassactions, 1); - print ''."\n"; print ''; if ($optioncss != '') { @@ -335,20 +387,21 @@ if ($result) { if (!empty($conf->global->ACCOUNTANCY_USE_EXPENSE_REPORT_VALIDATION_DATE)) { print ''; } - print ''; - if (!empty($conf->global->MAIN_LIST_FILTER_ON_DAY)) { - print ''; - } - print ''; - $formother->select_year($search_year, 'search_year', 1, 20, 5); + print ''; + print '
'; + print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
'; + print '
'; + print $form->selectDate($search_date_end ? $search_date_end : -1, 'search_date_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
'; print ''; print ''; print ''; - print ''; - print ''; + print ''; + print ''; print ''; print ''; - print ''; + print ''; $searchpicto = $form->showFilterButtons(); print $searchpicto; print ''; @@ -428,7 +481,7 @@ if ($result) { // Fees description -- Can be null print ''; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->comments)); + $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->comments, 1)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->comments); print ''; @@ -468,6 +521,9 @@ if ($result) { } else { print $db->error(); } +if ($db->type == 'mysqli') { + $db->query("SET SQL_BIG_SELECTS=0"); // Enable MAX_JOIN_SIZE limitation +} // Add code to auto check the box when we select an account print ''; + +$object_label = $langs->trans("ObjectsRef"); +if ($object->nature == 2 || $object->nature == 3) $object_label = $langs->trans("InvoiceRef"); +if ($object->nature == 5) $object_label = $langs->trans("ExpenseReportRef"); + +/* + * Show result array + */ +print '
'; + +print '
'; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +if ($object->nature == 4) print ''; // bank +print ''; +print ''; +print "\n"; + +foreach ($journal_data as $element_id => $element) { + foreach ($element['blocks'] as $lines) { + foreach ($lines as $line) { + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if ($object->nature == 4) print ''; + print ''; + print ''; + print ''; + } + } +} + +print '
' . $langs->trans("Date") . '' . $langs->trans("Piece") . ' (' . $object_label . ')' . $langs->trans("AccountAccounting") . '' . $langs->trans("SubledgerAccount") . '' . $langs->trans("LabelOperation") . '' . $langs->trans("PaymentMode") . '' . $langs->trans("Debit") . '' . $langs->trans("Credit") . '
' . $line['date'] . '' . $line['piece'] . '' . $line['account_accounting'] . '' . $line['subledger_account'] . '' . $line['label_operation'] . '' . $line['payment_mode'] . '' . $line['debit'] . '' . $line['credit'] . '
'; +print '
'; + +llxFooter(); + +$db->close(); diff --git a/htdocs/accountancy/supplier/lines.php b/htdocs/accountancy/supplier/lines.php index cb6a4e203b4..914c355c838 100644 --- a/htdocs/accountancy/supplier/lines.php +++ b/htdocs/accountancy/supplier/lines.php @@ -1,9 +1,9 @@ - * Copyright (C) 2013-2021 Alexandre Spangaro - * Copyright (C) 2014-2015 Ari Elbaz (elarifr) - * Copyright (C) 2013-2016 Florian Henry - * Copyright (C) 2014 Juanjo Menent +/* Copyright (C) 2013-2016 Olivier Geffroy + * Copyright (C) 2013-2022 Alexandre Spangaro + * Copyright (C) 2014-2015 Ari Elbaz (elarifr) + * Copyright (C) 2013-2016 Florian Henry + * Copyright (C) 2014 Juanjo Menent * * 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 @@ -49,6 +49,7 @@ $search_societe = GETPOST('search_societe', 'alpha'); $search_lineid = GETPOST('search_lineid', 'int'); $search_ref = GETPOST('search_ref', 'alpha'); $search_invoice = GETPOST('search_invoice', 'alpha'); +$search_ref_supplier = GETPOST('search_ref_supplier', 'alpha'); $search_label = GETPOST('search_label', 'alpha'); $search_desc = GETPOST('search_desc', 'alpha'); $search_amount = GETPOST('search_amount', 'alpha'); @@ -112,6 +113,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_lineid = ''; $search_ref = ''; $search_invoice = ''; + $search_ref_supplier = ''; $search_label = ''; $search_desc = ''; $search_amount = ''; @@ -236,6 +238,9 @@ if ($search_lineid) { if (strlen(trim($search_invoice))) { $sql .= natural_search("f.ref", $search_invoice); } +if (strlen(trim($search_ref_supplier))) { + $sql .= natural_search("f.ref_supplier", $search_ref_supplier); +} if (strlen(trim($search_label))) { $sql .= natural_search("f.libelle", $search_label); } @@ -328,6 +333,9 @@ if ($result) { if ($search_ref) { $param .= "&search_ref=".urlencode($search_ref); } + if ($search_ref_supplier) { + $param .= '&search_ref_supplier='.urlencode($search_ref_supplier); + } if ($search_label) { $param .= "&search_label=".urlencode($search_label); } @@ -392,6 +400,7 @@ if ($result) { print ''; print ''; print ''; + print ''; print ''; print ''; print '
'; @@ -420,6 +429,7 @@ if ($result) { print ''; print_liste_field_titre("LineId", $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Invoice", $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("RefSupplier", $_SERVER["PHP_SELF"], "f.ref_supplier", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("InvoiceLabel", $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, '', $sortfield, $sortorder, 'center '); print_liste_field_titre("ProductRef", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); @@ -446,6 +456,9 @@ if ($result) { $facturefournisseur_static->ref = $objp->ref; $facturefournisseur_static->id = $objp->facid; + $facturefournisseur_static->type = $objp->ftype; + $facturefournisseur_static->ref_supplier = $objp->ref_supplier; + $facturefournisseur_static->label = $objp->invoice_label; $thirdpartystatic->id = $objp->socid; $thirdpartystatic->name = $objp->name; @@ -465,8 +478,8 @@ if ($result) { $productstatic->status = $objp->tosell; $productstatic->status_buy = $objp->tobuy; $productstatic->accountancy_code_buy = $objp->accountancy_code_buy; - $productstatic->accountancy_code_buy_intra = $objp->accountancy_code_sell_buy; - $productstatic->accountancy_code_buy_export = $objp->accountancy_code_sell_buy; + $productstatic->accountancy_code_buy_intra = $objp->accountancy_code_sell_buy_intra; + $productstatic->accountancy_code_buy_export = $objp->accountancy_code_sell_buy_export; $accountingaccountstatic->rowid = $objp->fk_compte; $accountingaccountstatic->label = $objp->label_account; @@ -481,7 +494,13 @@ if ($result) { // Ref Invoice print ''.$facturefournisseur_static->getNomUrl(1).''; - print ''; + // Ref supplier invoice + print ''; + print $objp->ref_supplier; + print ''; + + // Supplier invoice label + print ''; print $objp->invoice_label; print ''; @@ -501,8 +520,8 @@ if ($result) { } print ''; - print ''; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description)); + print ''; + $text = dolGetFirstLineOfText(dol_string_nohtmltag($objp->description, 1)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; print $form->textwithtooltip(dol_trunc($text, $trunclength), $objp->description); print ''; diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index 24d0ed08a0a..32e939f7bee 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -1,10 +1,11 @@ - * Copyright (C) 2013-2021 Alexandre Spangaro + * Copyright (C) 2013-2022 Alexandre Spangaro * Copyright (C) 2014-2015 Ari Elbaz (elarifr) * Copyright (C) 2013-2021 Florian Henry - * Copyright (C) 2014 Juanjo Menent s - * Copyright (C) 2016 Laurent Destailleur + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2014 Juanjo Menent s + * Copyright (C) 2016 Laurent Destailleur * * 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 @@ -47,6 +48,7 @@ $show_files = GETPOST('show_files', 'int'); $confirm = GETPOST('confirm', 'alpha'); $toselect = GETPOST('toselect', 'array'); $optioncss = GETPOST('optioncss', 'alpha'); +$default_account = GETPOST('default_account', 'int'); // Select Box $mesCasesCochees = GETPOST('toselect', 'array'); @@ -55,6 +57,7 @@ $mesCasesCochees = GETPOST('toselect', 'array'); $search_societe = GETPOST('search_societe', 'alpha'); $search_lineid = GETPOST('search_lineid', 'int'); $search_ref = GETPOST('search_ref', 'alpha'); +$search_ref_supplier = GETPOST('search_ref_supplier', 'alpha'); $search_invoice = GETPOST('search_invoice', 'alpha'); $search_label = GETPOST('search_label', 'alpha'); $search_desc = GETPOST('search_desc', 'alpha'); @@ -137,6 +140,7 @@ if (empty($reshook)) { $search_societe = ''; $search_lineid = ''; $search_ref = ''; + $search_ref_supplier = ''; $search_invoice = ''; $search_label = ''; $search_desc = ''; @@ -290,6 +294,9 @@ if (strlen(trim($search_invoice))) { if (strlen(trim($search_ref))) { $sql .= natural_search("p.ref", $search_ref); } +if (strlen(trim($search_ref_supplier))) { + $sql .= natural_search("f.ref_supplier", $search_ref_supplier); +} if (strlen(trim($search_label))) { $sql .= natural_search(array("p.label", "f.libelle"), $search_label); } @@ -413,6 +420,9 @@ if ($result) { if ($search_ref) { $param .= '&search_ref='.urlencode($search_ref); } + if ($search_ref_supplier) { + $param .= '&search_ref_supplier='.urlencode($search_ref_supplier); + } if ($search_label) { $param .= '&search_label='.urlencode($search_label); } @@ -434,12 +444,15 @@ if ($result) { $arrayofmassactions = array( 'ventil'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Ventilate") + ,'set_default_account'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("ConfirmPreselectAccount") //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), ); //if ($user->rights->mymodule->supprimer) $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); //if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); - $massactionbutton = $form->selectMassAction('ventil', $arrayofmassactions, 1); + if ($massaction !== 'set_default_account') { + $massactionbutton = $form->selectMassAction('ventil', $arrayofmassactions, 1); + } print ''."\n"; print ''; @@ -454,6 +467,14 @@ if ($result) { print_barre_liste($langs->trans("InvoiceLines"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num_lines, $nbtotalofrecords, 'title_accountancy', 0, '', '', $limit); + if ($massaction == 'set_default_account') { + $formquestion[]=array('type' => 'other', + 'name' => 'set_default_account', + 'label' => $langs->trans("AccountancyCode"), + 'value' => $formaccounting->select_account('', 'default_account', 1, array(), 0, 0, 'maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone')); + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmPreselectAccount"), $langs->trans("ConfirmPreselectAccountQuestion", count($toselect)), "confirm_set_default_account", $formquestion, 1, 0, 200, 500, 1); + } + print ''.$langs->trans("DescVentilTodoCustomer").'

'; if ($msg) { @@ -469,7 +490,8 @@ if ($result) { print ''; print ''; print ''; - //print ''; + print ''; + print ''; print ''; print '
'; print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); @@ -499,7 +521,8 @@ if ($result) { print ''; print_liste_field_titre("LineId", $_SERVER["PHP_SELF"], "l.rowid", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Invoice", $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); - //print_liste_field_titre("InvoiceLabel", $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("RefSupplier", $_SERVER["PHP_SELF"], "f.ref_supplier", "", $param, '', $sortfield, $sortorder); + print_liste_field_titre("InvoiceLabel", $_SERVER["PHP_SELF"], "f.libelle", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "f.datef, f.ref, l.rowid", "", $param, '', $sortfield, $sortorder, 'center '); print_liste_field_titre("ProductRef", $_SERVER["PHP_SELF"], "p.ref", "", $param, '', $sortfield, $sortorder); //print_liste_field_titre("ProductLabel", $_SERVER["PHP_SELF"], "p.label", "", $param, '', $sortfield, $sortorder); @@ -566,6 +589,7 @@ if ($result) { $facturefourn_static->ref = $objp->ref; $facturefourn_static->id = $objp->facid; $facturefourn_static->type = $objp->ftype; + $facturefourn_static->ref_supplier = $objp->ref_supplier; $facturefourn_static->label = $objp->invoice_label; $facturefourn_static->date = $db->jdate($objp->datef); @@ -625,15 +649,21 @@ if ($result) { // Ref Invoice print ''.$facturefourn_static->getNomUrl(1).''; - /*print ''; + // Ref supplier invoice + print ''; + print $objp->ref_supplier; + print ''; + + // Supplier invoice label + print ''; print $objp->invoice_label; print ''; - */ + // Date print ''.dol_print_date($facturefourn_static->date, 'day').''; // Ref Product - print ''; + print ''; if ($product_static->id > 0) { print $product_static->getNomUrl(1); } @@ -644,7 +674,7 @@ if ($result) { // Description print ''; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($facturefourn_static_det->desc)); + $text = dolGetFirstLineOfText(dol_string_nohtmltag($facturefourn_static_det->desc, 1)); $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION) ? 32 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION; print $form->textwithtooltip(dol_trunc($text, $trunclength), $facturefourn_static_det->desc); print ''; @@ -719,7 +749,7 @@ if ($result) { // Suggested accounting account print ''; - print $formaccounting->select_account($suggestedid, 'codeventil'.$facturefourn_static_det->id, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone'); + print $formaccounting->select_account(($default_account > 0 && $confirm === 'yes' && in_array($objp->rowid."_".$i, $toselect)) ? $default_account : $suggestedid, 'codeventil'.$facturefourn_static_det->id, 1, array(), 0, 0, 'codeventil maxwidth200 maxwidthonsmartphone', 'cachewithshowemptyone'); print ''; // Column with checkbox @@ -728,6 +758,14 @@ if ($result) { if (!empty($suggestedid) && $suggestedaccountingaccountfor != '' && $suggestedaccountingaccountfor != 'eecwithoutvatnumber') { $ischecked = 1; } + + if (!empty($toselect)) { + $ischecked = 0; + if (in_array($objp->rowid."_".$i, $toselect)) { + $ischecked=1; + } + } + print ''; print ''; diff --git a/htdocs/adherents/admin/member.php b/htdocs/adherents/admin/member.php index d51dd8ef730..bae229bc77b 100644 --- a/htdocs/adherents/admin/member.php +++ b/htdocs/adherents/admin/member.php @@ -64,7 +64,7 @@ if ($action == 'set_default') { } elseif ($action == 'del_default') { $ret = delDocumentModel($value, $type); if ($ret > 0) { - if ($conf->global->MEMBER_ADDON_PDF_ODT == "$value") { + if (getDolGlobalString('MEMBER_ADDON_PDF_ODT') == "$value") { dolibarr_del_const($db, 'MEMBER_ADDON_PDF_ODT', $conf->entity); } } @@ -108,7 +108,7 @@ if ($action == 'set_default') { $res3 = dolibarr_set_const($db, 'ADHERENT_CREATE_EXTERNAL_USER_LOGIN', GETPOST('ADHERENT_CREATE_EXTERNAL_USER_LOGIN', 'alpha'), 'chaine', 0, '', $conf->entity); $res4 = dolibarr_set_const($db, 'ADHERENT_BANK_USE', GETPOST('ADHERENT_BANK_USE', 'alpha'), 'chaine', 0, '', $conf->entity); // Use vat for invoice creation - if ($conf->facture->enabled) { + if (!empty($conf->facture->enabled)) { $res4 = dolibarr_set_const($db, 'ADHERENT_VAT_FOR_SUBSCRIPTIONS', GETPOST('ADHERENT_VAT_FOR_SUBSCRIPTIONS', 'alpha'), 'chaine', 0, '', $conf->entity); $res5 = dolibarr_set_const($db, 'ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS', GETPOST('ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS', 'alpha'), 'chaine', 0, '', $conf->entity); if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { @@ -248,15 +248,15 @@ if (!empty($conf->banque->enabled) && !empty($conf->societe->enabled) && !empty( $arraychoices['bankviainvoice'] = $langs->trans("MoreActionBankViaInvoice"); } print ''; -print $form->selectarray('ADHERENT_BANK_USE', $arraychoices, $conf->global->ADHERENT_BANK_USE, 0); -if ($conf->global->ADHERENT_BANK_USE == 'bankdirect' || $conf->global->ADHERENT_BANK_USE == 'bankviainvoice') { +print $form->selectarray('ADHERENT_BANK_USE', $arraychoices, getDolGlobalString('ADHERENT_BANK_USE'), 0); +if (getDolGlobalString('ADHERENT_BANK_USE') == 'bankdirect' || getDolGlobalString('ADHERENT_BANK_USE') == 'bankviainvoice') { print '
'.$langs->trans("ABankAccountMustBeDefinedOnPaymentModeSetup").'
'; } print ''; print "\n"; // Use vat for invoice creation -if ($conf->facture->enabled) { +if (!empty($conf->facture->enabled)) { print ''.$langs->trans("VATToUseForSubscriptions").''; if (!empty($conf->banque->enabled)) { print ''; @@ -378,16 +378,16 @@ foreach ($dirmodels as $reldir) { print ''; } else { print ''."\n"; - print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; + print 'scandir) ? $module->scandir : '').'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; print ""; } // Defaut print ''; - if ($conf->global->MEMBER_ADDON_PDF == $name) { + if (getDolGlobalString('MEMBER_ADDON_PDF') == $name) { print img_picto($langs->trans("Default"), 'on'); } else { - print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; + print 'scandir) ? $module->scandir : '').'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; } print ''; @@ -398,8 +398,8 @@ foreach ($dirmodels as $reldir) { $htmltooltip .= '
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; } $htmltooltip .= '

'.$langs->trans("FeaturesSupported").':'; - $htmltooltip .= '
'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1); - $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); + $htmltooltip .= '
'.$langs->trans("Logo").': '.yn(!empty($module->option_logo) ? $module->option_logo : 0, 1, 1); + $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn(!empty($module->option_multilang) ? $module->option_multilang : 0, 1, 1); print ''; diff --git a/htdocs/adherents/admin/member_extrafields.php b/htdocs/adherents/admin/member_extrafields.php index 7f5262bc7c6..210e6213d6f 100644 --- a/htdocs/adherents/admin/member_extrafields.php +++ b/htdocs/adherents/admin/member_extrafields.php @@ -84,7 +84,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/adherents/admin/member_type_extrafields.php b/htdocs/adherents/admin/member_type_extrafields.php index 68916df624f..c643d6e15d4 100644 --- a/htdocs/adherents/admin/member_type_extrafields.php +++ b/htdocs/adherents/admin/member_type_extrafields.php @@ -87,7 +87,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/adherents/admin/website.php b/htdocs/adherents/admin/website.php index ed09c206abf..6199991f29c 100644 --- a/htdocs/adherents/admin/website.php +++ b/htdocs/adherents/admin/website.php @@ -95,12 +95,13 @@ if ($action == 'update') { $form = new Form($db); +$title = $langs->trans("MembersSetup"); $help_url = 'EN:Module_Foundations|FR:Module_Adhérents|ES:Módulo_Miembros'; -llxHeader('', $langs->trans("MembersSetup"), $help_url); +llxHeader('', $title, $help_url); $linkback = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("MembersSetup"), $linkback, 'title_setup'); +print load_fiche_titre($title, $linkback, 'title_setup'); $head = member_admin_prepare_head(); diff --git a/htdocs/adherents/agenda.php b/htdocs/adherents/agenda.php index cb942ba3176..0a6abcd4955 100644 --- a/htdocs/adherents/agenda.php +++ b/htdocs/adherents/agenda.php @@ -65,6 +65,9 @@ if (GETPOST('actioncode', 'array')) { } $search_agenda_label = GETPOST('search_agenda_label'); +// Get object canvas (By default, this is not defined, so standard usage of dolibarr) +$objcanvas = null; + // Security check $result = restrictedArea($user, 'adherent', $id); @@ -160,7 +163,7 @@ if ($object->id > 0) { $newcardbutton = ''; if (!empty($conf->agenda->enabled)) { - $newcardbutton .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create&backtopage=1&origin=member&originid='.$id); + $newcardbutton .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']).($object->id > 0 ? '?id='.$object->id : '').'&origin=member&originid='.$id); } if (!empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) { diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 99ebda6fcd7..88a63af0ae1 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -55,6 +55,7 @@ $id = GETPOST('id') ?GETPOST('id', 'int') : $rowid; $typeid = GETPOST('typeid', 'int'); $userid = GETPOST('userid', 'int'); $socid = GETPOST('socid', 'int'); +$ref = GETPOST('ref', 'alpha'); if (!empty($conf->mailmanspip->enabled)) { include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php'; @@ -1285,7 +1286,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''; // EMail - print ''.($conf->global->ADHERENT_MAIL_REQUIRED ? '' : '').$langs->trans("EMail").($conf->global->ADHERENT_MAIL_REQUIRED ? '' : '').''; + print ''.(getDolGlobalString("ADHERENT_MAIL_REQUIRED") ? '' : '').$langs->trans("EMail").(getDolGlobalString("ADHERENT_MAIL_REQUIRED") ? '' : '').''; print ''.img_picto('', 'object_email', 'class="pictofixedwidth"').'email).'">'; // Website @@ -2029,7 +2030,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { $MAX = 10; - $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-list-alt imgforviewmode', DOL_URL_ROOT.'/adherents/agenda.php?id='.$object->id); + $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/adherents/agenda.php?id='.$object->id); // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; diff --git a/htdocs/adherents/cartes/carte.php b/htdocs/adherents/cartes/carte.php index 94621195ac9..e9eb00d23f7 100644 --- a/htdocs/adherents/cartes/carte.php +++ b/htdocs/adherents/cartes/carte.php @@ -79,7 +79,7 @@ if ((!empty($foruserid) || !empty($foruserlogin) || !empty($mode)) && !$mesg) { } $sql .= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.country = c.rowid"; - if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { + if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."adherent_extrafields as ef on (d.rowid = ef.fk_object)"; } $sql .= " WHERE d.fk_adherent_type = t.rowid AND d.statut = 1"; @@ -110,7 +110,7 @@ if ((!empty($foruserid) || !empty($foruserlogin) || !empty($mode)) && !$mesg) { $adherentstatic->firstname = $objp->firstname; // Format extrafield so they can be parsed in function complete_substitutions_array - if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { + if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $adherentstatic->array_options = array(); foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { $tmpkey = 'options_'.$key; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 6a2c69e32fe..39b6eaa97d0 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -7,7 +7,7 @@ * Copyright (C) 2009-2017 Regis Houssin * Copyright (C) 2014-2018 Alexandre Spangaro * Copyright (C) 2015 Marcos García - * Copyright (C) 2015-2020 Frédéric France + * Copyright (C) 2015-2022 Frédéric France * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2016 Juanjo Menent * Copyright (C) 2018-2019 Thibault FOUCART @@ -1534,9 +1534,9 @@ class Adherent extends CommonObject * * @param int $date Date of effect of subscription * @param double $amount Amount of subscription (0 accepted for some members) - * @param int $accountid Id bank account - * @param string $operation Type of payment (if Id bank account provided). Example: 'CB', ... - * @param string $label Label operation (if Id bank account provided) + * @param int $accountid Id bank account. NOT USED. + * @param string $operation Code of payment mode (if Id bank account provided). Example: 'CB', ... NOT USED. + * @param string $label Label operation (if Id bank account provided). * @param string $num_chq Numero cheque (if Id bank account provided) * @param string $emetteur_nom Name of cheque writer * @param string $emetteur_banque Name of bank of cheque @@ -2163,7 +2163,7 @@ class Adherent extends CommonObject */ public function getNomUrl($withpictoimg = 0, $maxlen = 0, $option = 'card', $mode = '', $morecss = '', $save_lastsearch_value = -1, $notooltip = 0, $addlinktonotes = 0) { - global $conf, $langs; + global $conf, $langs, $hookmanager; if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) { $withpictoimg = 0; @@ -2281,7 +2281,15 @@ class Adherent extends CommonObject $result .= ''; } } - + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index 18a91efaacd..3f857ce827b 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -121,6 +121,9 @@ class AdherentType extends CommonObject /** @var array Array of members */ public $members = array(); + /** @var string string other */ + public $other = array(); + public $multilangs = array(); @@ -271,7 +274,7 @@ class AdherentType extends CommonObject $result = $this->db->query($sql); if ($result) { // Call trigger - $result = $this->call_trigger('ADHERENT_TYPE_DEL_MULTILANGS', $user); + $result = $this->call_trigger('MEMBER_TYPE_DEL_MULTILANGS', $user); if ($result < 0) { $this->error = $this->db->lasterror(); dol_syslog(get_class($this).'::delMultiLangs error='.$this->error, LOG_ERR); diff --git a/htdocs/adherents/class/subscription.class.php b/htdocs/adherents/class/subscription.class.php index 885c8981d93..b3cfe027197 100644 --- a/htdocs/adherents/class/subscription.class.php +++ b/htdocs/adherents/class/subscription.class.php @@ -358,7 +358,7 @@ class Subscription extends CommonObject $result = $member->update_end_date($user); if ($this->fk_bank > 0 && is_object($accountline) && $accountline->id > 0) { // If we found bank account line (this means this->fk_bank defined) - $result = $accountline->delete($user); // Return false if refused because line is conciliated + $result = $accountline->delete($user); // Return false if refused because line is reconciled if ($result > 0) { $this->db->commit(); return 1; @@ -490,17 +490,17 @@ class Subscription extends CommonObject $sql .= ' FROM '.MAIN_DB_PREFIX.'subscription as c'; $sql .= ' WHERE c.rowid = '.((int) $id); - $result = $this->db->query($sql); - if ($result) { - if ($this->db->num_rows($result)) { - $obj = $this->db->fetch_object($result); + $resql = $this->db->query($sql); + if ($resql) { + if ($this->db->num_rows($resql)) { + $obj = $this->db->fetch_object($resql); $this->id = $obj->rowid; $this->date_creation = $this->db->jdate($obj->datec); $this->date_modification = $this->db->jdate($obj->datem); } - $this->db->free($result); + $this->db->free($resql); } else { dol_print_error($this->db); } diff --git a/htdocs/adherents/index.php b/htdocs/adherents/index.php index 2b0c295afbd..1ef98dddb6d 100644 --- a/htdocs/adherents/index.php +++ b/htdocs/adherents/index.php @@ -99,12 +99,12 @@ $sql .= " WHERE t.entity IN (".getEntity('member_type').")"; $sql .= " GROUP BY t.rowid, t.libelle, t.subscription, d.statut"; dol_syslog("index.php::select nb of members per type", LOG_DEBUG); -$result = $db->query($sql); -if ($result) { - $num = $db->num_rows($result); +$resql = $db->query($sql); +if ($resql) { + $num = $db->num_rows($resql); $i = 0; while ($i < $num) { - $objp = $db->fetch_object($result); + $objp = $db->fetch_object($resql); $adhtype = new AdherentType($db); $adhtype->id = $objp->rowid; @@ -127,7 +127,7 @@ if ($result) { $i++; } - $db->free($result); + $db->free($resql); } $now = dol_now(); @@ -143,16 +143,16 @@ $sql .= " AND t.rowid = d.fk_adherent_type"; $sql .= " GROUP BY d.fk_adherent_type"; dol_syslog("index.php::select nb of uptodate members by type", LOG_DEBUG); -$result = $db->query($sql); -if ($result) { - $num = $db->num_rows($result); +$resql = $db->query($sql); +if ($resql) { + $num = $db->num_rows($resql); $i = 0; while ($i < $num) { - $objp = $db->fetch_object($result); + $objp = $db->fetch_object($resql); $MembersUpToDate[$objp->fk_adherent_type] = $objp->somme; $i++; } - $db->free(); + $db->free($resql); } /* diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 441ce85ec86..8bf7f7af6a6 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -1,7 +1,7 @@ * Copyright (C) 2002-2003 Jean-Louis Bergamo - * Copyright (C) 2004-2016 Laurent Destailleur + * Copyright (C) 2004-2022 Laurent Destailleur * Copyright (C) 2013-2015 Raphaël Doursenaud * Copyright (C) 2014-2016 Juanjo Menent * Copyright (C) 2018 Alexandre Spangaro @@ -63,6 +63,7 @@ $search_email = GETPOST("search_email", 'alpha'); $search_categ = GETPOST("search_categ", 'int'); $search_filter = GETPOST("search_filter", 'alpha'); $search_status = GETPOST("search_status", 'intcomma'); +$search_import_key = trim(GETPOST("search_import_key", "alpha")); $catid = GETPOST("catid", 'int'); $optioncss = GETPOST('optioncss', 'alpha'); $socid = GETPOST('socid', 'int'); @@ -156,7 +157,8 @@ $arrayfields = array( 'd.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), 'd.birth'=>array('label'=>$langs->trans("Birthday"), 'checked'=>0, 'position'=>500), 'd.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), - 'd.statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000) + 'd.statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), + 'd.import_key'=>array('label'=>"ImportId", 'checked'=>0, 'position'=>1100), ); // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; @@ -172,7 +174,7 @@ $result = restrictedArea($user, 'adherent'); if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; } -if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend' && $massaction != 'confirm_createbills') { +if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; } @@ -213,9 +215,10 @@ if (empty($reshook)) { $search_categ = ""; $search_filter = ""; $search_status = ""; + $search_import_key = ''; $catid = ""; $sall = ""; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } @@ -305,6 +308,8 @@ $formother = new FormOther($db); $membertypestatic = new AdherentType($db); $memberstatic = new Adherent($db); +$title = $langs->trans("Members"); + $now = dol_now(); if ((!empty($search_categ) && $search_categ > 0) || !empty($catid)) { @@ -316,7 +321,7 @@ $sql .= " d.rowid, d.ref, d.login, d.lastname, d.firstname, d.gender, d.societe $sql .= " d.civility, d.datefin, d.address, d.zip, d.town, d.state_id, d.country,"; $sql .= " d.email, d.phone, d.phone_perso, d.phone_mobile, d.birth, d.public, d.photo,"; $sql .= " d.fk_adherent_type as type_id, d.morphy, d.statut, d.datec as date_creation, d.tms as date_update,"; -$sql .= " d.note_private, d.note_public,"; +$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,"; @@ -425,6 +430,9 @@ if ($search_phone_mobile) { if ($search_country) { $sql .= " AND d.country IN (".$db->sanitize($search_country).')'; } +if ($search_import_key) { + $sql .= natural_search("d.import_key", $search_import_key); +} // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; @@ -434,8 +442,6 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; -$sql .= $db->order($sortfield, $sortorder); - // Count total nb of records with no order and no limits $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { @@ -445,15 +451,20 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { } else { dol_print_error($db); } + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); +} + +// Complete request and execute it with limit +$sql .= $db->order($sortfield, $sortorder); +if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); } -// Add limit -$sql .= $db->plimit($limit + 1, $offset); -dol_syslog("get list", LOG_DEBUG); $resql = $db->query($sql); if (!$resql) { dol_print_error($db); @@ -462,6 +473,7 @@ if (!$resql) { $num = $db->num_rows($resql); + $arrayofselected = is_array($toselect) ? $toselect : array(); if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $sall) { @@ -471,42 +483,42 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $ exit; } -llxHeader('', $langs->trans("Member"), 'EN:Module_Foundations|FR:Module_Adhérents|ES:Módulo_Miembros'); +$help_url = 'EN:Module_Foundations|FR:Module_Adhérents|ES:Módulo_Miembros'; +llxHeader('', $title, $help_url); -$titre = $langs->trans("MembersList"); if (GETPOSTISSET("search_status")) { if ($search_status == '-1,1') { // TODO : check this test as -1 == Adherent::STATUS_DRAFT and -2 == Adherent::STATUS_EXLCUDED - $titre = $langs->trans("MembersListQualified"); + $title = $langs->trans("MembersListQualified"); } if ($search_status == Adherent::STATUS_DRAFT) { - $titre = $langs->trans("MembersListToValid"); + $title = $langs->trans("MembersListToValid"); } if ($search_status == Adherent::STATUS_VALIDATED && $filter == '') { - $titre = $langs->trans("MenuMembersValidated"); + $title = $langs->trans("MenuMembersValidated"); } if ($search_status == Adherent::STATUS_VALIDATED && $filter == 'withoutsubscription') { - $titre = $langs->trans("MembersWithSubscriptionToReceive"); + $title = $langs->trans("MembersWithSubscriptionToReceive"); } if ($search_status == Adherent::STATUS_VALIDATED && $filter == 'uptodate') { - $titre = $langs->trans("MembersListUpToDate"); + $title = $langs->trans("MembersListUpToDate"); } if ($search_status == Adherent::STATUS_VALIDATED && $filter == 'outofdate') { - $titre = $langs->trans("MembersListNotUpToDate"); + $title = $langs->trans("MembersListNotUpToDate"); } if ((string) $search_status == (string) Adherent::STATUS_RESILIATED) { // The cast to string is required to have test false when search_status is '' - $titre = $langs->trans("MembersListResiliated"); + $title = $langs->trans("MembersListResiliated"); } if ($search_status == Adherent::STATUS_EXCLUDED) { - $titre = $langs->trans("MembersListExcluded"); + $title = $langs->trans("MembersListExcluded"); } } elseif ($action == 'search') { - $titre = $langs->trans("MembersListQualified"); + $title = $langs->trans("MembersListQualified"); } if ($search_type > 0) { $membertype = new AdherentType($db); - $result = $membertype->fetch(GETPOST("type", 'int')); - $titre .= " (".$membertype->label.")"; + $result = $membertype->fetch($search_type); + $title .= " (".$membertype->label.")"; } $param = ''; @@ -576,6 +588,9 @@ if ($search_filter && $search_filter != '-1') { if ($search_status != "" && $search_status != -3) { $param .= "&search_status=".urlencode($search_status); } +if ($search_import_key != '') { + $param .= '&search_import_key='.urlencode($search_import_key); +} if ($search_type > 0) { $param .= "&search_type=".urlencode($search_type); } @@ -587,7 +602,7 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; // List of mass actions available $arrayofmassactions = array( - //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').' '.$langs->trans("SendByMail"), + //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), ); if ($user->rights->adherent->creer) { @@ -602,7 +617,7 @@ if ($user->rights->societe->creer) { if ($user->rights->adherent->creer && $user->rights->user->user->creer) { $arrayofmassactions['createexternaluser'] = img_picto('', 'user', 'class="pictofixedwidth"').$langs->trans("CreateExternalUser"); } -if (in_array($massaction, array('presend', 'predelete', 'preaffecttag'))) { +if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete', 'preaffecttag'))) { $arrayofmassactions = array(); } $massactionbutton = $form->selectMassAction('', $arrayofmassactions); @@ -623,7 +638,7 @@ print ''; print ''; print ''; -print_barre_liste($titre, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); $topicmail = "Information"; $modelmail = "member"; @@ -668,7 +683,6 @@ if ($massactionbutton) { print '
'; print ''."\n"; - // Line for filters fields print ''; @@ -767,7 +781,7 @@ if (!empty($arrayfields['d.email']['checked'])) { } // End of subscription date if (!empty($arrayfields['d.datefin']['checked'])) { - print ''; @@ -806,15 +820,24 @@ if (!empty($arrayfields['d.statut']['checked'])) { print $form->selectarray('search_status', $liststatus, $search_status, -3); print ''; } -// Action column -print ''; - +if (!empty($arrayfields['d.import_key']['checked'])) { + print ''; +} +if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + // Action column + print ''; +} print "\n"; print ''; +if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch actioncolumn '); +} if (!empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) { print_liste_field_titre("ID", $_SERVER["PHP_SELF"], '', '', $param, 'align="center"', $sortfield, $sortorder); } @@ -858,7 +881,7 @@ if (!empty($arrayfields['state.nom']['checked'])) { print_liste_field_titre($arrayfields['state.nom']['label'], $_SERVER["PHP_SELF"], "state.nom", "", $param, '', $sortfield, $sortorder); } if (!empty($arrayfields['country.code_iso']['checked'])) { - print_liste_field_titre($arrayfields['country.code_iso']['label'], $_SERVER["PHP_SELF"], "country.code_iso", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($arrayfields['country.code_iso']['label'], $_SERVER["PHP_SELF"], "country.code_iso", "", $param, '', $sortfield, $sortorder, 'center '); } if (!empty($arrayfields['d.phone']['checked'])) { print_liste_field_titre($arrayfields['d.phone']['label'], $_SERVER["PHP_SELF"], 'd.phone', '', $param, '', $sortfield, $sortorder); @@ -873,7 +896,7 @@ if (!empty($arrayfields['d.email']['checked'])) { print_liste_field_titre($arrayfields['d.email']['label'], $_SERVER["PHP_SELF"], 'd.email', '', $param, '', $sortfield, $sortorder); } if (!empty($arrayfields['d.datefin']['checked'])) { - print_liste_field_titre($arrayfields['d.datefin']['label'], $_SERVER["PHP_SELF"], 'd.datefin', '', $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($arrayfields['d.datefin']['label'], $_SERVER["PHP_SELF"], 'd.datefin', '', $param, '', $sortfield, $sortorder, 'center '); } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; @@ -894,7 +917,12 @@ if (!empty($arrayfields['d.tms']['checked'])) { if (!empty($arrayfields['d.statut']['checked'])) { print_liste_field_titre($arrayfields['d.statut']['label'], $_SERVER["PHP_SELF"], "d.statut", "", $param, 'class="right"', $sortfield, $sortorder); } -print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', 'align="center"', $sortfield, $sortorder, 'maxwidthsearch '); +if (!empty($arrayfields['d.import_key']['checked'])) { + print_liste_field_titre($arrayfields['d.import_key']['label'], $_SERVER["PHP_SELF"], "d.import_key", "", $param, '', $sortfield, $sortorder, 'center '); +} +if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', 'align="center"', $sortfield, $sortorder, 'maxwidthsearch '); +} print "\n"; $i = 0; @@ -935,7 +963,7 @@ while ($i < min($num, $limit)) { print ''; if (!empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) { - print ''; + print ''; if (!$i) { $totalarray['nbfield']++; } @@ -1110,16 +1138,14 @@ while ($i < min($num, $limit)) { // End of subscription date $datefin = $db->jdate($obj->datefin); if (!empty($arrayfields['d.datefin']['checked'])) { + print ''; } else { - print ''; } + print ''; } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; @@ -1173,21 +1199,31 @@ while ($i < min($num, $limit)) { $totalarray['nbfield']++; } } - // Action column - print '\n"; + if (!$i) { + $totalarray['nbfield']++; } - print ''; } - print ''; + // Action column + if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; + } if (!$i) { $totalarray['nbfield']++; } - print "\n"; + print ''."\n"; $i++; } diff --git a/htdocs/adherents/partnership.php b/htdocs/adherents/partnership.php index 160a037c187..a01e7d28ed2 100644 --- a/htdocs/adherents/partnership.php +++ b/htdocs/adherents/partnership.php @@ -85,11 +85,18 @@ $usercanclose = $user->rights->partnership->write; // Used by the include of $upload_dir = $conf->partnership->multidir_output[isset($object->entity) ? $object->entity : 1]; -if ($conf->global->PARTNERSHIP_IS_MANAGED_FOR != 'member') accessforbidden(); -if (empty($conf->partnership->enabled)) accessforbidden(); -if (empty($permissiontoread)) accessforbidden(); -if ($action == 'edit' && empty($permissiontoadd)) accessforbidden(); - +if (getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR') != 'member') { + accessforbidden('Partnership module is not activated for members'); +} +if (empty($conf->partnership->enabled)) { + accessforbidden(); +} +if (empty($permissiontoread)) { + accessforbidden(); +} +if ($action == 'edit' && empty($permissiontoadd)) { + accessforbidden(); +} if (($action == 'update' || $action == 'edit') && $object->status != $object::STATUS_DRAFT) { accessforbidden(); } diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 9cad28be5d5..1cfbb80f65b 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -40,6 +40,8 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; $langs->loadLangs(array("companies", "bills", "members", "users", "mails", 'other')); +$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') + $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); $id = GETPOST('rowid', 'int') ?GETPOST('rowid', 'int') : GETPOST('id', 'int'); @@ -1163,9 +1165,13 @@ if ($rowid > 0) { print dol_get_fiche_end(); print '
'; - print ''; - print '     '; - print ''; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); + if (empty($reshook)) { + print ''; + print '     '; + print ''; + } print '
'; print ''; diff --git a/htdocs/adherents/subscription/card.php b/htdocs/adherents/subscription/card.php index 5967d670856..a18259fefe4 100644 --- a/htdocs/adherents/subscription/card.php +++ b/htdocs/adherents/subscription/card.php @@ -93,8 +93,8 @@ if ($user->rights->adherent->cotisation->creer && $action == 'update' && !$cance if ($accountline->rappro) { $errmsg = $langs->trans("SubscriptionLinkedToConciliatedTransaction"); } else { - $accountline->datev = dol_mktime($_POST['datesubhour'], $_POST['datesubmin'], 0, $_POST['datesubmonth'], $_POST['datesubday'], $_POST['datesubyear']); - $accountline->dateo = dol_mktime($_POST['datesubhour'], $_POST['datesubmin'], 0, $_POST['datesubmonth'], $_POST['datesubday'], $_POST['datesubyear']); + $accountline->datev = dol_mktime(GETPOST('datesubhour', 'int'), GETPOST('datesubmin', 'int'), 0, GETPOST('datesubmonth', 'int'), GETPOST('datesubday', 'int'), GETPOST('datesubyear', 'int')); + $accountline->dateo = dol_mktime(GETPOST('datesubhour', 'int'), GETPOST('datesubmin', 'int'), 0, GETPOST('datesubmonth', 'int'), GETPOST('datesubday', 'int'), GETPOST('datesubyear', 'int')); $accountline->amount = $amount; $result = $accountline->update($user); if ($result < 0) { @@ -105,12 +105,12 @@ if ($user->rights->adherent->cotisation->creer && $action == 'update' && !$cance if (!$errmsg) { // Modify values - $object->dateh = dol_mktime($_POST['datesubhour'], $_POST['datesubmin'], 0, $_POST['datesubmonth'], $_POST['datesubday'], $_POST['datesubyear']); - $object->datef = dol_mktime($_POST['datesubendhour'], $_POST['datesubendmin'], 0, $_POST['datesubendmonth'], $_POST['datesubendday'], $_POST['datesubendyear']); + $object->dateh = dol_mktime(GETPOST('datesubhour', 'int'), GETPOST('datesubmin', 'int'), 0, GETPOST('datesubmonth', 'int'), GETPOST('datesubday', 'int'), GETPOST('datesubyear', 'int')); + $object->datef = dol_mktime(GETPOST('datesubendhour', 'int'), GETPOST('datesubendmin', 'int'), 0, GETPOST('datesubendmonth', 'int'), GETPOST('datesubendday', 'int'), GETPOST('datesubendyear', 'int')); $object->fk_type = $typeid; $object->note = $note; + $object->note_private = $note; $object->amount = $amount; - //print 'datef='.$object->datef.' '.$_POST['datesubendday']; $result = $object->update($user); if ($result >= 0 && !count($object->errors)) { diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index 0b83881e502..6056e1320f0 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -111,7 +111,7 @@ $result = restrictedArea($user, 'adherent', '', '', 'cotisation'); if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; } -if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend' && $massaction != 'confirm_createbills') { +if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; } @@ -135,7 +135,7 @@ if (empty($reshook)) { $search_note = ""; $search_amount = ""; $search_account = ""; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } } @@ -628,10 +628,10 @@ while ($i < min($num, $limit)) { print ''; if (!$i) { diff --git a/htdocs/adherents/tpl/linkedobjectblock.tpl.php b/htdocs/adherents/tpl/linkedobjectblock.tpl.php index 3acb14a4cdb..5928b706a8e 100644 --- a/htdocs/adherents/tpl/linkedobjectblock.tpl.php +++ b/htdocs/adherents/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -echo "\n"; +echo "\n"; global $user; diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index 76dd0617cee..bcd6c99afbf 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -125,6 +125,7 @@ if ($action == 'add' && $user->rights->adherent->configurer) { $object->duration_value = $duration_value; $object->duration_unit = $duration_unit; $object->note = trim($comment); + $object->note_public = trim($comment); $object->mail_valid = trim($mail_valid); $object->vote = (int) $vote; @@ -176,6 +177,7 @@ if ($action == 'update' && $user->rights->adherent->configurer) { $object->duration_value = $duration_value; $object->duration_unit = $duration_unit; $object->note = trim($comment); + $object->note_public = trim($comment); $object->mail_valid = trim($mail_valid); $object->vote = (boolean) trim($vote); @@ -358,7 +360,7 @@ if ($action == 'create') { print ''; print ''; // Morphy @@ -375,7 +377,7 @@ if ($action == 'create') { print ''; print ''; print ''; @@ -783,7 +785,7 @@ if ($rowid > 0) { print ''; print ''; // Morphy diff --git a/htdocs/admin/agenda.php b/htdocs/admin/agenda.php index 730983ad090..52926cf1b19 100644 --- a/htdocs/admin/agenda.php +++ b/htdocs/admin/agenda.php @@ -88,7 +88,6 @@ if ($action == "save" && empty($cancel)) { foreach ($triggers as $trigger) { $keyparam = 'MAIN_AGENDA_ACTIONAUTO_'.$trigger['code']; - //print "param=".$param." - ".$_POST[$param]; if ($search_event === '' || preg_match('/'.preg_quote($search_event, '/').'/i', $keyparam)) { $res = dolibarr_set_const($db, $keyparam, (GETPOST($keyparam, 'alpha') ?GETPOST($keyparam, 'alpha') : ''), 'chaine', 0, '', $conf->entity); if (!($res > 0)) { @@ -174,6 +173,9 @@ if (!empty($triggers)) { if ($module == 'contact') { $module = 'societe'; } + if ($module == 'facturerec') { + $module = 'facture'; + } // If 'element' value is myobject@mymodule instead of mymodule $tmparray = explode('@', $module); @@ -192,6 +194,7 @@ if (!empty($triggers)) { } if ($search_event === '' || preg_match('/'.preg_quote($search_event, '/').'/i', $trigger['code'])) { + print ''; print ''; print ''; print ''; diff --git a/htdocs/admin/agenda_extrafields.php b/htdocs/admin/agenda_extrafields.php index 50e4a3e92c7..13f8ad246a0 100644 --- a/htdocs/admin/agenda_extrafields.php +++ b/htdocs/admin/agenda_extrafields.php @@ -89,7 +89,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/agenda_other.php b/htdocs/admin/agenda_other.php index 8e50380e2ae..1014d40de50 100644 --- a/htdocs/admin/agenda_other.php +++ b/htdocs/admin/agenda_other.php @@ -41,6 +41,8 @@ $langs->loadLangs(array('admin', 'other', 'agenda', 'users')); $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $param = GETPOST('param', 'alpha'); $cancel = GETPOST('cancel', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); diff --git a/htdocs/admin/agenda_reminder.php b/htdocs/admin/agenda_reminder.php index 1d8cd8f723c..79aa081ddef 100644 --- a/htdocs/admin/agenda_reminder.php +++ b/htdocs/admin/agenda_reminder.php @@ -36,6 +36,8 @@ $langs->loadLangs(array("admin", "other", "agenda")); $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $param = GETPOST('param', 'alpha'); $cancel = GETPOST('cancel', 'alpha'); $scandir = GETPOST('scandir', 'alpha'); diff --git a/htdocs/admin/bank.php b/htdocs/admin/bank.php index e1e468b0cec..ef365881feb 100644 --- a/htdocs/admin/bank.php +++ b/htdocs/admin/bank.php @@ -53,8 +53,6 @@ $type = 'bankaccount'; // Order display of bank account if ($action == 'setbankorder') { if (dolibarr_set_const($db, "BANK_SHOW_ORDER_OPTION", GETPOST('value', 'alpha'), 'chaine', 0, '', $conf->entity) > 0) { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; } else { dol_print_error($db); } @@ -63,15 +61,11 @@ if ($action == 'setbankorder') { // Auto report last num releve on conciliate if ($action == 'setreportlastnumreleve') { if (dolibarr_set_const($db, "BANK_REPORT_LAST_NUM_RELEVE", 1, 'chaine', 0, '', $conf->entity) > 0) { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; } else { dol_print_error($db); } } elseif ($action == 'unsetreportlastnumreleve') { if (dolibarr_set_const($db, "BANK_REPORT_LAST_NUM_RELEVE", 0, 'chaine', 0, '', $conf->entity) > 0) { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; } else { dol_print_error($db); } @@ -80,15 +74,11 @@ if ($action == 'setreportlastnumreleve') { // Colorize movements if ($action == 'setbankcolorizemovement') { if (dolibarr_set_const($db, "BANK_COLORIZE_MOVEMENT", 1, 'chaine', 0, '', $conf->entity) > 0) { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; } else { dol_print_error($db); } } elseif ($action == 'unsetbankcolorizemovement') { if (dolibarr_set_const($db, "BANK_COLORIZE_MOVEMENT", 0, 'chaine', 0, '', $conf->entity) > 0) { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; } else { dol_print_error($db); } @@ -427,13 +417,13 @@ print ""; // Active if ($conf->global->BANK_COLORIZE_MOVEMENT) { print ''; } else { print '"; } @@ -483,13 +473,13 @@ print ''; // Active if ($conf->global->BANK_REPORT_LAST_NUM_RELEVE) { print ''; } else { print '"; } diff --git a/htdocs/admin/bank_extrafields.php b/htdocs/admin/bank_extrafields.php index 35fd9f5271f..1382ef49983 100644 --- a/htdocs/admin/bank_extrafields.php +++ b/htdocs/admin/bank_extrafields.php @@ -85,7 +85,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/barcode.php b/htdocs/admin/barcode.php index 2fbfed35536..ee0fcd5d130 100644 --- a/htdocs/admin/barcode.php +++ b/htdocs/admin/barcode.php @@ -36,6 +36,7 @@ if (!$user->admin) { } $action = GETPOST('action', 'aZ09'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php /* diff --git a/htdocs/admin/bom.php b/htdocs/admin/bom.php index f8c2cf0bc06..dc56d3ae79f 100644 --- a/htdocs/admin/bom.php +++ b/htdocs/admin/bom.php @@ -36,6 +36,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'bom'; diff --git a/htdocs/admin/bom_extrafields.php b/htdocs/admin/bom_extrafields.php index 74d6ca931ec..c8ebafd4be8 100644 --- a/htdocs/admin/bom_extrafields.php +++ b/htdocs/admin/bom_extrafields.php @@ -84,7 +84,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/boxes.php b/htdocs/admin/boxes.php index 6c3a6f30646..1bc5f67239e 100644 --- a/htdocs/admin/boxes.php +++ b/htdocs/admin/boxes.php @@ -229,6 +229,7 @@ $sql .= " WHERE b.box_id = bd.rowid"; $sql .= " AND b.entity IN (0,".$conf->entity.")"; $sql .= " AND b.fk_user=0"; $sql .= " ORDER by b.position, b.box_order"; +//print $sql; dol_syslog("Search available boxes", LOG_DEBUG); $resql = $db->query($sql); diff --git a/htdocs/admin/commande.php b/htdocs/admin/commande.php index 24a45bb413a..f4afd27d46b 100644 --- a/htdocs/admin/commande.php +++ b/htdocs/admin/commande.php @@ -46,6 +46,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'order'; @@ -300,6 +302,7 @@ foreach ($dirmodels as $reldir) { $htmltooltip = ''; $htmltooltip .= ''.$langs->trans("Version").': '.$module->getVersion().'
'; $commande->type = 0; + $nextval = $module->getNextValue($mysoc, $commande); if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval $htmltooltip .= ''.$langs->trans("NextValue").': '; @@ -612,7 +615,7 @@ if (empty($conf->global->PDF_ALLOW_HTML_FOR_FREE_TEXT)) { print ''; } else { include_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor($variablename, $conf->global->$variablename, '', 80, 'dolibarr_notes'); + $doleditor = new DolEditor($variablename, getDolGlobalString($variablename), '', 80, 'dolibarr_notes'); print $doleditor->Create(); } print '\n"; diff --git a/htdocs/admin/commande_fournisseur_dispatch_extrafields.php b/htdocs/admin/commande_fournisseur_dispatch_extrafields.php index ac8f4fced4d..cf887b6b454 100644 --- a/htdocs/admin/commande_fournisseur_dispatch_extrafields.php +++ b/htdocs/admin/commande_fournisseur_dispatch_extrafields.php @@ -94,7 +94,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 25495e2de43..c3cb92dba8d 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -369,7 +369,7 @@ $form = new Form($db); $formother = new FormOther($db); $formcompany = new FormCompany($db); -$countrynotdefined = ''.$langs->trans("ErrorSetACountryFirst").' ('.$langs->trans("SeeAbove").')'; +$countrynotdefined = ''.$langs->trans("ErrorSetACountryFirst").' ('.$langs->trans("SeeAbove").')'; print load_fiche_titre($langs->trans("CompanyFoundation"), '', 'title_setup'); @@ -410,10 +410,10 @@ print ''."\n"; // Zip -print ''."\n"; -print ''."\n"; // Country diff --git a/htdocs/admin/contract.php b/htdocs/admin/contract.php index 1c6a0ec0458..0c8aba5ae2d 100644 --- a/htdocs/admin/contract.php +++ b/htdocs/admin/contract.php @@ -37,6 +37,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'contract'; diff --git a/htdocs/admin/defaultvalues.php b/htdocs/admin/defaultvalues.php index 58a72250d64..088c84de3f0 100644 --- a/htdocs/admin/defaultvalues.php +++ b/htdocs/admin/defaultvalues.php @@ -101,7 +101,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $defaulturl = ''; $defaultkey = ''; $defaultvalue = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } diff --git a/htdocs/admin/delivery.php b/htdocs/admin/delivery.php index 8e60b02a5bf..6f0f4c1b415 100644 --- a/htdocs/admin/delivery.php +++ b/htdocs/admin/delivery.php @@ -43,6 +43,8 @@ if (!$user->admin) { $action = GETPOST('action', 'alpha'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'delivery'; diff --git a/htdocs/admin/delivery_extrafields.php b/htdocs/admin/delivery_extrafields.php index cf712bc6ecf..fa1aa809944 100644 --- a/htdocs/admin/delivery_extrafields.php +++ b/htdocs/admin/delivery_extrafields.php @@ -91,7 +91,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/deliverydet_extrafields.php b/htdocs/admin/deliverydet_extrafields.php index c74f5235d42..6fbfbb58884 100644 --- a/htdocs/admin/deliverydet_extrafields.php +++ b/htdocs/admin/deliverydet_extrafields.php @@ -92,7 +92,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 621b2b783a7..8fd4feffcf4 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -3,16 +3,16 @@ * Copyright (C) 2004-2018 Laurent Destailleur * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2017 Regis Houssin - * Copyright (C) 2010-2016 Juanjo Menent + * Copyright (C) 2010-2022 Juanjo Menent * Copyright (C) 2011-2021 Philippe Grand * Copyright (C) 2011 Remy Younes * Copyright (C) 2012-2015 Marcos García * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2011-2021 Alexandre Spangaro + * Copyright (C) 2011-2022 Alexandre Spangaro * Copyright (C) 2015 Ferran Marcet * Copyright (C) 2016 Raphaël Doursenaud * Copyright (C) 2019-2020 Frédéric France - * Copyright (C) 2020 Open-Dsi + * Copyright (C) 2020-2022 Open-Dsi * * 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 @@ -94,59 +94,60 @@ if (!GETPOSTISSET('search_country_id') && $search_country_id == '' && ($id == 2 $search_code = GETPOST('search_code', 'alpha'); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$hookmanager->initHooks(array('admin')); +$hookmanager->initHooks(array('admin', 'dictionaryadmin')); // This page is a generic page to edit dictionaries // Put here declaration of dictionaries properties // Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this. -$taborder = array(9, 15, 30, 0, 4, 3, 2, 0, 1, 8, 19, 16, 39, 27, 40, 38, 0, 5, 11, 0, 6, 24, 0, 29, 0, 33, 34, 32, 28, 17, 35, 36, 0, 10, 23, 12, 13, 7, 0, 14, 0, 22, 20, 18, 21, 41, 0, 37, 42, 0, 43, 0, 25, 0); +$taborder = array(9, 15, 30, 0, 4, 3, 2, 0, 1, 8, 19, 16, 39, 27, 40, 38, 0, 5, 11, 0, 6, 24, 0, 29, 0, 33, 34, 32, 28, 17, 35, 36, 0, 10, 23, 12, 13, 7, 0, 14, 0, 22, 20, 18, 21, 41, 0, 37, 42, 0, 43, 0, 25, 0, 44, 0); // Name of SQL tables of dictionaries $tabname = array(); -$tabname[1] = MAIN_DB_PREFIX."c_forme_juridique"; -$tabname[2] = MAIN_DB_PREFIX."c_departements"; -$tabname[3] = MAIN_DB_PREFIX."c_regions"; -$tabname[4] = MAIN_DB_PREFIX."c_country"; -$tabname[5] = MAIN_DB_PREFIX."c_civility"; -$tabname[6] = MAIN_DB_PREFIX."c_actioncomm"; -$tabname[7] = MAIN_DB_PREFIX."c_chargesociales"; -$tabname[8] = MAIN_DB_PREFIX."c_typent"; -$tabname[9] = MAIN_DB_PREFIX."c_currencies"; -$tabname[10] = MAIN_DB_PREFIX."c_tva"; -$tabname[11] = MAIN_DB_PREFIX."c_type_contact"; -$tabname[12] = MAIN_DB_PREFIX."c_payment_term"; -$tabname[13] = MAIN_DB_PREFIX."c_paiement"; -$tabname[14] = MAIN_DB_PREFIX."c_ecotaxe"; -$tabname[15] = MAIN_DB_PREFIX."c_paper_format"; -$tabname[16] = MAIN_DB_PREFIX."c_prospectlevel"; -$tabname[17] = MAIN_DB_PREFIX."c_type_fees"; -$tabname[18] = MAIN_DB_PREFIX."c_shipment_mode"; -$tabname[19] = MAIN_DB_PREFIX."c_effectif"; -$tabname[20] = MAIN_DB_PREFIX."c_input_method"; -$tabname[21] = MAIN_DB_PREFIX."c_availability"; -$tabname[22] = MAIN_DB_PREFIX."c_input_reason"; -$tabname[23] = MAIN_DB_PREFIX."c_revenuestamp"; -$tabname[24] = MAIN_DB_PREFIX."c_type_resource"; -$tabname[25] = MAIN_DB_PREFIX."c_type_container"; -//$tabname[26]= MAIN_DB_PREFIX."c_units"; -$tabname[27] = MAIN_DB_PREFIX."c_stcomm"; -$tabname[28] = MAIN_DB_PREFIX."c_holiday_types"; -$tabname[29] = MAIN_DB_PREFIX."c_lead_status"; -$tabname[30] = MAIN_DB_PREFIX."c_format_cards"; -//$tabname[31]= MAIN_DB_PREFIX."accounting_system"; -$tabname[32] = MAIN_DB_PREFIX."c_hrm_public_holiday"; -$tabname[33] = MAIN_DB_PREFIX."c_hrm_department"; -$tabname[34] = MAIN_DB_PREFIX."c_hrm_function"; -$tabname[35] = MAIN_DB_PREFIX."c_exp_tax_cat"; -$tabname[36] = MAIN_DB_PREFIX."c_exp_tax_range"; -$tabname[37] = MAIN_DB_PREFIX."c_units"; -$tabname[38] = MAIN_DB_PREFIX."c_socialnetworks"; -$tabname[39] = MAIN_DB_PREFIX."c_prospectcontactlevel"; -$tabname[40] = MAIN_DB_PREFIX."c_stcommcontact"; -$tabname[41] = MAIN_DB_PREFIX."c_transport_mode"; -$tabname[42] = MAIN_DB_PREFIX."c_product_nature"; -$tabname[43] = MAIN_DB_PREFIX."c_productbatch_qcstatus"; +$tabname[1] = "c_forme_juridique"; +$tabname[2] = "c_departements"; +$tabname[3] = "c_regions"; +$tabname[4] = "c_country"; +$tabname[5] = "c_civility"; +$tabname[6] = "c_actioncomm"; +$tabname[7] = "c_chargesociales"; +$tabname[8] = "c_typent"; +$tabname[9] = "c_currencies"; +$tabname[10] = "c_tva"; +$tabname[11] = "c_type_contact"; +$tabname[12] = "c_payment_term"; +$tabname[13] = "c_paiement"; +$tabname[14] = "c_ecotaxe"; +$tabname[15] = "c_paper_format"; +$tabname[16] = "c_prospectlevel"; +$tabname[17] = "c_type_fees"; +$tabname[18] = "c_shipment_mode"; +$tabname[19] = "c_effectif"; +$tabname[20] = "c_input_method"; +$tabname[21] = "c_availability"; +$tabname[22] = "c_input_reason"; +$tabname[23] = "c_revenuestamp"; +$tabname[24] = "c_type_resource"; +$tabname[25] = "c_type_container"; +//$tabname[26]= "c_units"; +$tabname[27] = "c_stcomm"; +$tabname[28] = "c_holiday_types"; +$tabname[29] = "c_lead_status"; +$tabname[30] = "c_format_cards"; +//$tabname[31]= "accounting_system"; +$tabname[32] = "c_hrm_public_holiday"; +$tabname[33] = "c_hrm_department"; +$tabname[34] = "c_hrm_function"; +$tabname[35] = "c_exp_tax_cat"; +$tabname[36] = "c_exp_tax_range"; +$tabname[37] = "c_units"; +$tabname[38] = "c_socialnetworks"; +$tabname[39] = "c_prospectcontactlevel"; +$tabname[40] = "c_stcommcontact"; +$tabname[41] = "c_transport_mode"; +$tabname[42] = "c_product_nature"; +$tabname[43] = "c_productbatch_qcstatus"; +$tabname[44] = "c_asset_disposal_type"; // Dictionary labels $tablib = array(); @@ -193,13 +194,14 @@ $tablib[40] = "DictionaryProspectContactStatus"; $tablib[41] = "DictionaryTransportMode"; $tablib[42] = "DictionaryProductNature"; $tablib[43] = "DictionaryBatchStatus"; +$tablib[44] = "DictionaryAssetDisposalType"; // Requests to extract data $tabsql = array(); $tabsql[1] = "SELECT f.rowid as rowid, f.code, f.libelle, c.code as country_code, c.label as country, f.active FROM ".MAIN_DB_PREFIX."c_forme_juridique as f, ".MAIN_DB_PREFIX."c_country as c WHERE f.fk_pays=c.rowid"; $tabsql[2] = "SELECT d.rowid as rowid, d.code_departement as code, d.nom as libelle, d.fk_region as region_id, r.nom as region, c.code as country_code, c.label as country, d.active FROM ".MAIN_DB_PREFIX."c_departements as d, ".MAIN_DB_PREFIX."c_regions as r, ".MAIN_DB_PREFIX."c_country as c WHERE d.fk_region=r.code_region and r.fk_pays=c.rowid and r.active=1 and c.active=1"; $tabsql[3] = "SELECT r.rowid as rowid, r.code_region as state_code, r.nom as libelle, r.fk_pays as country_id, c.code as country_code, c.label as country, r.active FROM ".MAIN_DB_PREFIX."c_regions as r, ".MAIN_DB_PREFIX."c_country as c WHERE r.fk_pays=c.rowid and c.active=1"; -$tabsql[4] = "SELECT c.rowid as rowid, c.code, c.label, c.active, c.favorite FROM ".MAIN_DB_PREFIX."c_country AS c"; +$tabsql[4] = "SELECT c.rowid as rowid, c.code, c.label, c.active, c.favorite, c.eec FROM ".MAIN_DB_PREFIX."c_country AS c"; $tabsql[5] = "SELECT c.rowid as rowid, c.code as code, c.label, c.active FROM ".MAIN_DB_PREFIX."c_civility AS c"; $tabsql[6] = "SELECT a.id as rowid, a.code as code, a.libelle AS libelle, a.type, a.active, a.module, a.color, a.position FROM ".MAIN_DB_PREFIX."c_actioncomm AS a"; $tabsql[7] = "SELECT a.id as rowid, a.code as code, a.libelle AS libelle, a.accountancy_code as accountancy_code, c.code as country_code, c.label as country, a.fk_pays as country_id, a.active FROM ".MAIN_DB_PREFIX."c_chargesociales AS a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_pays=c.rowid and c.active=1"; @@ -207,7 +209,7 @@ $tabsql[8] = "SELECT t.id as rowid, t.code as code, t.libelle, t.fk_country as $tabsql[9] = "SELECT c.code_iso as code, c.label, c.unicode, c.active FROM ".MAIN_DB_PREFIX."c_currencies AS c"; $tabsql[10] = "SELECT t.rowid, t.code, t.taux, t.localtax1_type, t.localtax1, t.localtax2_type, t.localtax2, c.label as country, c.code as country_code, t.fk_pays as country_id, t.recuperableonly, t.note, t.active, t.accountancy_code_sell, t.accountancy_code_buy FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c WHERE t.fk_pays=c.rowid"; $tabsql[11] = "SELECT t.rowid as rowid, t.element, t.source, t.code, t.libelle, t.position, t.active FROM ".MAIN_DB_PREFIX."c_type_contact AS t"; -$tabsql[12] = "SELECT c.rowid as rowid, c.code, c.libelle, c.libelle_facture, c.nbjour, c.type_cdr, c.decalage, c.active, c.sortorder, c.entity FROM ".MAIN_DB_PREFIX."c_payment_term AS c WHERE c.entity = ".getEntity($tabname[12]); +$tabsql[12] = "SELECT c.rowid as rowid, c.code, c.libelle, c.libelle_facture, c.deposit_percent, c.nbjour, c.type_cdr, c.decalage, c.active, c.sortorder, c.entity FROM ".MAIN_DB_PREFIX."c_payment_term AS c WHERE c.entity = ".getEntity($tabname[12]); $tabsql[13] = "SELECT c.id as rowid, c.code, c.libelle, c.type, c.active, c.entity FROM ".MAIN_DB_PREFIX."c_paiement AS c WHERE c.entity = ".getEntity($tabname[13]); $tabsql[14] = "SELECT e.rowid as rowid, e.code as code, e.label, e.price, e.organization, e.fk_pays as country_id, c.code as country_code, c.label as country, e.active FROM ".MAIN_DB_PREFIX."c_ecotaxe AS e, ".MAIN_DB_PREFIX."c_country as c WHERE e.fk_pays=c.rowid and c.active=1"; $tabsql[15] = "SELECT rowid as rowid, code, label as libelle, width, height, unit, active FROM ".MAIN_DB_PREFIX."c_paper_format"; @@ -216,14 +218,14 @@ $tabsql[17] = "SELECT id as rowid, code, label, accountancy_code, active FR $tabsql[18] = "SELECT rowid as rowid, code, libelle, tracking, active FROM ".MAIN_DB_PREFIX."c_shipment_mode"; $tabsql[19] = "SELECT id as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_effectif"; $tabsql[20] = "SELECT rowid as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_input_method"; -$tabsql[21] = "SELECT c.rowid as rowid, c.code, c.label, c.active, c.position FROM ".MAIN_DB_PREFIX."c_availability AS c"; +$tabsql[21] = "SELECT c.rowid as rowid, c.code, c.label, c.type_duration, c.qty, c.active, c.position FROM ".MAIN_DB_PREFIX."c_availability AS c"; $tabsql[22] = "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_input_reason"; $tabsql[23] = "SELECT t.rowid as rowid, t.taux, t.revenuestamp_type, c.label as country, c.code as country_code, t.fk_pays as country_id, t.note, t.active, t.accountancy_code_sell, t.accountancy_code_buy FROM ".MAIN_DB_PREFIX."c_revenuestamp as t, ".MAIN_DB_PREFIX."c_country as c WHERE t.fk_pays=c.rowid"; $tabsql[24] = "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_type_resource"; $tabsql[25] = "SELECT rowid as rowid, code, label, active, module FROM ".MAIN_DB_PREFIX."c_type_container as t WHERE t.entity = ".getEntity($tabname[25]); //$tabsql[26]= "SELECT rowid as rowid, code, label, short_label, active FROM ".MAIN_DB_PREFIX."c_units"; $tabsql[27] = "SELECT id as rowid, code, libelle, picto, active FROM ".MAIN_DB_PREFIX."c_stcomm"; -$tabsql[28] = "SELECT h.rowid as rowid, h.code, h.label, h.affect, h.delay, h.newbymonth, h.fk_country as country_id, c.code as country_code, c.label as country, h.active FROM ".MAIN_DB_PREFIX."c_holiday_types as h LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON h.fk_country=c.rowid"; +$tabsql[28] = "SELECT h.rowid as rowid, h.code, h.label, h.affect, h.delay, h.newbymonth, h.fk_country as country_id, c.code as country_code, c.label as country, h.block_if_negative, h.sortorder, h.active FROM ".MAIN_DB_PREFIX."c_holiday_types as h LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON h.fk_country=c.rowid"; $tabsql[29] = "SELECT rowid as rowid, code, label, percent, position, active FROM ".MAIN_DB_PREFIX."c_lead_status"; $tabsql[30] = "SELECT rowid, code, name, paper_size, orientation, metric, leftmargin, topmargin, nx, ny, spacex, spacey, width, height, font_size, custom_x, custom_y, active FROM ".MAIN_DB_PREFIX."c_format_cards"; //$tabsql[31]= "SELECT s.rowid as rowid, pcg_version, s.label, s.active FROM ".MAIN_DB_PREFIX."accounting_system as s"; @@ -239,6 +241,7 @@ $tabsql[40] = "SELECT id as rowid, code, libelle, picto, active FROM ".MAIN $tabsql[41] = "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_transport_mode"; $tabsql[42] = "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_product_nature"; $tabsql[43] = "SELECT rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_productbatch_qcstatus"; +$tabsql[44] = "SELECT rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_asset_disposal_type"; // Criteria to sort dictionaries $tabsqlsort = array(); @@ -262,14 +265,14 @@ $tabsqlsort[17] = "code ASC"; $tabsqlsort[18] = "code ASC, libelle ASC"; $tabsqlsort[19] = "id ASC"; $tabsqlsort[20] = "code ASC, libelle ASC"; -$tabsqlsort[21] = "code ASC, label ASC, position ASC"; +$tabsqlsort[21] = "position ASC, type_duration ASC, qty ASC"; $tabsqlsort[22] = "code ASC, label ASC"; $tabsqlsort[23] = "country ASC, taux ASC"; $tabsqlsort[24] = "code ASC, label ASC"; $tabsqlsort[25] = "t.module ASC, t.code ASC, t.label ASC"; //$tabsqlsort[26]="code ASC"; $tabsqlsort[27] = "code ASC"; -$tabsqlsort[28] = "country ASC, code ASC"; +$tabsqlsort[28] = "sortorder ASC, country ASC, code ASC"; $tabsqlsort[29] = "position ASC"; $tabsqlsort[30] = "code ASC"; //$tabsqlsort[31]="pcg_version ASC"; @@ -285,6 +288,7 @@ $tabsqlsort[40] = "code ASC"; $tabsqlsort[41] = "code ASC"; $tabsqlsort[42] = "code ASC"; $tabsqlsort[43] = "code ASC"; +$tabsqlsort[44] = "code ASC"; // Field names in select result for dictionary display $tabfield = array(); @@ -299,7 +303,7 @@ $tabfield[8] = "code,libelle,country_id,country".(!empty($conf->global->SOCIETE_ $tabfield[9] = "code,label,unicode"; $tabfield[10] = "country_id,country,code,taux,localtax1_type,localtax1,localtax2_type,localtax2,recuperableonly,accountancy_code_sell,accountancy_code_buy,note"; $tabfield[11] = "element,source,code,libelle,position"; -$tabfield[12] = "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder,entity"; +$tabfield[12] = "code,libelle,libelle_facture,deposit_percent,nbjour,type_cdr,decalage,sortorder,entity"; $tabfield[13] = "code,libelle,type,entity"; $tabfield[14] = "code,label,price,organization,country"; $tabfield[15] = "code,libelle,width,height,unit"; @@ -308,14 +312,14 @@ $tabfield[17] = "code,label,accountancy_code"; $tabfield[18] = "code,libelle,tracking"; $tabfield[19] = "code,libelle"; $tabfield[20] = "code,libelle"; -$tabfield[21] = "code,label,position"; +$tabfield[21] = "code,label,qty,type_duration,position"; $tabfield[22] = "code,label"; $tabfield[23] = "country_id,country,taux,revenuestamp_type,accountancy_code_sell,accountancy_code_buy,note"; $tabfield[24] = "code,label"; $tabfield[25] = "code,label"; //$tabfield[26]= "code,label,short_label"; $tabfield[27] = "code,libelle,picto"; -$tabfield[28] = "code,label,affect,delay,newbymonth,country_id,country"; +$tabfield[28] = "code,label,affect,delay,newbymonth,country_id,country,block_if_negative,sortorder"; $tabfield[29] = "code,label,percent,position"; $tabfield[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; //$tabfield[31]= "pcg_version,label"; @@ -331,6 +335,7 @@ $tabfield[40] = "code,libelle,picto"; $tabfield[41] = "code,label"; $tabfield[42] = "code,label"; $tabfield[43] = "code,label"; +$tabfield[44] = "code,label"; // Edit field names for editing a record $tabfieldvalue = array(); @@ -345,7 +350,7 @@ $tabfieldvalue[8] = "code,libelle,country".(!empty($conf->global->SOCIETE_SORT_O $tabfieldvalue[9] = "code,label,unicode"; $tabfieldvalue[10] = "country,code,taux,localtax1_type,localtax1,localtax2_type,localtax2,recuperableonly,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldvalue[11] = "element,source,code,libelle,position"; -$tabfieldvalue[12] = "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder"; +$tabfieldvalue[12] = "code,libelle,libelle_facture,deposit_percent,nbjour,type_cdr,decalage,sortorder"; $tabfieldvalue[13] = "code,libelle,type"; $tabfieldvalue[14] = "code,label,price,organization,country"; $tabfieldvalue[15] = "code,libelle,width,height,unit"; @@ -354,14 +359,14 @@ $tabfieldvalue[17] = "code,label,accountancy_code"; $tabfieldvalue[18] = "code,libelle,tracking"; $tabfieldvalue[19] = "code,libelle"; $tabfieldvalue[20] = "code,libelle"; -$tabfieldvalue[21] = "code,label,position"; +$tabfieldvalue[21] = "code,label,qty,type_duration,position"; $tabfieldvalue[22] = "code,label"; $tabfieldvalue[23] = "country,taux,revenuestamp_type,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldvalue[24] = "code,label"; $tabfieldvalue[25] = "code,label"; //$tabfieldvalue[26]= "code,label,short_label"; $tabfieldvalue[27] = "code,libelle,picto"; -$tabfieldvalue[28] = "code,label,affect,delay,newbymonth,country"; +$tabfieldvalue[28] = "code,label,affect,delay,newbymonth,country,block_if_negative,sortorder"; $tabfieldvalue[29] = "code,label,percent,position"; $tabfieldvalue[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; //$tabfieldvalue[31]= "pcg_version,label"; @@ -377,6 +382,7 @@ $tabfieldvalue[40] = "code,libelle,picto"; $tabfieldvalue[41] = "code,label"; $tabfieldvalue[42] = "code,label"; $tabfieldvalue[43] = "code,label"; +$tabfieldvalue[44] = "code,label"; // Field names in the table for inserting a record $tabfieldinsert = array(); @@ -391,7 +397,7 @@ $tabfieldinsert[8] = "code,libelle,fk_country".(!empty($conf->global->SOCIETE_SO $tabfieldinsert[9] = "code_iso,label,unicode"; $tabfieldinsert[10] = "fk_pays,code,taux,localtax1_type,localtax1,localtax2_type,localtax2,recuperableonly,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldinsert[11] = "element,source,code,libelle,position"; -$tabfieldinsert[12] = "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder,entity"; +$tabfieldinsert[12] = "code,libelle,libelle_facture,deposit_percent,nbjour,type_cdr,decalage,sortorder,entity"; $tabfieldinsert[13] = "code,libelle,type,entity"; $tabfieldinsert[14] = "code,label,price,organization,fk_pays"; $tabfieldinsert[15] = "code,label,width,height,unit"; @@ -400,14 +406,14 @@ $tabfieldinsert[17] = "code,label,accountancy_code"; $tabfieldinsert[18] = "code,libelle,tracking"; $tabfieldinsert[19] = "code,libelle"; $tabfieldinsert[20] = "code,libelle"; -$tabfieldinsert[21] = "code,label,position"; +$tabfieldinsert[21] = "code,label,qty,type_duration,position"; $tabfieldinsert[22] = "code,label"; $tabfieldinsert[23] = "fk_pays,taux,revenuestamp_type,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldinsert[24] = "code,label"; $tabfieldinsert[25] = "code,label"; //$tabfieldinsert[26]= "code,label,short_label"; $tabfieldinsert[27] = "code,libelle,picto"; -$tabfieldinsert[28] = "code,label,affect,delay,newbymonth,fk_country"; +$tabfieldinsert[28] = "code,label,affect,delay,newbymonth,fk_country,block_if_negative,sortorder"; $tabfieldinsert[29] = "code,label,percent,position"; $tabfieldinsert[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; //$tabfieldinsert[31]= "pcg_version,label"; @@ -424,6 +430,7 @@ $tabfieldinsert[40] = "code,libelle,picto"; $tabfieldinsert[41] = "code,label"; $tabfieldinsert[42] = "code,label"; $tabfieldinsert[43] = "code,label"; +$tabfieldinsert[44] = "code,label"; // Rowid name of field depending if field is autoincrement on or off.. // Use "" if id field is "rowid" and has autoincrement on @@ -472,6 +479,7 @@ $tabrowid[40] = "id"; $tabrowid[41] = ""; $tabrowid[42] = "rowid"; $tabrowid[43] = "rowid"; +$tabrowid[44] = "rowid"; // Condition to show dictionary in setup page $tabcond = array(); @@ -518,111 +526,96 @@ $tabcond[40] = (!empty($conf->societe->enabled) && !empty($conf->global->THIRDPA $tabcond[41] = !empty($conf->intracommreport->enabled); $tabcond[42] = !empty($conf->product->enabled); $tabcond[43] = !empty($conf->product->enabled) && !empty($conf->productbatch->enabled) && $conf->global->MAIN_FEATURES_LEVEL >= 2; +$tabcond[44] = !empty($conf->asset->enabled); -// List of help for fields +// List of help for fields (no more used, help is defined into tabcomplete) $tabhelp = array(); -$tabhelp[1] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[2] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[3] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[4] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[5] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[6] = array('code'=>$langs->trans("EnterAnyCode"), 'color'=>$langs->trans("ColorFormat"), 'position'=>$langs->trans("PositionIntoComboList")); -$tabhelp[7] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[8] = array('code'=>$langs->trans("EnterAnyCode"), 'position'=>$langs->trans("PositionIntoComboList")); -$tabhelp[9] = array('code'=>$langs->trans("EnterAnyCode"), 'unicode'=>$langs->trans("UnicodeCurrency")); -$tabhelp[10] = array('code'=>$langs->trans("EnterAnyCode"), 'taux'=>$langs->trans("SellTaxRate"), 'recuperableonly'=>$langs->trans("RecuperableOnly"), 'localtax1_type'=>$langs->trans("LocalTaxDesc"), 'localtax2_type'=>$langs->trans("LocalTaxDesc")); -$tabhelp[11] = array('code'=>$langs->trans("EnterAnyCode"), 'position'=>$langs->trans("PositionIntoComboList")); -$tabhelp[12] = array('code'=>$langs->trans("EnterAnyCode"), 'type_cdr'=>$langs->trans("TypeCdr", $langs->transnoentitiesnoconv("NbOfDays"), $langs->transnoentitiesnoconv("Offset"), $langs->transnoentitiesnoconv("NbOfDays"), $langs->transnoentitiesnoconv("Offset"))); -$tabhelp[13] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[14] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[15] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[16] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[17] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[18] = array('code'=>$langs->trans("EnterAnyCode"), 'tracking'=>$langs->trans("UrlTrackingDesc")); -$tabhelp[19] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[20] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[21] = array('code'=>$langs->trans("EnterAnyCode"), 'position'=>$langs->trans("PositionIntoComboList")); -$tabhelp[22] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[23] = array('revenuestamp_type'=>'FixedOrPercent'); -$tabhelp[24] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[25] = array('code'=>$langs->trans('EnterAnyCode')); -//$tabhelp[26] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[27] = array('code'=>$langs->trans("EnterAnyCode"), 'picto'=>$langs->trans("PictoHelp")); -$tabhelp[28] = array('affect'=>$langs->trans("FollowedByACounter"), 'delay'=>$langs->trans("MinimumNoticePeriod"), 'newbymonth'=>$langs->trans("NbAddedAutomatically")); -$tabhelp[29] = array('code'=>$langs->trans("EnterAnyCode"), 'percent'=>$langs->trans("OpportunityPercent"), 'position'=>$langs->trans("PositionIntoComboList")); -$tabhelp[30] = array('code'=>$langs->trans("EnterAnyCode"), 'name'=>$langs->trans("LabelName"), 'paper_size'=>$langs->trans("LabelPaperSize")); -//$tabhelp[31] = array('pcg_version'=>$langs->trans("EnterAnyCode")); -$tabhelp[32] = array('code'=>$langs->trans("EnterAnyCode"), 'dayrule'=>"Keep empty for a date defined with month and day (most common case).
Use a keyword like 'easter', 'eastermonday', ... for a date predefined by complex rules.", 'country'=>$langs->trans("CountryIfSpecificToOneCountry"), 'year'=>$langs->trans("ZeroMeansEveryYear")); -$tabhelp[33] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[34] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[35] = array(); -$tabhelp[36] = array('range_ik'=>$langs->trans('PrevRangeToThisRange')); -$tabhelp[37] = array('code'=>$langs->trans("EnterAnyCode"), 'unit_type' => $langs->trans('MeasuringUnitTypeDesc'), 'scale' => $langs->trans('MeasuringScaleDesc')); -$tabhelp[38] = array('code'=>$langs->trans("EnterAnyCode"), 'url' => $langs->trans('UrlSocialNetworksDesc'), 'icon' => $langs->trans('FafaIconSocialNetworksDesc')); -$tabhelp[39] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[40] = array('code'=>$langs->trans("EnterAnyCode"), 'picto'=>$langs->trans("PictoHelp")); -$tabhelp[41] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[42] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[43] = array('code'=>$langs->trans("EnterAnyCode")); // Table to store complete informations (will replace all other table). Key is table name. $tabcomplete = array( - 'c_forme_juridique'=>array('picto'=>'company'), - 'c_departements'=>array('picto'=>'state'), - 'c_regions'=>array('picto'=>'region'), - 'c_country'=>array('picto'=>'country'), - 'c_civility'=>array('picto'=>'contact'), - 'c_actioncomm'=>array('picto'=>'action'), - 'c_chargesociales'=>array('picto'=>'bill'), - 'c_typent'=>array('picto'=>'company'), - 'c_currencies'=>array('picto'=>'multicurrency'), - 'c_tva'=>array('picto'=>'bill'), - 'c_type_contact'=>array('picto'=>'contact'), - 'c_payment_term'=>array('picto'=>'bill'), - 'c_paiement'=>array('picto'=>'bill'), - 'c_ecotaxe'=>array('picto'=>'bill'), - 'c_paper_format'=>array('picto'=>'generic'), - 'c_prospectlevel'=>array('picto'=>'company'), - 'c_type_fees'=>array('picto'=>'trip'), - 'c_effectif'=>array('picto'=>'company'), - 'c_input_method'=>array('picto'=>'order'), - 'c_input_reason'=>array('picto'=>'order'), - 'c_availability'=>array('picto'=>'shipment'), - 'c_shipment_mode'=>array('picto'=>'shipment'), - 'c_revenuestamp'=>array('picto'=>'bill'), - 'c_type_resource'=>array('picto'=>'resource'), - 'c_type_container'=>array('picto'=>'website'), - 'c_stcomm'=>array('picto'=>'company'), - 'c_holiday_types'=>array('picto'=>'holiday'), - 'c_lead_status'=>array('picto'=>'project'), - 'c_format_cards'=>array('picto'=>'generic'), - 'c_hrm_public_holiday'=>array('picto'=>'holiday'), - 'c_hrm_department'=>array('picto'=>'hrm'), - 'c_hrm_function'=>array('picto'=>'hrm'), - 'c_exp_tax_cat'=>array('picto'=>'expensereport'), - 'c_exp_tax_range'=>array('picto'=>'expensereport'), - 'c_units'=>array('picto'=>'product'), - 'c_socialnetworks'=>array('picto'=>'share-alt'), - 'c_product_nature'=>array('picto'=>'product'), - 'c_transport_mode'=>array('picto'=>'incoterm'), - 'c_prospectcontactlevel'=>array('picto'=>'company'), - 'c_stcommcontact'=>array('picto'=>'company'), - 'c_product_nature'=>array('picto'=>'product'), - 'c_productbatch_qcstatus'=>array('picto'=>'lot'), - + 'c_forme_juridique'=>array('picto'=>'company', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_departements'=>array('picto'=>'state', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_regions'=>array('picto'=>'region', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_country'=>array('picto'=>'country', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_civility'=>array('picto'=>'contact', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_actioncomm'=>array('picto'=>'action', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'color'=>$langs->trans("ColorFormat"), 'position'=>$langs->trans("PositionIntoComboList"))), + 'c_chargesociales'=>array('picto'=>'bill', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_typent'=>array('picto'=>'company', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'position'=>$langs->trans("PositionIntoComboList"))), + 'c_currencies'=>array('picto'=>'multicurrency', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'unicode'=>$langs->trans("UnicodeCurrency"))), + 'c_tva'=>array('picto'=>'bill', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'taux'=>$langs->trans("SellTaxRate"), 'recuperableonly'=>$langs->trans("RecuperableOnly"), 'localtax1_type'=>$langs->trans("LocalTaxDesc"), 'localtax2_type'=>$langs->trans("LocalTaxDesc"))), + 'c_type_contact'=>array('picto'=>'contact', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'position'=>$langs->trans("PositionIntoComboList"))), + 'c_payment_term'=>array('picto'=>'bill', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'type_cdr'=>$langs->trans("TypeCdr", $langs->transnoentitiesnoconv("NbOfDays"), $langs->transnoentitiesnoconv("Offset"), $langs->transnoentitiesnoconv("NbOfDays"), $langs->transnoentitiesnoconv("Offset")))), + 'c_paiement'=>array('picto'=>'bill', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_ecotaxe'=>array('picto'=>'bill', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_paper_format'=>array('picto'=>'generic', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_prospectlevel'=>array('picto'=>'company', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_type_fees'=>array('picto'=>'trip', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_shipment_mode'=>array('picto'=>'shipment', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'tracking'=>$langs->trans("UrlTrackingDesc"))), + 'c_effectif'=>array('picto'=>'company', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_input_method'=>array('picto'=>'order', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_input_reason'=>array('picto'=>'order', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'position'=>$langs->trans("PositionIntoComboList"))), + 'c_availability'=>array('picto'=>'shipment', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_revenuestamp'=>array('picto'=>'bill', 'help'=>array('revenuestamp_type'=>$langs->trans('FixedOrPercent'))), + 'c_type_resource'=>array('picto'=>'resource', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_type_container'=>array('picto'=>'website', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_stcomm'=>array('picto'=>'company', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'picto'=>$langs->trans("PictoHelp"))), + 'c_holiday_types'=>array('picto'=>'holiday', 'help'=>array('affect'=>$langs->trans("FollowedByACounter"), 'delay'=>$langs->trans("MinimumNoticePeriod"), 'newbymonth'=>$langs->trans("NbAddedAutomatically"))), + 'c_lead_status'=>array('picto'=>'project', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'percent'=>$langs->trans("OpportunityPercent"), 'position'=>$langs->trans("PositionIntoComboList"))), + 'c_format_cards'=>array('picto'=>'generic', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'name'=>$langs->trans("LabelName"), 'paper_size'=>$langs->trans("LabelPaperSize"))), + 'c_hrm_public_holiday'=>array('picto'=>'holiday', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'dayrule'=>"Keep empty for a date defined with month and day (most common case).
Use a keyword like 'easter', 'eastermonday', ... for a date predefined by complex rules.", 'country'=>$langs->trans("CountryIfSpecificToOneCountry"), 'year'=>$langs->trans("ZeroMeansEveryYear"))), + 'c_hrm_department'=>array('picto'=>'hrm', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_hrm_function'=>array('picto'=>'hrm', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_exp_tax_cat'=>array('picto'=>'expensereport', 'help'=>array()), + 'c_exp_tax_range'=>array('picto'=>'expensereport', 'help'=>array('range_ik'=>$langs->trans('PrevRangeToThisRange'))), + 'c_units'=>array('picto'=>'product', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'unit_type' => $langs->trans('Measuringtype_durationDesc'), 'scale' => $langs->trans('MeasuringScaleDesc'))), + 'c_socialnetworks'=>array('picto'=>'share-alt', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'url' => $langs->trans('UrlSocialNetworksDesc'), 'icon' => $langs->trans('FafaIconSocialNetworksDesc'))), + 'c_prospectcontactlevel'=>array('picto'=>'company', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_stcommcontact'=>array('picto'=>'company', 'help'=>array('code'=>$langs->trans("EnterAnyCode"), 'picto'=>$langs->trans("PictoHelp"))), + 'c_transport_mode'=>array('picto'=>'incoterm', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_product_nature'=>array('picto'=>'product', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_productbatch_qcstatus'=>array('picto'=>'lot', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), + 'c_asset_disposal_type'=>array('picto'=>'asset', 'help'=>array('code'=>$langs->trans("EnterAnyCode"))), ); // Complete all arrays with entries found into modules complete_dictionary_with_modules($taborder, $tabname, $tablib, $tabsql, $tabsqlsort, $tabfield, $tabfieldvalue, $tabfieldinsert, $tabrowid, $tabcond, $tabhelp, $tabcomplete); +// Complete the table $tabcomplete +$i = 0; +foreach ($tabcomplete as $key => $value) { + $i++; + // When a dictionnary is commented + if (!isset($tabcond[$i])) { + continue; + } + $tabcomplete[$key]['id'] = $i; + $tabcomplete[$key]['cond'] = $tabcond[$i]; + $tabcomplete[$key]['rowid'] = $tabrowid[$i]; + $tabcomplete[$key]['fieldinsert'] = $tabfieldinsert[$i]; + $tabcomplete[$key]['fieldvalue'] = $tabfieldvalue[$i]; + $tabcomplete[$key]['lib'] = $tablib[$i]; + $tabcomplete[$key]['sql'] = $tabsql[$i]; + $tabcomplete[$key]['sqlsort'] = $tabsqlsort[$i]; + $tabcomplete[$key]['field'] = $tabfield[$i]; +} + +$keytable = ''; +if ($id > 0) { + $arrayofkeys = array_keys($tabcomplete); + $keytable = $arrayofkeys[$id - 1]; +} + // Defaut sortorder if (empty($sortfield)) { - $tmp1 = explode(',', empty($tabsqlsort[$id]) ? '' : $tabsqlsort[$id]); + $tmp1 = explode(',', empty($tabcomplete[$keytable]['sqlsort']) ? '' : $tabcomplete[$keytable]['sqlsort']); $tmp2 = explode(' ', $tmp1[0]); $sortfield = preg_replace('/^.*\./', '', $tmp2[0]); + $sortorder = (!empty($tmp2[1]) ? $tmp2[1] : ''); + //var_dump($sortfield);var_dump($sortorder); } + // Define elementList and sourceList (used for dictionary type of contacts "llx_c_type_contact") $elementList = array(); $sourceList = array(); @@ -664,430 +657,490 @@ if ($id == 11) { } // Define localtax_typeList (used for dictionary "llx_c_tva") -$localtax_typeList = array(); -if ($id == 10) { - $localtax_typeList = array( - "0" => $langs->trans("No"), - "1" => $langs->trans("Yes").' ('.$langs->trans("Type")." 1)", //$langs->trans("%ageOnAllWithoutVAT"), - "2" => $langs->trans("Yes").' ('.$langs->trans("Type")." 2)", //$langs->trans("%ageOnAllBeforeVAT"), - "3" => $langs->trans("Yes").' ('.$langs->trans("Type")." 3)", //$langs->trans("%ageOnProductsWithoutVAT"), - "4" => $langs->trans("Yes").' ('.$langs->trans("Type")." 4)", //$langs->trans("%ageOnProductsBeforeVAT"), - "5" => $langs->trans("Yes").' ('.$langs->trans("Type")." 5)", //$langs->trans("%ageOnServiceWithoutVAT"), - "6" => $langs->trans("Yes").' ('.$langs->trans("Type")." 6)" //$langs->trans("%ageOnServiceBeforeVAT"), - ); -} - +$localtax_typeList = array( + "0" => $langs->trans("No"), + "1" => $langs->trans("Yes").' ('.$langs->trans("Type")." 1)", //$langs->trans("%ageOnAllWithoutVAT"), + "2" => $langs->trans("Yes").' ('.$langs->trans("Type")." 2)", //$langs->trans("%ageOnAllBeforeVAT"), + "3" => $langs->trans("Yes").' ('.$langs->trans("Type")." 3)", //$langs->trans("%ageOnProductsWithoutVAT"), + "4" => $langs->trans("Yes").' ('.$langs->trans("Type")." 4)", //$langs->trans("%ageOnProductsBeforeVAT"), + "5" => $langs->trans("Yes").' ('.$langs->trans("Type")." 5)", //$langs->trans("%ageOnServiceWithoutVAT"), + "6" => $langs->trans("Yes").' ('.$langs->trans("Type")." 6)" //$langs->trans("%ageOnServiceBeforeVAT"), +); /* * Actions */ +$object = new stdClass(); +$parameters = array( + 'id' =>$id, + 'rowid' =>$rowid, + 'code' =>$code, + 'confirm' =>$confirm, + 'entity' =>$entity, + 'taborder' =>$taborder, + 'tabname' =>$tabname, + 'tablib' =>$tablib, + 'tabsql' =>$tabsql, + 'tabsqlsort' =>$tabsqlsort, + 'tabfield' =>$tabfield, + 'tabfieldvalue' =>$tabfieldvalue, + 'tabfieldinsert'=>$tabfieldinsert, + 'tabrowid' =>$tabrowid, + 'tabcond' =>$tabcond, + 'tabhelp' =>$tabhelp, + 'tabcomplete' =>$tabcomplete +); +$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 (GETPOST('button_removefilter', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter_x', 'alpha')) { $search_country_id = ''; $search_code = ''; } -// Actions add or modify an entry into a dictionary -if (GETPOST('actionadd') || GETPOST('actionmodify')) { - $listfield = explode(',', str_replace(' ', '', $tabfield[$id])); - $listfieldinsert = explode(',', $tabfieldinsert[$id]); - $listfieldmodify = explode(',', $tabfieldinsert[$id]); - $listfieldvalue = explode(',', $tabfieldvalue[$id]); +if (empty($reshook)) { + // Actions add or modify an entry into a dictionary + if (GETPOST('actionadd') || GETPOST('actionmodify')) { + $listfield = explode(',', str_replace(' ', '', $tabfield[$id])); + $listfieldinsert = explode(',', $tabfieldinsert[$id]); + $listfieldmodify = explode(',', $tabfieldinsert[$id]); + $listfieldvalue = explode(',', $tabfieldvalue[$id]); - // Check that all mandatory fields are filled - $ok = 1; - foreach ($listfield as $f => $value) { - // Discard check of mandatory fields for country for some tables - if ($value == 'country_id' && in_array($tablib[$id], array('DictionaryPublicHolidays', 'DictionaryVAT', 'DictionaryRegion', 'DictionaryCompanyType', 'DictionaryHolidayTypes', 'DictionaryRevenueStamp', 'DictionaryAccountancysystem', 'DictionaryAccountancyCategory'))) { - continue; // For some pages, country is not mandatory - } - if ($value == 'country' && in_array($tablib[$id], array('DictionaryPublicHolidays', 'DictionaryCanton', 'DictionaryCompanyType', 'DictionaryHolidayTypes', 'DictionaryRevenueStamp'))) { - continue; // For some pages, country is not mandatory - } - // Discard check of mandatory fiedls for other fields - if ($value == 'localtax1' && empty($_POST['localtax1_type'])) { - continue; - } - if ($value == 'localtax2' && empty($_POST['localtax2_type'])) { - continue; - } - if ($value == 'color' && empty($_POST['color'])) { - continue; - } - if ($value == 'formula' && empty($_POST['formula'])) { - continue; - } - if ($value == 'dayrule' && empty($_POST['dayrule'])) { - continue; - } - if ($value == 'sortorder') { - continue; // For a column name 'sortorder', we use the field name 'position' - } - if ((!GETPOSTISSET($value) || GETPOST($value) == '') - && (!in_array($value, array('decalage', 'module', 'accountancy_code', 'accountancy_code_sell', 'accountancy_code_buy', 'tracking', 'picto')) // Fields that are not mandatory - && ($id != 10 || ($value != 'code' && $value != 'note')) // Field code and note is not mandatory for dictionary table 10 - ) - ) { - $ok = 0; - $fieldnamekey = $value; - // We take translate key of field - if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) { - $fieldnamekey = 'Label'; + // Check that all mandatory fields are filled + $ok = 1; + foreach ($listfield as $f => $value) { + // Discard check of mandatory fields for country for some tables + if ($value == 'country_id' && in_array($tablib[$id], array('DictionaryPublicHolidays', 'DictionaryVAT', 'DictionaryRegion', 'DictionaryCompanyType', 'DictionaryHolidayTypes', 'DictionaryRevenueStamp', 'DictionaryAccountancysystem', 'DictionaryAccountancyCategory'))) { + continue; // For some pages, country is not mandatory } - if ($fieldnamekey == 'libelle_facture') { - $fieldnamekey = 'LabelOnDocuments'; + if ($value == 'country' && in_array($tablib[$id], array('DictionaryPublicHolidays', 'DictionaryCanton', 'DictionaryCompanyType', 'DictionaryHolidayTypes', 'DictionaryRevenueStamp'))) { + continue; // For some pages, country is not mandatory } - if ($fieldnamekey == 'nbjour') { - $fieldnamekey = 'NbOfDays'; + // Discard check of mandatory fiedls for other fields + if ($value == 'localtax1' && !GETPOST('localtax1_type')) { + continue; } - if ($fieldnamekey == 'decalage') { - $fieldnamekey = 'Offset'; + if ($value == 'localtax2' && !GETPOST('localtax2_type')) { + continue; } - if ($fieldnamekey == 'module') { - $fieldnamekey = 'Module'; + if ($value == 'color' && !GETPOST('color')) { + continue; } - if ($fieldnamekey == 'code') { - $fieldnamekey = 'Code'; + if ($value == 'formula' && !GETPOST('formula')) { + continue; } - if ($fieldnamekey == 'note') { - $fieldnamekey = 'Note'; + if ($value == 'dayrule' && !GETPOST('dayrule')) { + continue; } - if ($fieldnamekey == 'taux') { - $fieldnamekey = 'Rate'; - } - if ($fieldnamekey == 'type') { - $fieldnamekey = 'Type'; - } - if ($fieldnamekey == 'position') { - $fieldnamekey = 'Position'; - } - if ($fieldnamekey == 'unicode') { - $fieldnamekey = 'Unicode'; - } - if ($fieldnamekey == 'deductible') { - $fieldnamekey = 'Deductible'; - } - if ($fieldnamekey == 'sortorder') { - $fieldnamekey = 'SortOrder'; - } - if ($fieldnamekey == 'category_type') { - $fieldnamekey = 'Calculated'; - } - if ($fieldnamekey == 'revenuestamp_type') { - $fieldnamekey = 'TypeOfRevenueStamp'; - } - if ($fieldnamekey == 'use_default') { - $fieldnamekey = 'UseByDefault'; + if ($value == 'sortorder') { + continue; // For a column name 'sortorder', we use the field name 'position' } + if ((!GETPOSTISSET($value) || GETPOST($value) == '') + && (!in_array($value, array('decalage', 'module', 'accountancy_code', 'accountancy_code_sell', 'accountancy_code_buy', 'tracking', 'picto', 'deposit_percent')) // Fields that are not mandatory + && ($id != 10 || ($value != 'code' && $value != 'note')) // Field code and note is not mandatory for dictionary table 10 + ) + ) { + $ok = 0; + $fieldnamekey = $value; + // We take translate key of field + if ($fieldnamekey == 'libelle' || ($fieldnamekey == 'label')) { + $fieldnamekey = 'Label'; + } + if ($fieldnamekey == 'libelle_facture') { + $fieldnamekey = 'LabelOnDocuments'; + } + if ($fieldnamekey == 'deposit_percent') { + $fieldnamekey = 'DepositPercent'; + } + if ($fieldnamekey == 'nbjour') { + $fieldnamekey = 'NbOfDays'; + } + if ($fieldnamekey == 'decalage') { + $fieldnamekey = 'Offset'; + } + if ($fieldnamekey == 'module') { + $fieldnamekey = 'Module'; + } + if ($fieldnamekey == 'code') { + $fieldnamekey = 'Code'; + } + if ($fieldnamekey == 'note') { + $fieldnamekey = 'Note'; + } + if ($fieldnamekey == 'taux') { + $fieldnamekey = 'Rate'; + } + if ($fieldnamekey == 'type') { + $fieldnamekey = 'Type'; + } + if ($fieldnamekey == 'position') { + $fieldnamekey = 'Position'; + } + if ($fieldnamekey == 'unicode') { + $fieldnamekey = 'Unicode'; + } + if ($fieldnamekey == 'deductible') { + $fieldnamekey = 'Deductible'; + } + if ($fieldnamekey == 'sortorder') { + $fieldnamekey = 'SortOrder'; + } + if ($fieldnamekey == 'category_type') { + $fieldnamekey = 'Calculated'; + } + if ($fieldnamekey == 'revenuestamp_type') { + $fieldnamekey = 'TypeOfRevenueStamp'; + } + if ($fieldnamekey == 'use_default') { + $fieldnamekey = 'UseByDefault'; + } setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors'); + } } - } - // Other checks - if (GETPOST('actionadd') && $tabname[$id] == MAIN_DB_PREFIX."c_actioncomm" && GETPOSTISSET("type") && in_array(GETPOST("type"), array('system', 'systemauto'))) { - $ok = 0; - setEventMessages($langs->transnoentities('ErrorReservedTypeSystemSystemAuto'), null, 'errors'); - } - if (GETPOSTISSET("code")) { - if (GETPOST("code") == '0') { + // Other checks + if (GETPOST('actionadd') && $tabname[$id] == "c_actioncomm" && GETPOSTISSET("type") && in_array(GETPOST("type"), array('system', 'systemauto'))) { $ok = 0; - setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors'); + setEventMessages($langs->transnoentities('ErrorReservedTypeSystemSystemAuto'), null, 'errors'); } - /*if (!is_numeric($_POST['code'])) // disabled, code may not be in numeric base - { - $ok = 0; - $msg .= $langs->transnoentities('ErrorFieldFormat', $langs->transnoentities('Code')).'
'; - }*/ - } - if (GETPOSTISSET("country") && (GETPOST("country") == '0') && ($id != 2)) { - if (in_array($tablib[$id], array('DictionaryCompanyType', 'DictionaryHolidayTypes'))) { // Field country is no mandatory for such dictionaries - $_POST["country"] = ''; - } else { + if (GETPOSTISSET("code")) { + if (GETPOST("code") == '0') { + $ok = 0; + setEventMessages($langs->transnoentities('ErrorCodeCantContainZero'), null, 'errors'); + } + } + if (GETPOSTISSET("country") && (GETPOST("country") == '0') && ($id != 2)) { + if (in_array($tablib[$id], array('DictionaryCompanyType', 'DictionaryHolidayTypes'))) { // Field country is no mandatory for such dictionaries + $_POST["country"] = ''; + } else { + $ok = 0; + setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities("Country")), null, 'errors'); + } + } + if (($id == 3 || $id == 42) && !is_numeric(GETPOST("code"))) { $ok = 0; - setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities("Country")), null, 'errors'); + setEventMessages($langs->transnoentities("ErrorFieldMustBeANumeric", $langs->transnoentities("Code")), null, 'errors'); } - } - if (($id == 3 || $id == 42) && !is_numeric(GETPOST("code"))) { - $ok = 0; - setEventMessages($langs->transnoentities("ErrorFieldMustBeANumeric", $langs->transnoentities("Code")), null, 'errors'); - } - // Clean some parameters - if ((GETPOST("localtax1_type") || (GETPOST('localtax1_type') == '0')) && !GETPOST("localtax1")) { - $_POST["localtax1"] = '0'; // If empty, we force to 0 - } - if ((GETPOST("localtax2_type") || (GETPOST('localtax2_type') == '0')) && !GETPOST("localtax2")) { - $_POST["localtax2"] = '0'; // If empty, we force to 0 - } - if (GETPOST("accountancy_code") <= 0) { - $_POST["accountancy_code"] = ''; // If empty, we force to null - } - if (GETPOST("accountancy_code_sell") <= 0) { - $_POST["accountancy_code_sell"] = ''; // If empty, we force to null - } - if (GETPOST("accountancy_code_buy") <= 0) { - $_POST["accountancy_code_buy"] = ''; // If empty, we force to null - } - if ($id == 10 && GETPOSTISSET("code")) { // Spaces are not allowed into code for tax dictionary - $_POST["code"] = preg_replace('/[^a-zA-Z0-9\-\+]/', '', $_POST["code"]); - } + // Clean some parameters + if ((GETPOST("localtax1_type") || (GETPOST('localtax1_type') == '0')) && !GETPOST("localtax1")) { + $_POST["localtax1"] = '0'; // If empty, we force to 0 + } + if ((GETPOST("localtax2_type") || (GETPOST('localtax2_type') == '0')) && !GETPOST("localtax2")) { + $_POST["localtax2"] = '0'; // If empty, we force to 0 + } + if (GETPOST("accountancy_code") <= 0) { + $_POST["accountancy_code"] = ''; // If empty, we force to null + } + if (GETPOST("accountancy_code_sell") <= 0) { + $_POST["accountancy_code_sell"] = ''; // If empty, we force to null + } + if (GETPOST("accountancy_code_buy") <= 0) { + $_POST["accountancy_code_buy"] = ''; // If empty, we force to null + } + if ($id == 10 && GETPOSTISSET("code")) { // Spaces are not allowed into code for tax dictionary + $_POST["code"] = preg_replace('/[^a-zA-Z0-9\-\+]/', '', GETPOST("code")); + } - // If check ok and action add, add the line - if ($ok && GETPOST('actionadd')) { - if ($tabrowid[$id]) { - // Get free id for insert - $newid = 0; - $sql = "SELECT max(".$tabrowid[$id].") newid from ".$tabname[$id]; - $result = $db->query($sql); - if ($result) { - $obj = $db->fetch_object($result); - $newid = ($obj->newid + 1); + $tablename = $tabname[$id]; + $tablename = preg_replace('/^'.preg_quote(MAIN_DB_PREFIX, '/').'/', '', $tablename); + + // If check ok and action add, add the line + if ($ok && GETPOST('actionadd')) { + if ($tabrowid[$id]) { + // Get free id for insert + $newid = 0; + $sql = "SELECT MAX(".$tabrowid[$id].") as newid FROM ".MAIN_DB_PREFIX.$tablename; + $result = $db->query($sql); + if ($result) { + $obj = $db->fetch_object($result); + $newid = ($obj->newid + 1); + } else { + dol_print_error($db); + } + } + + // Add new entry + $sql = "INSERT INTO ".MAIN_DB_PREFIX.$tablename." ("; + // List of fields + if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) { + $sql .= $tabrowid[$id].","; + } + $sql .= $tabfieldinsert[$id]; + $sql .= ",active)"; + $sql .= " VALUES("; + + // List of values + if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) { + $sql .= $newid.","; + } + $i = 0; + foreach ($listfieldinsert as $f => $value) { + $keycode = $listfieldvalue[$i]; + if (empty($keycode)) { + $keycode = $value; + } + + if ($value == 'price' || preg_match('/^amount/i', $value)) { + $_POST[$keycode] = price2num(GETPOST($keycode), 'MU'); + } elseif ($value == 'taux' || $value == 'localtax1') { + $_POST[$keycode] = price2num(GETPOST($keycode), 8); // Note that localtax2 can be a list of rates separated by coma like X:Y:Z + } elseif ($value == 'entity') { + $_POST[$keycode] = getEntity($tablename); + } + + if ($i) { + $sql .= ","; + } + + if ($keycode == 'sortorder') { // For column name 'sortorder', we use the field name 'position' + $sql .= (int) GETPOST('position', 'int'); + } elseif (GETPOST($keycode) == '' && !($keycode == 'code' && $id == 10)) { + $sql .= "null"; // For vat, we want/accept code = '' + } elseif ($keycode == 'content') { + $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; + } elseif (in_array($keycode, array('joinfile', 'private', 'pos', 'position', 'scale', 'use_default'))) { + $sql .= (int) GETPOST($keycode, 'int'); + } else { + $sql .= "'".$db->escape(GETPOST($keycode, 'nohtml'))."'"; + } + + $i++; + } + $sql .= ",1)"; + + dol_syslog("actionadd", LOG_DEBUG); + $resql = $db->query($sql); + if ($resql) { // Add is ok + setEventMessages($langs->transnoentities("RecordCreatedSuccessfully"), null, 'mesgs'); + + // Clean $_POST array, we keep only id of dictionary + if ($id == 10 && GETPOST('country', 'int') > 0) { + $search_country_id = GETPOST('country', 'int'); + } + $_POST = array('id'=>$id); } else { - dol_print_error($db); + if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors'); + } else { + dol_print_error($db); + } } } - // Add new entry - $sql = "INSERT INTO ".$tabname[$id]." ("; - // List of fields - if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) { - $sql .= $tabrowid[$id].","; - } - $sql .= $tabfieldinsert[$id]; - $sql .= ",active)"; - $sql .= " VALUES("; - - // List of values - if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldinsert)) { - $sql .= $newid.","; - } - $i = 0; - foreach ($listfieldinsert as $f => $value) { - $keycode = $listfieldvalue[$i]; - if (empty($keycode)) { - $keycode = $value; - } - - if ($value == 'price' || preg_match('/^amount/i', $value)) { - $_POST[$keycode] = price2num(GETPOST($keycode), 'MU'); - } elseif ($value == 'taux' || $value == 'localtax1') { - $_POST[$keycode] = price2num(GETPOST($keycode), 8); // Note that localtax2 can be a list of rates separated by coma like X:Y:Z - } elseif ($value == 'entity') { - $_POST[$keycode] = getEntity($tabname[$id]); - } - - if ($i) { - $sql .= ","; - } - - if ($keycode == 'sortorder') { // For column name 'sortorder', we use the field name 'position' - $sql .= (int) GETPOST('position', 'int'); - } elseif ($_POST[$keycode] == '' && !($keycode == 'code' && $id == 10)) { - $sql .= "null"; // For vat, we want/accept code = '' - } elseif ($keycode == 'content') { - $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; - } elseif (in_array($keycode, array('joinfile', 'private', 'pos', 'position', 'scale', 'use_default'))) { - $sql .= (int) GETPOST($keycode, 'int'); + // If verif ok and action modify, modify the line + if ($ok && GETPOST('actionmodify')) { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; } else { - $sql .= "'".$db->escape(GETPOST($keycode, 'nohtml'))."'"; + $rowidcol = "rowid"; } - $i++; - } - $sql .= ",1)"; - - dol_syslog("actionadd", LOG_DEBUG); - $resql = $db->query($sql); - if ($resql) { // Add is ok - setEventMessages($langs->transnoentities("RecordCreatedSuccessfully"), null, 'mesgs'); - - // Clean $_POST array, we keep only id of dictionary - if ($id == 10 && GETPOST('country', 'int') > 0) { - $search_country_id = GETPOST('country', 'int'); + // Modify entry + $sql = "UPDATE ".MAIN_DB_PREFIX.$tablename." SET "; + // Modifie valeur des champs + if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldmodify)) { + $sql .= $tabrowid[$id]."="; + $sql .= "'".$db->escape($rowid)."', "; } - $_POST = array('id'=>$id); - } else { - if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { - setEventMessages($langs->transnoentities("ErrorRecordAlreadyExists"), null, 'errors'); + $i = 0; + foreach ($listfieldmodify as $field) { + $keycode = $listfieldvalue[$i]; + if (empty($keycode)) { + $keycode = $field; + } + + if ($field == 'price' || preg_match('/^amount/i', $field)) { + $_POST[$keycode] = price2num(GETPOST($keycode), 'MU'); + } elseif ($field == 'taux' || $field == 'localtax1') { + $_POST[$keycode] = price2num(GETPOST($keycode), 8); // Note that localtax2 can be a list of rates separated by coma like X:Y:Z + } elseif ($field == 'entity') { + $_POST[$keycode] = getEntity($tablename); + } + + if ($i) { + $sql .= ","; + } + $sql .= $field."="; + if ($listfieldvalue[$i] == 'sortorder') { // For column name 'sortorder', we use the field name 'position' + $sql .= (int) GETPOST('position', 'int'); + } elseif (GETPOST($keycode) == '' && !($keycode == 'code' && $id == 10)) { + $sql .= "null"; // For vat, we want/accept code = '' + } elseif ($keycode == 'content') { + $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; + } elseif (in_array($keycode, array('joinfile', 'private', 'pos', 'position', 'scale', 'use_default'))) { + $sql .= (int) GETPOST($keycode, 'int'); + } else { + $sql .= "'".$db->escape(GETPOST($keycode, 'nohtml'))."'"; + } + + $i++; + } + if (in_array($rowidcol, array('code', 'code_iso'))) { + $sql .= " WHERE ".$rowidcol." = '".$db->escape($rowid)."'"; } else { - dol_print_error($db); + $sql .= " WHERE ".$rowidcol." = ".((int) $rowid); + } + if (in_array('entity', $listfieldmodify)) { + $sql .= " AND entity = ".((int) getEntity($tablename, 0)); + } + + dol_syslog("actionmodify", LOG_DEBUG); + //print $sql; + $resql = $db->query($sql); + if (!$resql) { + setEventMessages($db->error(), null, 'errors'); } } } - // If verif ok and action modify, modify the line - if ($ok && GETPOST('actionmodify')) { + if ($action == 'confirm_delete' && $confirm == 'yes') { // delete if ($tabrowid[$id]) { $rowidcol = $tabrowid[$id]; } else { $rowidcol = "rowid"; } - // Modify entry - $sql = "UPDATE ".$tabname[$id]." SET "; - // Modifie valeur des champs - if ($tabrowid[$id] && !in_array($tabrowid[$id], $listfieldmodify)) { - $sql .= $tabrowid[$id]."="; - $sql .= "'".$db->escape($rowid)."', "; - } - $i = 0; - foreach ($listfieldmodify as $field) { - $keycode = $listfieldvalue[$i]; - if (empty($keycode)) { - $keycode = $field; - } + $tablename = $tabname[$id]; + $tablename = preg_replace('/^'.preg_quote(MAIN_DB_PREFIX, '/').'/', '', $tablename); - if ($field == 'price' || preg_match('/^amount/i', $field)) { - $_POST[$keycode] = price2num(GETPOST($keycode), 'MU'); - } elseif ($field == 'taux' || $field == 'localtax1') { - $_POST[$keycode] = price2num(GETPOST($keycode), 8); // Note that localtax2 can be a list of rates separated by coma like X:Y:Z - } elseif ($field == 'entity') { - $_POST[$keycode] = getEntity($tabname[$id]); - } + $sql = "DELETE FROM ".MAIN_DB_PREFIX.$tablename." WHERE ".$rowidcol." = '".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - if ($i) { - $sql .= ","; - } - $sql .= $field."="; - if ($listfieldvalue[$i] == 'sortorder') { // For column name 'sortorder', we use the field name 'position' - $sql .= (int) GETPOST('position', 'int'); - } elseif ($_POST[$keycode] == '' && !($keycode == 'code' && $id == 10)) { - $sql .= "null"; // For vat, we want/accept code = '' - } elseif ($keycode == 'content') { - $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; - } elseif (in_array($keycode, array('joinfile', 'private', 'pos', 'position', 'scale', 'use_default'))) { - $sql .= (int) GETPOST($keycode, 'int'); + dol_syslog("delete", LOG_DEBUG); + $result = $db->query($sql); + if (!$result) { + if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') { + setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors'); } else { - $sql .= "'".$db->escape(GETPOST($keycode, 'nohtml'))."'"; + dol_print_error($db); } - - $i++; - } - if (in_array($rowidcol, array('code', 'code_iso'))) { - $sql .= " WHERE ".$rowidcol." = '".$db->escape($rowid)."'"; - } else { - $sql .= " WHERE ".$rowidcol." = ".((int) $rowid); - } - if (in_array('entity', $listfieldmodify)) { - $sql .= " AND entity = ".((int) getEntity($tabname[$id], 0)); - } - - dol_syslog("actionmodify", LOG_DEBUG); - //print $sql; - $resql = $db->query($sql); - if (!$resql) { - setEventMessages($db->error(), null, 'errors'); } } - //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition -} -if (GETPOST('actioncancel')) { - //$_GET["id"]=GETPOST('id', 'int'); // Force affichage dictionnaire en cours d'edition -} + // activate + if ($action == $acts[0]) { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; + } else { + $rowidcol = "rowid"; + } -if ($action == 'confirm_delete' && $confirm == 'yes') { // delete - if ($tabrowid[$id]) { - $rowidcol = $tabrowid[$id]; - } else { - $rowidcol = "rowid"; + if ($rowid) { + $sql = "UPDATE ".MAIN_DB_PREFIX.$tabname[$id]." SET active = 1 WHERE ".$rowidcol." = '".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".MAIN_DB_PREFIX.$tabname[$id]." SET active = 1 WHERE code = '".$db->escape(dol_escape_htmltag($code))."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { + dol_print_error($db); + } } - $sql = "DELETE FROM ".$tabname[$id]." WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - - dol_syslog("delete", LOG_DEBUG); - $result = $db->query($sql); - if (!$result) { - if ($db->errno() == 'DB_ERROR_CHILD_EXISTS') { - setEventMessages($langs->transnoentities("ErrorRecordIsUsedByChild"), null, 'errors'); + // disable + if ($action == $acts[1]) { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; } else { + $rowidcol = "rowid"; + } + + if ($rowid) { + $sql = "UPDATE ".MAIN_DB_PREFIX.$tabname[$id]." SET active = 0 WHERE ".$rowidcol." = '".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".MAIN_DB_PREFIX.$tabname[$id]." SET active = 0 WHERE code = '".$db->escape(dol_escape_htmltag($code))."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { + dol_print_error($db); + } + } + + // favorite + if ($action == 'activate_favorite') { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; + } else { + $rowidcol = "rowid"; + } + + if ($rowid) { + $sql = "UPDATE ".MAIN_DB_PREFIX.$tabname[$id]." SET favorite = 1 WHERE ".$rowidcol." = '".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".MAIN_DB_PREFIX.$tabname[$id]." SET favorite = 1 WHERE code = '".$db->escape(dol_escape_htmltag($code))."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { + dol_print_error($db); + } + } + + // disable favorite + if ($action == 'disable_favorite') { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; + } else { + $rowidcol = "rowid"; + } + + if ($rowid) { + $sql = "UPDATE ".MAIN_DB_PREFIX.$tabname[$id]." SET favorite = 0 WHERE ".$rowidcol." = '".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".MAIN_DB_PREFIX.$tabname[$id]." SET favorite = 0 WHERE code = '".$db->escape(dol_escape_htmltag($code))."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { + dol_print_error($db); + } + } + + // Is in EEC - Activate + if ($action == 'activate_eec') { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; + } else { + $rowidcol = "rowid"; + } + + if ($rowid) { + $sql = "UPDATE ".MAIN_DB_PREFIX.$tabname[$id]." SET eec = 1 WHERE ".$rowidcol." = '".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".MAIN_DB_PREFIX.$tabname[$id]." SET eec = 1 WHERE code = '".$db->escape(dol_escape_htmltag($code))."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { + dol_print_error($db); + } + } + + // Is in EEC - Disable + if ($action == 'disable_eec') { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; + } else { + $rowidcol = "rowid"; + } + + if ($rowid) { + $sql = "UPDATE ".MAIN_DB_PREFIX.$tabname[$id]." SET eec = 0 WHERE ".$rowidcol." = '".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".MAIN_DB_PREFIX.$tabname[$id]." SET eec = 0 WHERE code = '".$db->escape(dol_escape_htmltag($code))."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { dol_print_error($db); } } } - -// activate -if ($action == $acts[0]) { - if ($tabrowid[$id]) { - $rowidcol = $tabrowid[$id]; - } else { - $rowidcol = "rowid"; - } - - if ($rowid) { - $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } elseif ($code) { - $sql = "UPDATE ".$tabname[$id]." SET active = 1 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } - - $result = $db->query($sql); - if (!$result) { - dol_print_error($db); - } -} - -// disable -if ($action == $acts[1]) { - if ($tabrowid[$id]) { - $rowidcol = $tabrowid[$id]; - } else { - $rowidcol = "rowid"; - } - - if ($rowid) { - $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } elseif ($code) { - $sql = "UPDATE ".$tabname[$id]." SET active = 0 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } - - $result = $db->query($sql); - if (!$result) { - dol_print_error($db); - } -} - -// favorite -if ($action == 'activate_favorite') { - if ($tabrowid[$id]) { - $rowidcol = $tabrowid[$id]; - } else { - $rowidcol = "rowid"; - } - - if ($rowid) { - $sql = "UPDATE ".$tabname[$id]." SET favorite = 1 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } elseif ($code) { - $sql = "UPDATE ".$tabname[$id]." SET favorite = 1 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } - - $result = $db->query($sql); - if (!$result) { - dol_print_error($db); - } -} - -// disable favorite -if ($action == 'disable_favorite') { - if ($tabrowid[$id]) { - $rowidcol = $tabrowid[$id]; - } else { - $rowidcol = "rowid"; - } - - if ($rowid) { - $sql = "UPDATE ".$tabname[$id]." SET favorite = 0 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } elseif ($code) { - $sql = "UPDATE ".$tabname[$id]." SET favorite = 0 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); - } - - $result = $db->query($sql); - if (!$result) { - dol_print_error($db); - } -} - - /* * View */ @@ -1155,7 +1208,7 @@ if ($action == 'delete') { /* * Show a dictionary */ -if ($id) { +if ($id > 0) { // Complete search values request with sort criteria $sql = $tabsql[$id]; @@ -1223,6 +1276,7 @@ if ($id) { print '
'; + print ''; $selectarray = array('-1'=>'', 'withoutsubscription'=>$langs->trans("WithoutSubscription"), 'uptodate'=>$langs->trans("UpToDate"), 'outofdate'=>$langs->trans("OutOfDate")); print $form->selectarray('search_filter', $selectarray, $search_filter); print ''; -$searchpicto = $form->showFilterButtons(); -print $searchpicto; -print ''; + print ''; + print ''; + $searchpicto = $form->showFilterButtons(); + print $searchpicto; + print '
'.$obj->rowid.''.$obj->rowid.''; if ($datefin) { - print ''; print dol_print_date($datefin, 'day'); if ($memberstatic->hasDelay()) { $textlate = ' ('.$langs->trans("DateReference").' > '.$langs->trans("DateToday").' '.(ceil($conf->adherent->subscription->warning_delay / 60 / 60 / 24) >= 0 ? '+' : '').ceil($conf->adherent->subscription->warning_delay / 60 / 60 / 24).' '.$langs->trans("days").')'; print " ".img_warning($langs->trans("SubscriptionLate").$textlate); } - print ''; if (!empty($obj->subscription)) { print $langs->trans("SubscriptionNotReceived"); if ($obj->statut > 0) { @@ -1128,8 +1154,8 @@ while ($i < min($num, $limit)) { } else { print ' '; } - print ''; - if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - $selected = 0; - if (in_array($obj->rowid, $arrayofselected)) { - $selected = 1; + if (!empty($arrayfields['d.import_key']['checked'])) { + print ''; + print dol_escape_htmltag($obj->import_key); + print "'; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($obj->rowid, $arrayofselected)) { + $selected = 1; + } + print ''; + } + print '
'; if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined $selected = 0; - if (in_array($obj->rowid, $arrayofselected)) { + if (in_array($obj->crowid, $arrayofselected)) { $selected = 1; } - print ''; + print ''; } print '
'.$langs->trans("Label").'
'.$langs->trans("Status").''; - print $form->selectarray('status', array('0'=>$langs->trans('ActivityCeased'), '1'=>$langs->trans('InActivity')), 1); + print $form->selectarray('status', array('0'=>$langs->trans('ActivityCeased'), '1'=>$langs->trans('InActivity')), 1, 0, 0, 0, '', 0, 0, 0, '', 'minwidth100'); print '
'.$langs->trans("Amount").''; - print ''; + print ''; print '
'.$langs->trans("VoteAllowed").''; @@ -389,12 +391,12 @@ if ($action == 'create') { print '
'.$langs->trans("Description").''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('comment', $object->note, '', 200, 'dolibarr_notes', '', false, true, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, 15, '90%'); + $doleditor = new DolEditor('comment', (GETPOSTISSET('comment') ? GETPOST('comment', 'restricthtml') : $object->note_public), '', 200, 'dolibarr_notes', '', false, true, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, 15, '90%'); $doleditor->Create(); print '
'.$langs->trans("WelcomeEMail").''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('mail_valid', $object->mail_valid, '', 250, 'dolibarr_notes', '', false, true, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, 15, '90%'); + $doleditor = new DolEditor('mail_valid', GETPOSTISSET('mail_valid') ? GETPOST('mail_valid') : $object->mail_valid, '', 250, 'dolibarr_notes', '', false, true, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, 15, '90%'); $doleditor->Create(); print '
'.$langs->trans("Label").'
'.$langs->trans("Status").''; - print $form->selectarray('status', array('0'=>$langs->trans('ActivityCeased'), '1'=>$langs->trans('InActivity')), $object->status); + print $form->selectarray('status', array('0'=>$langs->trans('ActivityCeased'), '1'=>$langs->trans('InActivity')), $object->status, 0, 0, 0, '', 0, 0, 0, '', 'minwidth100'); print '
'.$trigger['code'].''.$trigger['label'].''."\n"; - print ''; + print ''; print img_picto($langs->trans("Enabled"), 'switch_on'); print ''; print ''."\n"; - print ''.img_picto($langs->trans("Disabled"), 'switch_off').''; + print ''.img_picto($langs->trans("Disabled"), 'switch_off').''; print "'."\n"; - print ''; + print ''; print img_picto($langs->trans("Enabled"), 'switch_on'); print ''; print ''."\n"; - print ''.img_picto($langs->trans("Disabled"), 'switch_off').''; + print ''.img_picto($langs->trans("Disabled"), 'switch_off').''; print "'; @@ -628,7 +631,7 @@ print "'; print $form->textwithpicto($langs->trans("WatermarkOnDraftOrders"), $htmltext, 1, 'help', '', 0, 2, 'watermarktooltip').'
'; print '
'; -print ''; +print ''; print ''; print ''; print "
'; +print '
'; print '
'; +print '
'; print '
'; // Line for title + print ''; $tdsoffields = ''; foreach ($fieldlist as $field => $value) { if ($value == 'entity') { @@ -1245,7 +1299,7 @@ if ($id) { $valuetoshow = $langs->trans("PriceUHT"); } if ($value == 'taux') { - if ($tabname[$id] != MAIN_DB_PREFIX."c_revenuestamp") { + if ($tabname[$id] != "c_revenuestamp") { $valuetoshow = $langs->trans("Rate"); } else { $valuetoshow = $langs->trans("Amount"); @@ -1271,7 +1325,7 @@ if ($id) { $valuetoshow = $langs->trans("Language"); } if ($value == 'type') { - if ($tabname[$id] == MAIN_DB_PREFIX."c_paiement") { + if ($tabname[$id] == "c_paiement") { $valuetoshow = $form->textwithtooltip($langs->trans("Type"), $langs->trans("TypePaymentDesc"), 2, 1, img_help(1, '')); } else { $valuetoshow = $langs->trans("Type"); @@ -1286,6 +1340,10 @@ if ($id) { if ($value == 'libelle_facture') { $valuetoshow = $form->textwithtooltip($langs->trans("LabelOnDocuments"), $langs->trans("LabelUsedByDefault"), 2, 1, img_help(1, '')); } + if ($value == 'deposit_percent') { + $valuetoshow = $langs->trans('DepositPercent'); + $class = 'right'; + } if ($value == 'country') { if (in_array('region_id', $fieldlist)) { print ''; continue; @@ -1297,12 +1355,14 @@ if ($id) { } if ($value == 'nbjour') { $valuetoshow = $langs->trans("NbOfDays"); + $class = 'right'; } if ($value == 'type_cdr') { $valuetoshow = $langs->trans("AtEndOfMonth"); $class = "center"; } if ($value == 'decalage') { $valuetoshow = $langs->trans("Offset"); + $class = 'right'; } if ($value == 'width' || $value == 'nx') { $valuetoshow = $langs->trans("Width"); @@ -1339,6 +1399,7 @@ if ($id) { } if ($value == 'sortorder') { $valuetoshow = $langs->trans("SortOrder"); + $class = 'center'; } if ($value == 'short_label') { $valuetoshow = $langs->trans("ShortLabel"); @@ -1418,6 +1479,12 @@ if ($id) { if ($value == 'public' && $tablib[$id] == 'TicketDictCategory') { $valuetoshow = $langs->trans('TicketGroupIsPublic'); $class = 'center'; } + if ($value == 'block_if_negative') { + $valuetoshow = $langs->trans('BlockHolidayIfNegative'); + } + if ($value == 'type_duration') { + $valuetoshow = $langs->trans('Unit'); + } if ($id == 2) { // Special case for state page if ($value == 'region_id') { @@ -1429,36 +1496,39 @@ if ($id) { } if ($valuetoshow != '') { - $tdsoffields .= ''; - if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { - $tdsoffields .= ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; - } elseif (!empty($tabhelp[$id][$value])) { - $tdsoffields .= $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]); + $tooltiphelp = (isset($tabcomplete[$tabname[$id]]['help'][$value]) ? $tabcomplete[$tabname[$id]]['help'][$value] : ''); + + $tdsoffields .= ''; + if ($tooltiphelp && preg_match('/^http(s*):/i', $tooltiphelp)) { + $tdsoffields .= ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; + } elseif ($tooltiphelp) { + $tdsoffields .= $form->textwithpicto($valuetoshow, $tooltiphelp); } else { $tdsoffields .= $valuetoshow; } - $tdsoffields .= ''; + $tdsoffields .= ''; } } if ($id == 4) { - $tdsoffields .= ''; + $tdsoffields .= ''; + $tdsoffields .= ''; } - $tdsoffields .= ''; - $tdsoffields .= ''; + $tdsoffields .= ''; + $tdsoffields .= ''; + $tdsoffields .= ''; $tdsoffields .= ''; print $tdsoffields; // Line to enter new values - print ''; + print ''; print ''; $obj = new stdClass(); @@ -1487,6 +1557,7 @@ if ($id) { if ($id == 4) { print ''; + print ''; } print ''; - print ''; - print ''; - print ''; -} - - -/** - * Print a form part - * - * @param string $confkey the conf key - * @param bool $title Title of conf - * @param string $desc Description of - * @param array $metas html meta - * @param string $type type of input textarea or input - * @param bool $help help description - * - * @return void - */ -function _printInputFormPart($confkey, $title = false, $desc = '', $metas = array(), $type = 'input', $help = false) -{ - global $langs, $conf, $db, $inputCount; - - $inputCount = empty($inputCount) ? 1 : ($inputCount + 1); - $form = new Form($db); - - $defaultMetas = array( - 'name' => 'value'.$inputCount - ); - - if ($type != 'textarea') { - $defaultMetas['type'] = 'text'; - $defaultMetas['value'] = $conf->global->{$confkey}; - } - - - $metas = array_merge($defaultMetas, $metas); - $metascompil = ''; - foreach ($metas as $key => $values) { - $metascompil .= ' '.$key.'="'.$values.'" '; - } - - print ''; - print ''; - print ''; - print ''; -} diff --git a/htdocs/admin/fichinter.php b/htdocs/admin/fichinter.php index 4369bb9a2a7..c95f354a189 100644 --- a/htdocs/admin/fichinter.php +++ b/htdocs/admin/fichinter.php @@ -43,6 +43,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'ficheinter'; diff --git a/htdocs/admin/holiday.php b/htdocs/admin/holiday.php index bfd7e22c461..7b0aa577a87 100644 --- a/htdocs/admin/holiday.php +++ b/htdocs/admin/holiday.php @@ -39,6 +39,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'contract'; @@ -440,23 +442,23 @@ print ''; print ''; print "\n"; -/*var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_MONDAY); -var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_FRIDAY); -var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY); -var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY); -*/ +//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_MONDAY); +//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_FRIDAY); +//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY); +//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY); + if (!isset($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY)) { $conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY = 1; } if (!isset($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY)) { $conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY = 1; } -/* -var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_MONDAY); -var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_FRIDAY); -var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY); -var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY); -*/ + +//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_MONDAY); +//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_FRIDAY); +//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SATURDAY); +//var_dump($conf->global->MAIN_NON_WORKING_DAYS_INCLUDE_SUNDAY); + // Set working days print ''; diff --git a/htdocs/admin/holiday_extrafields.php b/htdocs/admin/holiday_extrafields.php index 609187058e3..0ef1998d9e7 100644 --- a/htdocs/admin/holiday_extrafields.php +++ b/htdocs/admin/holiday_extrafields.php @@ -85,7 +85,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/hrm.php b/htdocs/admin/hrm.php index 1ad84ce19ac..f5bbb5c648f 100644 --- a/htdocs/admin/hrm.php +++ b/htdocs/admin/hrm.php @@ -50,6 +50,8 @@ $backtopage = GETPOST('backtopage', 'alpha'); $value = GETPOST('value', 'alpha'); $label = GETPOST('label', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $scandir = GETPOST('scan_dir', 'alpha'); $type = 'myobject'; @@ -277,7 +279,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print ''; print ''; } } - print ''; print ''; $obj = new stdClass(); @@ -742,7 +796,7 @@ if ($action == 'add') { $fieldsforcontent = array('topic', 'joinfiles', 'content', 'content_lines'); } foreach ($fieldsforcontent as $tmpfieldlist) { - print ''; - if ($tmpfieldlist == 'topic') { - print ''; - } - // else print ''; print ''; } print '
 '; + $tdsoffields .= ''; $tdsoffields .= ''; if (!is_null($withentity)) { $tdsoffields .= ''; } - $tdsoffields .= ''; - $tdsoffields .= '
'; if ($action != 'edit') { @@ -1528,6 +1599,7 @@ if ($id) { print ''; // Title line with search input fields + print ''."\n"; print ''; $filterfound = 0; foreach ($fieldlist as $field => $value) { @@ -1560,6 +1632,7 @@ if ($id) { } if ($id == 4) { print ''; + print ''; } print ''; print ''; // Title of lines + print ''."\n"; print ''; foreach ($fieldlist as $field => $value) { if ($value == 'entity') { continue; } - if (in_array($value, array('label', 'libelle', 'libelle_facture')) && empty($tabhelp[$id][$value])) { - $tabhelp[$id][$value] = $langs->trans('LabelUsedByDefault'); + if (in_array($value, array('label', 'libelle', 'libelle_facture')) && empty($tabcomplete[$tabname[$id]]['help'][$value])) { + $tabcomplete[$tabname[$id]]['help'][$value] = $langs->trans('LabelUsedByDefault'); } // Determines the name of the field in relation to the possible names // in data dictionaries - $showfield = 1; // By defaut + $showfield = 1; // By default $cssprefix = ''; $sortable = 1; - $valuetoshow = ucfirst($value); // By defaut + $valuetoshow = ucfirst($value); // By default $valuetoshow = $langs->trans($valuetoshow); // try to translate // Special cases @@ -1597,7 +1671,7 @@ if ($id) { $valuetoshow = $langs->trans("PriceUHT"); } if ($value == 'taux') { - if ($tabname[$id] != MAIN_DB_PREFIX."c_revenuestamp") { + if ($tabname[$id] != "c_revenuestamp") { $valuetoshow = $langs->trans("Rate"); } else { $valuetoshow = $langs->trans("Amount"); @@ -1638,6 +1712,10 @@ if ($id) { if ($value == 'libelle_facture') { $valuetoshow = $langs->trans("LabelOnDocuments"); } + if ($value == 'deposit_percent') { + $valuetoshow = $langs->trans('DepositPercent'); + $cssprefix = 'right '; + } if ($value == 'country') { $valuetoshow = $langs->trans("Country"); } @@ -1646,12 +1724,14 @@ if ($id) { } if ($value == 'nbjour') { $valuetoshow = $langs->trans("NbOfDays"); + $cssprefix = 'right '; } if ($value == 'type_cdr') { $valuetoshow = $langs->trans("AtEndOfMonth"); $cssprefix = "center "; } if ($value == 'decalage') { $valuetoshow = $langs->trans("Offset"); + $cssprefix = 'right '; } if ($value == 'width' || $value == 'nx') { $valuetoshow = $langs->trans("Width"); @@ -1685,6 +1765,7 @@ if ($id) { } if ($value == 'sortorder') { $valuetoshow = $langs->trans("SortOrder"); + $cssprefix = 'center '; } if ($value == 'short_label') { $valuetoshow = $langs->trans("ShortLabel"); @@ -1764,6 +1845,12 @@ if ($id) { if ($value == 'public' && $tablib[$id] == 'TicketDictCategory') { $valuetoshow = $langs->trans('TicketGroupIsPublic'); $cssprefix = 'center '; } + if ($value == 'block_if_negative') { + $valuetoshow = $langs->trans('BlockHolidayIfNegative'); + } + if ($value == 'type_duration') { + $valuetoshow = $langs->trans('Unit'); + } if ($value == 'region_id' || $value == 'country_id') { $showfield = 0; @@ -1771,10 +1858,12 @@ if ($id) { // Show field title if ($showfield) { - if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { - $newvaluetoshow = ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; - } elseif (!empty($tabhelp[$id][$value])) { - $newvaluetoshow = $form->textwithpicto($valuetoshow, $tabhelp[$id][$value]); + $tooltiphelp = (isset($tabcomplete[$tabname[$id]]['help'][$value]) ? $tabcomplete[$tabname[$id]]['help'][$value] : ''); + + if ($tooltiphelp && preg_match('/^http(s*):/i', $tooltiphelp)) { + $newvaluetoshow = ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; + } elseif ($tooltiphelp) { + $newvaluetoshow = $form->textwithpicto($valuetoshow, $tooltiphelp); } else { $newvaluetoshow = $valuetoshow; } @@ -1782,8 +1871,9 @@ if ($id) { print getTitleFieldOfList($newvaluetoshow, 0, $_SERVER["PHP_SELF"], ($sortable ? $value : ''), ($page ? 'page='.$page.'&' : ''), $param, '', $sortfield, $sortorder, $cssprefix); } } - // Favorite - Only activated on country dictionary + // Favorite & EEC - Only activated on country dictionary if ($id == 4) { + print getTitleFieldOfList($langs->trans("InEEC"), 0, $_SERVER["PHP_SELF"], "eec", ($page ? 'page='.$page.'&' : ''), $param, 'align="center"', $sortfield, $sortorder, '', 0, $langs->trans("CountryIsInEEC")); print getTitleFieldOfList($langs->trans("Favorite"), 0, $_SERVER["PHP_SELF"], "favorite", ($page ? 'page='.$page.'&' : ''), $param, 'align="center"', $sortfield, $sortorder); } @@ -1876,58 +1966,58 @@ if ($id) { $key = $langs->trans("PaymentCondition".strtoupper($obj->code)); $valuetoshow = ($obj->code && $key != "PaymentCondition".strtoupper($obj->code) ? $key : $obj->{$value}); $valuetoshow = nl2br($valuetoshow); - } elseif ($value == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_country') { + } elseif ($value == 'label' && $tabname[$id] == 'c_country') { $key = $langs->trans("Country".strtoupper($obj->code)); $valuetoshow = ($obj->code && $key != "Country".strtoupper($obj->code) ? $key : $obj->{$value}); - } elseif ($value == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_availability') { + } elseif ($value == 'label' && $tabname[$id] == 'c_availability') { $langs->load("propal"); $key = $langs->trans("AvailabilityType".strtoupper($obj->code)); $valuetoshow = ($obj->code && $key != "AvailabilityType".strtoupper($obj->code) ? $key : $obj->{$value}); - } elseif ($value == 'libelle' && $tabname[$id] == MAIN_DB_PREFIX.'c_actioncomm') { + } elseif ($value == 'libelle' && $tabname[$id] == 'c_actioncomm') { $key = $langs->trans("Action".strtoupper($obj->code)); $valuetoshow = ($obj->code && $key != "Action".strtoupper($obj->code) ? $key : $obj->{$value}); - } elseif (!empty($obj->code_iso) && $value == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_currencies') { + } elseif (!empty($obj->code_iso) && $value == 'label' && $tabname[$id] == 'c_currencies') { $key = $langs->trans("Currency".strtoupper($obj->code_iso)); $valuetoshow = ($obj->code_iso && $key != "Currency".strtoupper($obj->code_iso) ? $key : $obj->{$value}); - } elseif ($value == 'libelle' && $tabname[$id] == MAIN_DB_PREFIX.'c_typent') { + } elseif ($value == 'libelle' && $tabname[$id] == 'c_typent') { $key = $langs->trans(strtoupper($obj->code)); $valuetoshow = ($key != strtoupper($obj->code) ? $key : $obj->{$value}); - } elseif ($value == 'libelle' && $tabname[$id] == MAIN_DB_PREFIX.'c_prospectlevel') { + } elseif ($value == 'libelle' && $tabname[$id] == 'c_prospectlevel') { $key = $langs->trans(strtoupper($obj->code)); $valuetoshow = ($key != strtoupper($obj->code) ? $key : $obj->{$value}); - } elseif ($value == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_civility') { + } elseif ($value == 'label' && $tabname[$id] == 'c_civility') { $key = $langs->trans("Civility".strtoupper($obj->code)); $valuetoshow = ($obj->code && $key != "Civility".strtoupper($obj->code) ? $key : $obj->{$value}); - } elseif ($value == 'libelle' && $tabname[$id] == MAIN_DB_PREFIX.'c_type_contact') { + } elseif ($value == 'libelle' && $tabname[$id] == 'c_type_contact') { $langs->load('agenda'); $key = $langs->trans("TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code)); $valuetoshow = ($obj->code && $key != "TypeContact_".$obj->element."_".$obj->source."_".strtoupper($obj->code) ? $key : $obj->{$value}); - } elseif ($value == 'libelle' && $tabname[$id] == MAIN_DB_PREFIX.'c_payment_term') { + } elseif ($value == 'libelle' && $tabname[$id] == 'c_payment_term') { $langs->load("bills"); $key = $langs->trans("PaymentConditionShort".strtoupper($obj->code)); $valuetoshow = ($obj->code && $key != "PaymentConditionShort".strtoupper($obj->code) ? $key : $obj->{$value}); - } elseif ($value == 'libelle' && $tabname[$id] == MAIN_DB_PREFIX.'c_paiement') { + } elseif ($value == 'libelle' && $tabname[$id] == 'c_paiement') { $langs->load("bills"); $key = $langs->trans("PaymentType".strtoupper($obj->code)); $valuetoshow = ($obj->code && $key != "PaymentType".strtoupper($obj->code) ? $key : $obj->{$value}); - } elseif ($value == 'type' && $tabname[$id] == MAIN_DB_PREFIX.'c_paiement') { + } elseif ($value == 'type' && $tabname[$id] == 'c_paiement') { $payment_type_list = array(0=>$langs->trans('PaymentTypeCustomer'), 1=>$langs->trans('PaymentTypeSupplier'), 2=>$langs->trans('PaymentTypeBoth')); $valuetoshow = $payment_type_list[$valuetoshow]; - } elseif ($value == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_input_reason') { + } elseif ($value == 'label' && $tabname[$id] == 'c_input_reason') { $key = $langs->trans("DemandReasonType".strtoupper($obj->code)); $valuetoshow = ($obj->code && $key != "DemandReasonType".strtoupper($obj->code) ? $key : $obj->{$value}); - } elseif ($value == 'libelle' && $tabname[$id] == MAIN_DB_PREFIX.'c_input_method') { + } elseif ($value == 'libelle' && $tabname[$id] == 'c_input_method') { $langs->load("orders"); $key = $langs->trans($obj->code); $valuetoshow = ($obj->code && $key != $obj->code) ? $key : $obj->{$value}; - } elseif ($value == 'libelle' && $tabname[$id] == MAIN_DB_PREFIX.'c_shipment_mode') { + } elseif ($value == 'libelle' && $tabname[$id] == 'c_shipment_mode') { $langs->load("sendings"); $key = $langs->trans("SendingMethod".strtoupper($obj->code)); $valuetoshow = ($obj->code && $key != "SendingMethod".strtoupper($obj->code) ? $key : $obj->{$value}); - } elseif ($value == 'libelle' && $tabname[$id] == MAIN_DB_PREFIX.'c_paper_format') { + } elseif ($value == 'libelle' && $tabname[$id] == 'c_paper_format') { $key = $langs->trans('PaperFormat'.strtoupper($obj->code)); $valuetoshow = ($obj->code && $key != 'PaperFormat'.strtoupper($obj->code) ? $key : $obj->{$value}); - } elseif ($value == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_type_fees') { + } elseif ($value == 'label' && $tabname[$id] == 'c_type_fees') { $langs->load('trips'); $key = $langs->trans(strtoupper($obj->code)); $valuetoshow = ($obj->code && $key != strtoupper($obj->code) ? $key : $obj->{$value}); @@ -1935,13 +2025,13 @@ if ($id) { $showfield = 0; } elseif ($value == 'unicode') { $valuetoshow = $langs->getCurrencySymbol($obj->code, 1); - } elseif ($value == 'label' && $tabname[GETPOST("id", 'int')] == MAIN_DB_PREFIX.'c_units') { + } elseif ($value == 'label' && $tabname[GETPOST("id", 'int')] == 'c_units') { $langs->load("products"); $valuetoshow = $langs->trans($obj->{$value}); - } elseif ($value == 'short_label' && $tabname[GETPOST("id", 'int')] == MAIN_DB_PREFIX.'c_units') { + } elseif ($value == 'short_label' && $tabname[GETPOST("id", 'int')] == 'c_units') { $langs->load("products"); $valuetoshow = $langs->trans($obj->{$value}); - } elseif (($value == 'unit') && ($tabname[$id] == MAIN_DB_PREFIX.'c_paper_format')) { + } elseif (($value == 'unit') && ($tabname[$id] == 'c_paper_format')) { $key = $langs->trans('SizeUnit'.strtolower($obj->unit)); $valuetoshow = ($obj->code && $key != 'SizeUnit'.strtolower($obj->unit) ? $key : $obj->{$value}); } elseif ($value == 'localtax1' || $value == 'localtax2') { @@ -1981,22 +2071,28 @@ if ($id) { } } } elseif ($value == 'fk_c_exp_tax_cat') { - $valuetoshow = getDictionaryValue(MAIN_DB_PREFIX.'c_exp_tax_cat', 'label', $valuetoshow); + $tmpid = $valuetoshow; + $valuetoshow = getDictionaryValue('c_exp_tax_cat', 'label', $tmpid); + $valuetoshow = $langs->trans($valuetoshow ? $valuetoshow : $tmpid); + } elseif ($tabname[$id] == 'c_exp_tax_cat') { $valuetoshow = $langs->trans($valuetoshow); - } elseif ($tabname[$id] == MAIN_DB_PREFIX.'c_exp_tax_cat') { - $valuetoshow = $langs->trans($valuetoshow); - } elseif ($value == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_units') { + } elseif ($value == 'label' && $tabname[$id] == 'c_units') { $langs->load('other'); $key = $langs->trans($obj->label); $valuetoshow = ($obj->label && $key != strtoupper($obj->label) ? $key : $obj->{$value}); } elseif ($value == 'code' && $id == 3) { $valuetoshow = $obj->state_code; - } elseif ($value == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_product_nature') { + } elseif ($value == 'label' && $tabname[$id] == 'c_product_nature') { $langs->load("products"); $valuetoshow = $langs->trans($obj->{$value}); - } elseif ($fieldlist[$field] == 'label' && $tabname[$id] == MAIN_DB_PREFIX.'c_productbatch_qcstatus') { + } elseif ($fieldlist[$field] == 'label' && $tabname[$id] == 'c_productbatch_qcstatus') { $langs->load("productbatch"); $valuetoshow = $langs->trans($obj->{$value}); + } elseif ($value == 'block_if_negative') { + $valuetoshow = yn($obj->{$value}); + } elseif ($value == 'type_duration') { + $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')); + $valuetoshow =$TDurationTypes[$obj->{$value}]; } $class .= ($class ? ' ' : '').'tddict'; if ($value == 'note' && $id == 10) { @@ -2005,13 +2101,13 @@ if ($id) { if ($value == 'tracking') { $class .= ' tdoverflowauto'; } - if (in_array($value, array('pos', 'position'))) { + if (in_array($value, array('nbjour', 'decalage', 'pos', 'position', 'deposit_percent'))) { $class .= ' right'; } if (in_array($value, array('localtax1_type', 'localtax2_type'))) { $class .= ' nowrap'; } - if (in_array($value, array('use_default', 'fk_parent'))) { + if (in_array($value, array('use_default', 'fk_parent', 'sortorder'))) { $class .= ' center'; } if ($value == 'public') { @@ -2055,7 +2151,7 @@ if ($id) { if (!empty($obj->code) && $obj->code == 'RECEP') { $canbemodified = 1; } - if ($tabname[$id] == MAIN_DB_PREFIX."c_actioncomm") { + if ($tabname[$id] == "c_actioncomm") { $canbemodified = 1; } @@ -2074,14 +2170,23 @@ if ($id) { } $url .= '&'; - // Favorite + // Favorite & EEC // Only activated on country dictionary if ($id == 4) { print ''; + print ''; } @@ -2098,7 +2203,7 @@ if ($id) { } elseif (isset($obj->type) && in_array($obj->type, array('system')) && !empty($obj->active) && $obj->code != 'AC_OTH') { print $langs->trans("UsedOnlyWithTypeOption"); } else { - print $langs->trans("AlwaysActive"); + print ''.$langs->trans("AlwaysActive").''; } } print ""; @@ -2182,7 +2287,7 @@ if ($id) { print ''; print ''; print ''; print ''; $lastlineisempty = false; @@ -2232,7 +2337,7 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') continue; } - if (in_array($value, array('code', 'libelle', 'type')) && $tabname == MAIN_DB_PREFIX."c_actioncomm" && in_array($obj->type, array('system', 'systemauto'))) { + if (in_array($value, array('code', 'libelle', 'type')) && $tabname == "c_actioncomm" && in_array($obj->type, array('system', 'systemauto'))) { $hidden = (!empty($obj->{$value}) ? $obj->{$value}:''); print ''; - } elseif ($value == 'element') { - // The type of the element (for contact types) + } elseif (in_array($value, array('element', 'source'))) { //Example: the type and source of the element (for contact types) print ''; - } elseif ($value == 'source') { - // The source of the element (for contact types) - print ''; } elseif (in_array($value, array('public', 'use_default'))) { // Fields 0/1 with a combo select Yes/No @@ -2288,12 +2387,12 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') print ''; - } elseif ($value == 'type' && $tabname == MAIN_DB_PREFIX."c_actioncomm") { + } elseif ($value == 'type' && $tabname == "c_actioncomm") { $type = (!empty($obj->type) ? $obj->type : 'user'); // Check if type is different of 'user' (external module) print ''; - } elseif ($value == 'type' && $tabname == MAIN_DB_PREFIX.'c_paiement') { + } elseif ($value == 'type' && $tabname == 'c_paiement') { print ''; } elseif (in_array($value, array('nbjour', 'decalage', 'taux', 'localtax1', 'localtax2'))) { - $class = "left"; + $class = "right"; if (in_array($value, array('taux', 'localtax1', 'localtax2'))) { $class = "center"; // Fields aligned on right } @@ -2323,7 +2422,7 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') $transfound = 0; $transkey = ''; // Special case for labels - if ($tabname == MAIN_DB_PREFIX.'c_payment_term') { + if ($tabname == 'c_payment_term') { $langs->load("bills"); $transkey = "PaymentCondition".strtoupper($obj->code); if ($langs->trans($transkey) != $transkey) { @@ -2379,20 +2478,31 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') print ''; + } elseif ($value == 'block_if_negative') { + print ''; + } elseif ($value == 'type_duration') { + print ''; } else { $fieldValue = isset($obj->{$value}) ? $obj->{$value}: ''; + $classtd = ''; $class = ''; if ($value == 'sortorder') { $fieldlist[$field] = 'position'; } - $classtd = ''; $class = ''; if ($fieldlist[$field] == 'code') { $class = 'maxwidth100'; } - if (in_array($fieldlist[$field], array('pos', 'position'))) { + if (in_array($fieldlist[$field], array('deposit_percent'))) { $classtd = 'right'; $class = 'maxwidth50 right'; } + if (in_array($fieldlist[$field], array('pos', 'position'))) { + $classtd = 'center'; $class = 'maxwidth50 center'; + } if (in_array($fieldlist[$field], array('dayrule', 'day', 'month', 'year', 'use_default', 'affect', 'delay', 'public', 'sortorder', 'sens', 'category_type', 'fk_parent'))) { $class = 'maxwidth50 center'; } @@ -2408,15 +2518,40 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') $fieldValue = '0'; } } + + // Labels Length + $maxlength = ''; + if (in_array($fieldlist[$field], array('libelle', 'label'))) { + switch ($tabname) { + case 'c_accounting_category': + case 'c_ecotaxe': + case 'c_email_senderprofile': + case 'c_forme_juridique': + case 'c_holiday_types': + case 'c_payment_term': + case 'c_transport_mode': + $maxlength = ' maxlength="255"'; + break; + case 'c_email_templates': + $maxlength = ' maxlength="180"'; + break; + case 'c_socialnetworks': + $maxlength = ' maxlength="150"'; + break; + default: + $maxlength = ' maxlength="128"'; + } + } + print '\n"; print ''; + +print ''; +print ''; + print ''; + print '
'; @@ -1571,22 +1644,23 @@ if ($id) { print '
'; + // Is in EEC + if ($iserasable) { + print ''.$actl[$obj->eec].''; + } else { + print ''.$langs->trans("AlwaysActive").''; + } + print ''; + // Favorite if ($iserasable) { print ''.$actl[$obj->favorite].''; } else { - print $langs->trans("AlwaysActive"); + print ''.$langs->trans("AlwaysActive").''; } print ''; - print $form->textwithpicto('', $langs->trans("Table").': '.$tabname[$i]); + print $form->textwithpicto('', $langs->trans("Table").': '.MAIN_DB_PREFIX.$tabname[$i]); print '
'; print ''; @@ -2268,15 +2373,9 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') print ''; print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'lang'); print ''; - print $form->selectarray('element', $elementList, (!empty($obj->{$value}) ? $obj->{$value}:'')); - print ''; - print $form->selectarray('source', $sourceList, (!empty($obj->{$value}) ? $obj->{$value}:'')); + print $form->selectarray($value, $elementList, (!empty($obj->{$value}) ? $obj->{$value}:'')); print ''; print $form->selectyesno("private", (!empty($obj->{$value}) ? $obj->{$value}:'')); print ''; print $type.''; print ''; $select_list = array(0=>$langs->trans('PaymentTypeCustomer'), 1=>$langs->trans('PaymentTypeSupplier'), 2=>$langs->trans('PaymentTypeBoth')); print $form->selectarray($value, $select_list, (!empty($obj->{$value}) ? $obj->{$value}:'2')); @@ -2311,7 +2410,7 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') } print ''; print $form->selectExpenseRanges($obj->fk_range); print ''; + print $form->selectyesno("block_if_negative", (!empty($obj->{$value}) ? $obj->{$value}:''), 1); + print ''; + print $form->selectTypeDuration('', $obj->{$value}, array('i','h')); + print ''; $transfound = 0; $transkey = ''; if (in_array($fieldlist[$field], array('label', 'libelle'))) { // For label // Special case for labels - if ($tabname == MAIN_DB_PREFIX.'c_civility' && !empty($obj->code)) { + if ($tabname == 'c_civility' && !empty($obj->code)) { $transkey = "Civility".strtoupper($obj->code); } - if ($tabname == MAIN_DB_PREFIX.'c_payment_term' && !empty($obj->code)) { + if ($tabname == 'c_payment_term' && !empty($obj->code)) { $langs->load("bills"); $transkey = "PaymentConditionShort".strtoupper($obj->code); } @@ -2426,7 +2561,7 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') } } if (!$transfound) { - print ''; + print ''; } else { print ''; } diff --git a/htdocs/admin/dolistore/ajax/image.php b/htdocs/admin/dolistore/ajax/image.php index af844edaa68..e601da43e06 100644 --- a/htdocs/admin/dolistore/ajax/image.php +++ b/htdocs/admin/dolistore/ajax/image.php @@ -1,7 +1,7 @@ . * Copyright (C) 2008-2011 Laurent Destailleur - * Copyright (C) 2020 Frédéric France + * Copyright (C) 2020 Frédéric France * * This program is free software; you can redistribute it and/or modifyion 2.0 (the "License"); * it under the terms of the GNU General Public License as published bypliance with the License. @@ -17,9 +17,6 @@ * or see https://www.gnu.org/ */ -if (!defined('REQUIRE_JQUERY_BLOCKUI')) { - define('REQUIRE_JQUERY_BLOCKUI', 1); -} if (!defined('NOTOKENRENEWAL')) { define('NOTOKENRENEWAL', 1); } diff --git a/htdocs/admin/dolistore/class/PSWebServiceLibrary.class.php b/htdocs/admin/dolistore/class/PSWebServiceLibrary.class.php index 5a23133923e..521a24f490d 100644 --- a/htdocs/admin/dolistore/class/PSWebServiceLibrary.class.php +++ b/htdocs/admin/dolistore/class/PSWebServiceLibrary.class.php @@ -232,6 +232,9 @@ class PrestaShopWebservice if ($response != '') { libxml_clear_errors(); libxml_use_internal_errors(true); + if (!function_exists('simplexml_load_string')) { + throw new PrestaShopWebserviceException('Method simplexml_load_string not available. Your PHP does not support xml.'); + } $xml = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA|LIBXML_NONET); if (libxml_get_errors()) { $msg = var_export(libxml_get_errors(), true); diff --git a/htdocs/admin/dolistore/css/dolistore.css b/htdocs/admin/dolistore/css/dolistore.css index 3d8f163caf2..c3a8b6ca7ce 100644 --- a/htdocs/admin/dolistore/css/dolistore.css +++ b/htdocs/admin/dolistore/css/dolistore.css @@ -67,9 +67,6 @@ div.divsearchfield { .tree li:last-child:after{ display: none } -.blockUI { - cursor: auto!important; -} .newAppParent{ position: relative; overflow: hidden; diff --git a/htdocs/admin/ecm_directories_extrafields.php b/htdocs/admin/ecm_directories_extrafields.php index d913826b245..ea75c5ea0fc 100644 --- a/htdocs/admin/ecm_directories_extrafields.php +++ b/htdocs/admin/ecm_directories_extrafields.php @@ -91,7 +91,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/ecm_files_extrafields.php b/htdocs/admin/ecm_files_extrafields.php index b260eff55fa..41a0d714eb9 100644 --- a/htdocs/admin/ecm_files_extrafields.php +++ b/htdocs/admin/ecm_files_extrafields.php @@ -91,7 +91,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 7a4faa989d0..4f3cf10e77b 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -1,5 +1,6 @@ + * Copyright (C) 2022 Charlene Benke * * 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 @@ -359,47 +360,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $linkback = ''.$langs->trans("BackToList").''; $morehtmlref = '
'; - /* - // Ref bis - $morehtmlref.=$form->editfieldkey("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->emailcollector->creer, 'string', '', 0, 1); - $morehtmlref.=$form->editfieldval("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->emailcollector->creer, 'string', '', null, null, '', 1); - // Thirdparty - $morehtmlref.='
'.$langs->trans('ThirdParty') . ' : ' . $soc->getNomUrl(1); - // Project - if (! empty($conf->projet->enabled)) - { - $langs->load("projects"); - $morehtmlref.='
'.$langs->trans('Project') . ' '; - if ($user->rights->emailcollector->creer) - { - if ($action != 'classify') - { - $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref.='
'; - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.=''; - $morehtmlref.='
'; - } else { - $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); - } - } - } else { - if (! empty($object->fk_project)) { - $proj = new Project($db); - $proj->fetch($object->fk_project); - $morehtmlref.=''; - $morehtmlref.=$proj->ref; - $morehtmlref.=''; - } else { - $morehtmlref.=''; - } - } - } - */ $morehtmlref .= '
'; $morehtml = $langs->trans("NbOfEmailsInInbox").' : '; @@ -428,15 +388,21 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $connectstringtarget = $connectstringserver.$object->getEncodedUtf7($targetdir); } - $timeoutconnect = empty($conf->global->MAIN_USE_CONNECT_TIMEOUT) ? 10 : $conf->global->MAIN_USE_CONNECT_TIMEOUT; - $timeoutread = empty($conf->global->MAIN_USE_RESPONSE_TIMEOUT) ? 30 : $conf->global->MAIN_USE_RESPONSE_TIMEOUT; + $timeoutconnect = empty($conf->global->MAIN_USE_CONNECT_TIMEOUT) ? 5 : $conf->global->MAIN_USE_CONNECT_TIMEOUT; + $timeoutread = empty($conf->global->MAIN_USE_RESPONSE_TIMEOUT) ? 20 : $conf->global->MAIN_USE_RESPONSE_TIMEOUT; dol_syslog("imap_open connectstring=".$connectstringsource." login=".$object->login." password=".$object->password." timeoutconnect=".$timeoutconnect." timeoutread=".$timeoutread); - imap_timeout(IMAP_OPENTIMEOUT, $timeoutconnect); - imap_timeout(IMAP_READTIMEOUT, $timeoutread); + $result1 = imap_timeout(IMAP_OPENTIMEOUT, $timeoutconnect); // timeout seems ignored with ssl connect + $result2 = imap_timeout(IMAP_READTIMEOUT, $timeoutread); + $result3 = imap_timeout(IMAP_WRITETIMEOUT, 5); + $result4 = imap_timeout(IMAP_CLOSETIMEOUT, 5); + + dol_syslog("result1=".$result1." result2=".$result2." result3=".$result3." result4=".$result4); $connection = imap_open($connectstringsource, $object->login, $object->password); + + //dol_syslog("end imap_open connection=".var_export($connection, true)); } catch (Exception $e) { print $e->getMessage(); } @@ -490,7 +456,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'; print ''; print ''; - print ''; + print ''; print ''; // Add filter print ''; @@ -555,7 +521,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $rulefilterobj->fetch($rulefilter['id']); print ''; - print ''; print ''; @@ -577,24 +543,22 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''; print ''; - // Add operation - print ''; - print ''; + print ''; - print ''; - print '
'.img_picto('', 'filter', 'class="pictofixedwidth"').$form->textwithpicto($langs->trans("Filters"), $langs->trans("EmailCollectorFilterDesc")).''.img_picto('', 'filter', 'class="pictofixedwidth opacitymedium"').$form->textwithpicto($langs->trans("Filters"), $langs->trans("EmailCollectorFilterDesc")).'
'; + print ''; print $langs->trans($arrayoftypes[$rulefilter['type']]['label']); print ''.$rulefilter['rulevalue'].'
'.img_picto('', 'technic', 'class="pictofixedwidth"').$form->textwithpicto($langs->trans("EmailcollectorOperations"), $langs->trans("EmailcollectorOperationsDesc")).'
'; + $arrayoftypes = array( 'loadthirdparty'=>$langs->trans('LoadThirdPartyFromName', $langs->transnoentities("ThirdPartyName")), 'loadandcreatethirdparty'=>$langs->trans('LoadThirdPartyFromNameOrCreate', $langs->transnoentities("ThirdPartyName")), 'recordjoinpiece'=>'AttachJoinedDocumentsToObject', 'recordevent'=>'RecordEvent'); $arrayoftypesnocondition = $arrayoftypes; - if ($conf->projet->enabled) { + if (!empty($conf->projet->enabled)) { $arrayoftypes['project'] = 'CreateLeadAndThirdParty'; } $arrayoftypesnocondition['project'] = 'CreateLeadAndThirdParty'; - if ($conf->ticket->enabled) { + if (!empty($conf->ticket->enabled)) { $arrayoftypes['ticket'] = 'CreateTicketAndThirdParty'; } $arrayoftypesnocondition['ticket'] = 'CreateTicketAndThirdParty'; - if ($conf->recruitment->enabled) { + if (!empty($conf->recruitment->enabled)) { $arrayoftypes['candidature'] = 'CreateCandidature'; } $arrayoftypesnocondition['candidature'] = 'CreateCandidature'; @@ -611,6 +575,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } } + // Add operation + print '
'; print $form->selectarray('operationtype', $arrayoftypes, '', 1, 0, 0, '', 1, 0, 0, '', 'maxwidth300', 1); print ''; print ''; @@ -631,7 +598,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $ruleactionobj->fetch($ruleaction['id']); print '
'; + print ''; print ''; if (array_key_exists($ruleaction['type'], $arrayoftypes)) { print $langs->trans($arrayoftypes[$ruleaction['type']]); @@ -647,7 +614,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print $form->textwithpicto('', $langs->transnoentitiesnoconv('EmailCollectorLoadThirdPartyHelp')); } print ''; + print ''; if ($action == 'editoperation' && $ruleaction['id'] == $operationid) { print '
'; print ''; diff --git a/htdocs/admin/emailcollector_list.php b/htdocs/admin/emailcollector_list.php index 9e93dd78b86..f1cf4ca6385 100644 --- a/htdocs/admin/emailcollector_list.php +++ b/htdocs/admin/emailcollector_list.php @@ -29,6 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/events.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; + dol_include_once('/emailcollector/class/emailcollector.class.php'); // Load translation files required by page @@ -43,6 +44,7 @@ $toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'emailcollectorlist'; // To manage different context of search $backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') +$mode = GETPOST('mode', 'aZ'); $id = GETPOST('id', 'int'); @@ -52,8 +54,9 @@ $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { + // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action $page = 0; -} // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action +} $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; @@ -73,7 +76,7 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen // Default sort order (if not yet defined by previous GETPOST) if (!$sortfield) { - $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition. + $sortfield = "t.ref"; // Set here default search field. By default 1st field in definition. } if (!$sortorder) { $sortorder = "ASC"; @@ -88,12 +91,16 @@ if ($user->socid > 0) { // Protection if external user //$result = restrictedArea($user, 'emailcollector', $id, ''); // Initialize array of search criterias -$search_all = GETPOST("search_all", 'alphanohtml'); +$search_all = GETPOST('search_all', 'alphanohtml'); $search = array(); foreach ($object->fields as $key => $val) { if (GETPOST('search_'.$key, 'alpha') !== '') { $search[$key] = GETPOST('search_'.$key, 'alpha'); } + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int')); + $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int')); + } } // List of fields to search into when doing a "search in all" @@ -109,29 +116,19 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = dol_eval($val['visible'], 1, 1, '1'); + $visible = (int) dol_eval($val['visible'], 1); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), - 'position'=>$val['position'] + 'enabled'=>(abs($visible) != 3 && dol_eval($val['enabled'], 1)), + 'position'=>$val['position'], + 'help'=> isset($val['help']) ? $val['help'] : '' ); } } // Extra fields -if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0) { - foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - if (!empty($extrafields->attributes[$object->table_element]['list'][$key])) { - $arrayfields["ef.".$key] = array( - 'label'=>$extrafields->attributes[$object->table_element]['label'][$key], - 'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1), - 'position'=>$extrafields->attributes[$object->table_element]['pos'][$key], - 'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key]), - 'langfile'=>$extrafields->attributes[$object->table_element]['langfile'][$key] - ); - } - } -} +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'); @@ -156,7 +153,8 @@ if (empty($conf->emailcollector->enabled)) { */ if (GETPOST('cancel', 'alpha')) { - $action = 'list'; $massaction = ''; + $action = 'list'; + $massaction = ''; } if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; @@ -176,8 +174,12 @@ if (empty($reshook)) { 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 foreach ($object->fields as $key => $val) { $search[$key] = ''; + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = ''; + $search[$key.'_dtend'] = ''; + } } - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') @@ -200,20 +202,22 @@ if (empty($reshook)) { $form = new Form($db); +$now = dol_now(); + $help_url = "EN:Module_EMail_Collector|FR:Module_Collecteur_de_courrier_électronique|ES:Module_EMail_Collector"; -$title = $langs->trans('ListOf', $langs->transnoentitiesnoconv("EmailCollector")); +$title = $langs->trans('EmailCollectors'); +$morejs = array(); +$morecss = array(); // 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 @@ -222,7 +226,7 @@ $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $obje $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; -if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { +if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; } if ($object->ismultientitymanaged == 1) { @@ -231,18 +235,32 @@ if ($object->ismultientitymanaged == 1) { $sql .= " WHERE 1 = 1"; } foreach ($search as $key => $val) { - if ($key == 'status' && $search[$key] == -1) { - continue; - } - $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); - if (strpos($object->fields[$key]['type'], 'integer:') === 0) { - if ($search[$key] == '-1') { - $search[$key] = ''; + if (array_key_exists($key, $object->fields)) { + if ($key == 'status' && $search[$key] == -1) { + continue; + } + $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); + if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) { + if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) { + $search[$key] = ''; + } + $mode_search = 2; + } + if ($search[$key] != '') { + $sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search)); + } + } else { + if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') { + $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key); + if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) { + if (preg_match('/_dtstart$/', $key)) { + $sql .= " AND t.".$db->escape($columnName)." >= '".$db->idate($search[$key])."'"; + } + if (preg_match('/_dtend$/', $key)) { + $sql .= " AND t.".$db->escape($columnName)." <= '".$db->idate($search[$key])."'"; + } + } } - $mode_search = 2; - } - if ($search[$key] != '') { - $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); } } if ($search_all) { @@ -257,49 +275,48 @@ $sql .= $hookmanager->resPrint; /* If a group by is required $sql.= " GROUP BY "; -foreach ($object->fields as $key => $val) -{ - $sql .= "t.".$key.", "; +foreach ($object->fields as $key => $val) { + $sql .= "t.".$db->escape($key).", "; } // 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.', ' : ''); + foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { + $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.', ' : ''); + } } // Add where from hooks $parameters=array(); -$reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters); // Note that $action and $object may have been modified by hook -$sql.=$hookmanager->resPrint; -$sql=preg_replace('/, $/','', $sql); +$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; +$sql = preg_replace('/,\s*$/', '', $sql); */ -$sql .= $db->order($sortfield, $sortorder); - // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $resql = $db->query($sql); $nbtotalofrecords = $db->num_rows($resql); + if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 $page = 0; $offset = 0; } -} -// if total of record found is smaller than limit, no need to do paging and to restart another select with limits set. -if (is_numeric($nbtotalofrecords) && ($limit > $nbtotalofrecords || empty($limit))) { - $num = $nbtotalofrecords; -} else { - if ($limit) { - $sql .= $db->plimit($limit + 1, $offset); - } - $resql = $db->query($sql); - if (!$resql) { - dol_print_error($db); - exit; - } - - $num = $db->num_rows($resql); + $db->free($resql); } +// Complete request and execute it with limit +$sql .= $db->order($sortfield, $sortorder); +if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); +} + +$resql = $db->query($sql); +if (!$resql) { + dol_print_error($db); + exit; +} + +$num = $db->num_rows($resql); // Direct jump if only one record found if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) { @@ -313,7 +330,7 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $ // Output page // -------------------------------------------------------------------- -llxHeader('', $title, $help_url); +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); $arrayofselected = is_array($toselect) ? $toselect : array(); @@ -327,9 +344,11 @@ if ($limit > 0 && $limit != $conf->liste_limit) { foreach ($search as $key => $val) { if (is_array($search[$key]) && count($search[$key])) { foreach ($search[$key] as $skey) { - $param .= '&search_'.$key.'[]='.urlencode($skey); + if ($skey != '') { + $param .= '&search_'.$key.'[]='.urlencode($skey); + } } - } else { + } elseif ($search[$key] != '') { $param .= '&search_'.$key.'='.urlencode($search[$key]); } } @@ -338,6 +357,10 @@ if ($optioncss != '') { } // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; +// Add $param from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook +$param .= $hookmanager->resPrint; // List of mass actions available $arrayofmassactions = array( @@ -352,7 +375,7 @@ if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'pr } $massactionbutton = $form->selectMassAction('', $arrayofmassactions); -print '
'; +print ''."\n"; if ($optioncss != '') { print ''; } @@ -397,7 +420,7 @@ if (!empty($moreforfilter)) { } $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; -$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields +$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table @@ -407,25 +430,43 @@ print ''; +// Action column +if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; +} foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if ($key == 'status') { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } if (!empty($arrayfields['t.'.$key]['checked'])) { print ''; } @@ -438,45 +479,57 @@ $parameters = array('arrayfields'=>$arrayfields); $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column -print ''; +if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; +} print ''."\n"; +$totalarray = array(); +$totalarray['nbfield'] = 0; // Fields title label // -------------------------------------------------------------------- print ''; +if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; +} foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if ($key == 'status') { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } + $cssforfield = preg_replace('/small\s*/', '', $cssforfield); // the 'small' css must not be used for the title label if (!empty($arrayfields['t.'.$key]['checked'])) { print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n"; + $totalarray['nbfield']++; } } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields -$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); +$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column -print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; +if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; +} +$totalarray['nbfield']++; print ''."\n"; // Detect if we need a fetch on each output line $needToFetchEachLine = 0; -if (is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) { +if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) { foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) { if (preg_match('/\$object/', $val)) { $needToFetchEachLine++; // There is at least one compute field that use $object @@ -488,8 +541,10 @@ if (is_array($extrafields->attributes[$object->table_element]['computed']) && co // Loop on record // -------------------------------------------------------------------- $i = 0; -$totalarray = array(); -while ($i < ($limit ? min($num, $limit) : $num)) { +$savnbfield = $totalarray['nbfield']; +$totalarray['nbfield'] = 0; +$imaxinloop = ($limit ? min($num, $limit) : $num); +while ($i < $imaxinloop) { $obj = $db->fetch_object($resql); if (empty($obj)) { break; // Should not happen @@ -498,73 +553,107 @@ while ($i < ($limit ? min($num, $limit) : $num)) { // Store properties in $object $object->setVarsFromFetchObj($obj); - // Show here line of result - print ''; - foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); - if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'center'; - } elseif ($key == 'status') { - $cssforfield .= ($cssforfield ? ' ' : '').'center'; + if ($mode == 'kanban') { + if ($i == 0) { + print ''; } - - if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'right'; - } - //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; - - if (!empty($arrayfields['t.'.$key]['checked'])) { - print ''; - if ($key == 'status') { - print $object->getLibStatut(5); - } else { - print $object->showOutputField($val, $key, $object->$key, ''); + } else { + // Show here line of result + $j = 0; + print ''; + // Action column + if (!empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; - if (!$i) { - $totalarray['nbfield']++; - } - if (!empty($val['isameasure']) && $val['isameasure'] == 1) { - if (!$i) { - $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; - } - if (!isset($totalarray['val'])) { - $totalarray['val'] = array(); - } - if (!isset($totalarray['val']['t.'.$key])) { - $totalarray['val']['t.'.$key] = 0; - } - $totalarray['val']['t.'.$key] += $object->$key; - } } - } - // Extra fields - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; - // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); - $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - // Action column - print ''; - if (!$i) { - $totalarray['nbfield']++; - } + foreach ($object->fields as $key => $val) { + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); + if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } elseif ($key == 'status') { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } - print ''."\n"; + if (in_array($val['type'], array('timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + } elseif ($key == 'ref') { + $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + } + + if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) { + $cssforfield .= ($cssforfield ? ' ' : '').'right'; + } + //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; + + if (!empty($arrayfields['t.'.$key]['checked'])) { + print ''; + if ($key == 'status') { + print $object->getLibStatut(5); + } elseif ($key == 'rowid') { + print $object->showOutputField($val, $key, $object->id, ''); + } else { + print $object->showOutputField($val, $key, $object->$key, ''); + } + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + if (!empty($val['isameasure']) && $val['isameasure'] == 1) { + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; + } + if (!isset($totalarray['val'])) { + $totalarray['val'] = array(); + } + if (!isset($totalarray['val']['t.'.$key])) { + $totalarray['val']['t.'.$key] = 0; + } + $totalarray['val']['t.'.$key] += $object->$key; + } + } + } + // Extra fields + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; + // Fields from hook + $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Action column + if (empty($conf->global->MAIN_CHECKBOX_LEFT_COLUMN)) { + print ''; + } + if (!$i) { + $totalarray['nbfield']++; + } + + print ''."\n"; + } $i++; } @@ -581,7 +670,7 @@ if ($num == 0) { $colspan++; } } - print ''; + print ''; } @@ -594,6 +683,34 @@ print $hookmanager->resPrint; print '
'; + $searchpicto = $form->showFilterButtons('left'); + print $searchpicto; + print ''; if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { - print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); - } elseif (strpos($val['type'], 'integer:') === 0) { - print $object->showInputField($val, $key, $search[$key], '', '', 'search_', 'maxwidth150', 1); - } elseif (!preg_match('/^(date|timestamp)/', $val['type'])) { - print ''; + print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); + } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) { + print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', 'maxwidth125', 1); + } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + print '
'; + print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
'; + print '
'; + print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
'; + } elseif ($key == 'lang') { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; + $formadmin = new FormAdmin($db); + print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2); + } else { + print ''; } print '
'; -$searchpicto = $form->showFilterButtons(); -print $searchpicto; -print ''; + $searchpicto = $form->showFilterButtons(); + print $searchpicto; + print '
'; + print '
'; } - - if (in_array($val['type'], array('timestamp'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif ($key == 'ref') { - $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + // Output Kanban + print $object->getKanbanView(''); + if ($i == ($imaxinloop - 1)) { + print '
'; + print '
'; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($object->id, $arrayofselected)) { + $selected = 1; + } + print ''; } print ''; - if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - $selected = 0; - if (in_array($object->id, $arrayofselected)) { - $selected = 1; - } - print ''; - } - print '
'; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($object->id, $arrayofselected)) { + $selected = 1; + } + print ''; + } + print '
'.$langs->trans("NoRecordFound").'
'.$langs->trans("NoRecordFound").'
'."\n"; print '
'."\n"; +print load_fiche_titre($langs->trans("Other"), '', ''); + + +print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table +print ''; + +print ''; +print ''; +print ''; +print "\n"; + +// Hide e-mail headers from collected messages +print ''; +print ''; +print ''; + +print '
'.$langs->trans("Parameter").'
'.$form->textwithpicto($langs->trans("EmailCollectorHideMailHeaders"), $langs->transnoentitiesnoconv("EmailCollectorHideMailHeadersHelp")).''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('MAIN_EMAILCOLLECTOR_MAIL_WITHOUT_HEADER'); +} else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("MAIN_EMAILCOLLECTOR_MAIL_WITHOUT_HEADER", $arrval, $conf->global->TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND); +} +print '
'; +print '
'; + +print '
'; + print '
'."\n"; if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) { diff --git a/htdocs/admin/eventorganization.php b/htdocs/admin/eventorganization.php index 8edc61bf255..ee6c2ae6b52 100644 --- a/htdocs/admin/eventorganization.php +++ b/htdocs/admin/eventorganization.php @@ -41,6 +41,8 @@ $backtopage = GETPOST('backtopage', 'alpha'); $value = GETPOST('value', 'alpha'); $label = GETPOST('label', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $scandir = GETPOST('scan_dir', 'alpha'); $type = 'myobject'; @@ -220,6 +222,7 @@ if ($action == 'edit') { $setupnotempty++; print '
'; $tooltiphelp = (($langs->trans($constname . 'Tooltip') != $constname . 'Tooltip') ? $langs->trans($constname . 'Tooltip') : ''); + $tooltiphelp .= (($langs->trans($constname . 'Tooltip2') && $langs->trans($constname . 'Tooltip2') != $constname . 'Tooltip2') ? '

'."\n".$langs->trans($constname . 'Tooltip2') : ''); print ''.$form->textwithpicto($langs->trans($constname), $tooltiphelp, 1, 'info', '', 0, 3, 'tootips'.$constname).''; print '
'; @@ -312,6 +315,7 @@ if ($action == 'edit') { $setupnotempty++; print '
'; $tooltiphelp = (($langs->trans($constname . 'Tooltip') != $constname . 'Tooltip') ? $langs->trans($constname . 'Tooltip') : ''); + $tooltiphelp .= (($langs->trans($constname . 'Tooltip2') && $langs->trans($constname . 'Tooltip2') != $constname . 'Tooltip2') ? '

'."\n".$langs->trans($constname . 'Tooltip2') : ''); print $form->textwithpicto($langs->trans($constname), $tooltiphelp); print '
'; @@ -453,7 +457,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print ''; $constforvar = 'EVENTORGANIZATION_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $file) { + if (getDolGlobalString($constforvar) == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { print ''; @@ -593,7 +597,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Default print ''; $constforvar = 'EVENTORGANIZATION_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $name) { + if (getDolGlobalString($constforvar) == $name) { //print img_picto($langs->trans("Default"), 'on'); // Even if choice is the default value, we allow to disable it. Replace this with previous line if you need to disable unset print 'scandir.'&label='.urlencode($module->name).'&type='.urlencode($type).'" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; diff --git a/htdocs/admin/eventorganization_confbooth_extrafields.php b/htdocs/admin/eventorganization_confbooth_extrafields.php index 991ed3f824a..f17a2cf91e1 100644 --- a/htdocs/admin/eventorganization_confbooth_extrafields.php +++ b/htdocs/admin/eventorganization_confbooth_extrafields.php @@ -81,7 +81,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/eventorganization_confboothattendee_extrafields.php b/htdocs/admin/eventorganization_confboothattendee_extrafields.php index 0b50c483d69..552e814f8de 100644 --- a/htdocs/admin/eventorganization_confboothattendee_extrafields.php +++ b/htdocs/admin/eventorganization_confboothattendee_extrafields.php @@ -85,7 +85,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/expedition.php b/htdocs/admin/expedition.php index 2d4736cc49d..12e0d0a6d01 100644 --- a/htdocs/admin/expedition.php +++ b/htdocs/admin/expedition.php @@ -43,6 +43,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'shipping'; diff --git a/htdocs/admin/expedition_extrafields.php b/htdocs/admin/expedition_extrafields.php index b76ee35b76c..948efb6188a 100644 --- a/htdocs/admin/expedition_extrafields.php +++ b/htdocs/admin/expedition_extrafields.php @@ -91,7 +91,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/expeditiondet_extrafields.php b/htdocs/admin/expeditiondet_extrafields.php index 4f807ee9da3..41fba691b7f 100644 --- a/htdocs/admin/expeditiondet_extrafields.php +++ b/htdocs/admin/expeditiondet_extrafields.php @@ -92,7 +92,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/expensereport.php b/htdocs/admin/expensereport.php index 5b73d995b5c..fc63940f0b8 100644 --- a/htdocs/admin/expensereport.php +++ b/htdocs/admin/expensereport.php @@ -43,6 +43,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'expensereport'; diff --git a/htdocs/admin/expensereport_extrafields.php b/htdocs/admin/expensereport_extrafields.php index 25771ef63d0..54ce5a9ffea 100644 --- a/htdocs/admin/expensereport_extrafields.php +++ b/htdocs/admin/expensereport_extrafields.php @@ -85,7 +85,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/expensereport_ik.php b/htdocs/admin/expensereport_ik.php index 900754ef4b4..10b14f8ee99 100644 --- a/htdocs/admin/expensereport_ik.php +++ b/htdocs/admin/expensereport_ik.php @@ -36,10 +36,10 @@ $langs->loadLangs(array("admin", "trips", "errors", "other", "dict")); $error = 0; $action = GETPOST('action', 'aZ09'); + $id = GETPOST('id', 'int'); $ikoffset = GETPOST('ikoffset', 'int'); $coef = GETPOST('coef', 'int'); - $fk_c_exp_tax_cat = GETPOST('fk_c_exp_tax_cat'); $fk_range = GETPOST('fk_range', 'int'); @@ -62,9 +62,16 @@ if ($action == 'updateik') { } } - $expIk->setValues($_POST); - $result = $expIk->create($user); + $expIk->coef = $coef; + $expIk->ikoffset = $ikoffset; + $expIk->fk_c_exp_tax_cat = $fk_c_exp_tax_cat; + $expIk->fk_range = $fk_range; + if ($expIk->id > 0) { + $result = $expIk->update($user); + } else { + $result = $expIk->create($user); + } if ($result > 0) { setEventMessages('SetupSaved', null, 'mesgs'); diff --git a/htdocs/admin/expensereport_rules.php b/htdocs/admin/expensereport_rules.php index 77fb8f24f82..7c27ee6e408 100644 --- a/htdocs/admin/expensereport_rules.php +++ b/htdocs/admin/expensereport_rules.php @@ -34,173 +34,196 @@ require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport_rule.class.ph // Load translation files required by the page $langs->loadLangs(array("admin", "other", "trips", "errors", "dict")); +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('admin', 'dictionaryadmin','expensereport_rules')); + +$object = new ExpenseReportRule($db); + if (!$user->admin) { accessforbidden(); } -//Init error -$error = false; -$message = false; -$action = GETPOST('action', 'aZ09'); -$id = GETPOST('id', 'int'); +/* + * Action + */ -$apply_to = GETPOST('apply_to'); -$fk_user = GETPOST('fk_user', 'int'); -$fk_usergroup = GETPOST('fk_usergroup', 'int'); - -$fk_c_type_fees = GETPOST('fk_c_type_fees'); -$code_expense_rules_type = GETPOST('code_expense_rules_type'); -$dates = dol_mktime(12, 0, 0, GETPOST('startmonth'), GETPOST('startday'), GETPOST('startyear')); -$datee = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear')); -$amount = GETPOST('amount'); - -$object = new ExpenseReportRule($db); -if (!empty($id)) { - $result = $object->fetch($id); - if ($result < 0) { - dol_print_error('', $object->error, $object->errors); - } +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } -// TODO do action -if ($action == 'save') { - $error = 0; +if (empty($reshook)) { + //Init error + $error = false; - // check parameters - if (empty($apply_to)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportApplyTo")), null, 'errors'); - } - if (empty($fk_c_type_fees)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDomain")), null, 'errors'); - } - if (empty($code_expense_rules_type)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportLimitOn")), null, 'errors'); - } - if (empty($dates)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDateStart")), null, 'errors'); - } - if (empty($datee)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDateEnd")), null, 'errors'); - } - if (empty($amount)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportLimitAmount")), null, 'errors'); + $action = GETPOST('action', 'aZ09'); + $id = GETPOST('id', 'int'); + + $apply_to = GETPOST('apply_to'); + $fk_user = GETPOST('fk_user', 'int'); + $fk_usergroup = GETPOST('fk_usergroup', 'int'); + $restrictive = GETPOST('restrictive', 'int'); + $fk_c_type_fees = GETPOST('fk_c_type_fees', 'int'); + $code_expense_rules_type = GETPOST('code_expense_rules_type'); + $dates = dol_mktime(12, 0, 0, GETPOST('startmonth'), GETPOST('startday'), GETPOST('startyear')); + $datee = dol_mktime(12, 0, 0, GETPOST('endmonth'), GETPOST('endday'), GETPOST('endyear')); + $amount = price2num(GETPOST('amount'), 'MT', 2); + + if (!empty($id)) { + $result = $object->fetch($id); + if ($result < 0) { + dol_print_error('', $object->error, $object->errors); + } } - if (empty($error)) { - $object->setValues($_POST); + if ($action == 'save') { + $error = 0; - if ($apply_to == 'U') { - $object->fk_user = (int) $fk_user; - $object->fk_usergroup = 0; - $object->is_for_all = 0; - } elseif ($apply_to == 'G') { - $object->fk_usergroup = (int) $fk_usergroup; - $object->fk_user = 0; - $object->is_for_all = 0; - } elseif ($apply_to == 'A') { - $object->is_for_all = 1; - $object->fk_user = 0; - $object->fk_usergroup = 0; + // check parameters + if (empty($apply_to)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportApplyTo")), null, 'errors'); + } + if (empty($fk_c_type_fees)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDomain")), null, 'errors'); + } + if (empty($code_expense_rules_type)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportLimitOn")), null, 'errors'); + } + if (empty($dates)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDateStart")), null, 'errors'); + } + if (empty($datee)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportDateEnd")), null, 'errors'); + } + if (empty($amount)) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ExpenseReportLimitAmount")), null, 'errors'); } - $object->dates = $dates; - $object->datee = $datee; + if (empty($error)) { + if ($apply_to == 'U') { + $object->fk_user = (int) $fk_user; + $object->fk_usergroup = 0; + $object->is_for_all = 0; + } elseif ($apply_to == 'G') { + $object->fk_usergroup = (int) $fk_usergroup; + $object->fk_user = 0; + $object->is_for_all = 0; + } elseif ($apply_to == 'A') { + $object->is_for_all = 1; + $object->fk_user = 0; + $object->fk_usergroup = 0; + } - $object->entity = $conf->entity; + $object->dates = $dates; + $object->datee = $datee; + $object->restrictive = $restrictive; + $object->fk_c_type_fees = $fk_c_type_fees; + $object->code_expense_rules_type = $code_expense_rules_type; + $object->amount = $amount; + $object->entity = $conf->entity; - $res = $object->create($user); - if ($res > 0) { - setEventMessages($langs->trans('ExpenseReportRuleSave'), null); - } else { + if ($object->id > 0) { + $res = $object->update($user); + } else { + $res = $object->create($user); + } + if ($res > 0) { + setEventMessages($langs->trans('ExpenseReportRuleSave'), null); + } else { + dol_print_error($object->db); + $error++; + } + + if (!$error) { + header('Location: ' . $_SERVER['PHP_SELF']); + exit; + } else { + $action = ''; + } + } + } elseif ($action == 'delete') { + // TODO add confirm + $res = $object->delete($user); + + if ($res < 0) { dol_print_error($object->db); } - header('Location: '.$_SERVER['PHP_SELF']); + header('Location: ' . $_SERVER['PHP_SELF']); exit; } -} elseif ($action == 'delete') { - // TODO add confirm - $res = $object->delete($user); - if ($res < 0) { - dol_print_error($object->db); - } + $rules = $object->getAllRule(); - header('Location: '.$_SERVER['PHP_SELF']); - exit; + $tab_apply = array( + 'A' => $langs->trans('All'), + 'G' => $langs->trans('Group'), + 'U' => $langs->trans('User') + ); + $tab_rules_type = array( + 'EX_DAY' => $langs->trans('Day'), + 'EX_MON' => $langs->trans('Month'), + 'EX_YEA' => $langs->trans('Year'), + 'EX_EXP' => $langs->trans('OnExpense') + ); } + /* + * View + */ -$rules = $object->getAllRule(); + llxHeader('', $langs->trans("ExpenseReportsSetup")); -$tab_apply = array( - 'A' => $langs->trans('All'), - 'G' => $langs->trans('Group'), - 'U' => $langs->trans('User') -); -$tab_rules_type = array( - 'EX_DAY' => $langs->trans('Day'), - 'EX_MON' => $langs->trans('Month'), - 'EX_YEA' => $langs->trans('Year'), - 'EX_EXP' => $langs->trans('OnExpense') -); + $form = new Form($db); + $linkback = '' . $langs->trans("BackToModuleList") . ''; + print load_fiche_titre($langs->trans("ExpenseReportsSetup"), $linkback, 'title_setup'); -/* - * View - */ + $head = expensereport_admin_prepare_head(); + print dol_get_fiche_head($head, 'expenserules', $langs->trans("ExpenseReportsRules"), -1, 'trip'); -llxHeader('', $langs->trans("ExpenseReportsSetup")); - -$form = new Form($db); - -$linkback = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("ExpenseReportsSetup"), $linkback, 'title_setup'); - -$head = expensereport_admin_prepare_head(); -print dol_get_fiche_head($head, 'expenserules', $langs->trans("ExpenseReportsRules"), -1, 'trip'); - -echo ''.$langs->trans('ExpenseReportRulesDesc').''; -print '

'; + echo '' . $langs->trans('ExpenseReportRulesDesc') . ''; + print '

'; if ($action != 'edit') { - echo '
'; - echo ''; + echo ''; + echo ''; echo ''; echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; echo ''; echo ''; echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; echo ''; echo '
'.$langs->trans('ExpenseReportApplyTo').''.$langs->trans('Type').''.$langs->trans('ExpenseReportLimitOn').''.$langs->trans('ExpenseReportDateStart').''.$langs->trans('ExpenseReportDateEnd').''.$langs->trans('ExpenseReportLimitAmount').''.$langs->trans('ExpenseReportRestrictive').'
' . $langs->trans('ExpenseReportApplyTo') . '' . $langs->trans('Type') . '' . $langs->trans('ExpenseReportLimitOn') . '' . $langs->trans('ExpenseReportDateStart') . '' . $langs->trans('ExpenseReportDateEnd') . '' . $langs->trans('ExpenseReportLimitAmount') . '' . $langs->trans('ExpenseReportRestrictive') . ' 
'; - echo '
'.$form->selectarray('apply_to', $tab_apply, '', 0).'
'; - echo '
'.$form->select_dolusers('', 'fk_user').'
'; - echo '
'.$form->select_dolgroups('', 'fk_usergroup').'
'; + echo '
' . $form->selectarray('apply_to', $tab_apply, '', 0) . '
'; + echo '
' . $form->select_dolusers('', 'fk_user') . '
'; + echo '
' . $form->select_dolgroups('', 'fk_usergroup') . '
'; echo '
'.$form->selectExpense('', 'fk_c_type_fees', 0, 1, 1).''.$form->selectarray('code_expense_rules_type', $tab_rules_type, '', 0).''.$form->selectDate(strtotime(date('Y-m-01', dol_now())), 'start', '', '', 0, '', 1, 0).''.$form->selectDate(strtotime(date('Y-m-t', dol_now())), 'end', '', '', 0, '', 1, 0).' '.$conf->currency.''.$form->selectyesno('restrictive', 0, 1).'' . $form->selectExpense('', 'fk_c_type_fees', 0, 1, 1) . '' . $form->selectarray('code_expense_rules_type', $tab_rules_type, '', 0) . '' . $form->selectDate(strtotime(date('Y-m-01', dol_now())), 'start', '', '', 0, '', 1, 0) . '' . $form->selectyesno('restrictive', 0, 1) . '
'; @@ -208,60 +231,60 @@ if ($action != 'edit') { } -echo ''; -echo ''; + echo ''; + echo ''; if ($action == 'edit') { - echo ''; + echo ''; echo ''; } -echo ''; + echo '
'; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; -echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; foreach ($rules as $rule) { - echo ''; + echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - - echo ''; - echo ''; @@ -328,10 +351,10 @@ foreach ($rules as $rule) { } -echo '
'.$langs->trans('ExpenseReportApplyTo').''.$langs->trans('Type').''.$langs->trans('ExpenseReportLimitOn').''.$langs->trans('ExpenseReportDateStart').''.$langs->trans('ExpenseReportDateEnd').''.$langs->trans('ExpenseReportLimitAmount').''.$langs->trans('ExpenseReportRestrictive').' 
' . $langs->trans('ExpenseReportApplyTo') . '' . $langs->trans('Type') . '' . $langs->trans('ExpenseReportLimitOn') . '' . $langs->trans('ExpenseReportDateStart') . '' . $langs->trans('ExpenseReportDateEnd') . '' . $langs->trans('ExpenseReportLimitAmount') . '' . $langs->trans('ExpenseReportRestrictive') . ' 
'; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { $selected = ($object->is_for_all > 0) ? 'A' : ($object->fk_usergroup > 0 ? 'G' : 'U'); - echo '
'.$form->selectarray('apply_to', $tab_apply, $selected, 0).'
'; - echo '
'.$form->select_dolusers($object->fk_user, 'fk_user').'
'; - echo '
'.$form->select_dolgroups($object->fk_usergroup, 'fk_usergroup').'
'; + echo '
' . $form->selectarray('apply_to', $tab_apply, $selected, 0) . '
'; + echo '
' . $form->select_dolusers($object->fk_user, 'fk_user') . '
'; + echo '
' . $form->select_dolgroups($object->fk_usergroup, 'fk_usergroup') . '
'; } else { if ($rule->is_for_all > 0) { echo $tab_apply['A']; } elseif ($rule->fk_usergroup > 0) { - echo $tab_apply['G'].' ('.$rule->getGroupLabel().')'; + echo $tab_apply['G'] . ' (' . $rule->getGroupLabel() . ')'; } elseif ($rule->fk_user > 0) { - echo $tab_apply['U'].' ('.$rule->getUserName().')'; + echo $tab_apply['U'] . ' (' . $rule->getUserName() . ')'; } } echo '
'; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { echo $form->selectExpense($object->fk_c_type_fees, 'fk_c_type_fees', 0, 1, 1); } else { if ($rule->fk_c_type_fees == -1) { echo $langs->trans('AllExpenseReport'); } else { - $key = getDictionaryValue(MAIN_DB_PREFIX.'c_type_fees', 'code', $rule->fk_c_type_fees, false, 'id'); + $key = getDictionaryValue('c_type_fees', 'code', $rule->fk_c_type_fees, false, 'id'); if ($key && $key != $langs->trans($key)) { echo $langs->trans($key); } else { - $value = getDictionaryValue(MAIN_DB_PREFIX.'c_type_fees', 'label', $rule->fk_c_type_fees, false, 'id'); + $value = getDictionaryValue('c_type_fees', 'label', $rule->fk_c_type_fees, false, 'id'); echo $langs->trans($value ? $value : 'Undefined'); // TODO check to return trans of 'code' } } @@ -269,7 +292,7 @@ foreach ($rules as $rule) { echo ''; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { echo $form->selectarray('code_expense_rules_type', $tab_rules_type, $object->code_expense_rules_type, 0); } else { @@ -278,7 +301,7 @@ foreach ($rules as $rule) { echo ''; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { print $form->selectDate(strtotime(date('Y-m-d', $object->dates)), 'start', '', '', 0, '', 1, 0); } else { @@ -287,7 +310,7 @@ foreach ($rules as $rule) { echo ''; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { print $form->selectDate(strtotime(date('Y-m-d', $object->datee)), 'end', '', '', 0, '', 1, 0); } else { @@ -295,17 +318,17 @@ foreach ($rules as $rule) { } echo ''; + // Amount + echo ''; if ($action == 'edit' && $object->id == $rule->id) { - echo ''.$conf->currency; + echo ''; } else { echo price($rule->amount, 0, $langs, 1, -1, -1, $conf->currency); } echo ''; + echo ''; if ($action == 'edit' && $object->id == $rule->id) { echo $form->selectyesno('restrictive', $object->restrictive, 1); } else { @@ -316,11 +339,11 @@ foreach ($rules as $rule) { echo ''; if ($object->id != $rule->id) { - echo ''.img_edit().' '; - echo ''.img_delete().''; + echo '' . img_edit() . ' '; + echo '' . img_delete() . ''; } else { - echo ' '; - echo ''.$langs->trans("Cancel").''; + echo ' '; + echo '' . $langs->trans("Cancel") . ''; } echo '
'; -echo '
'; + echo '
'; + echo ''; -echo ''; + print dol_get_fiche_end(); // End of page diff --git a/htdocs/admin/facture.php b/htdocs/admin/facture.php index ae269492ddf..599aac27c3f 100644 --- a/htdocs/admin/facture.php +++ b/htdocs/admin/facture.php @@ -42,6 +42,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'invoice'; @@ -223,6 +225,12 @@ if ($action == 'updateMask') { setEventMessages($langs->trans("Error"), null, 'errors'); } } +} elseif ($action == 'set_INVOICE_CHECK_POSTERIOR_DATE') { + $check_posterior_date = GETPOST('INVOICE_CHECK_POSTERIOR_DATE', 'int'); + $res = dolibarr_set_const($db, 'INVOICE_CHECK_POSTERIOR_DATE', $check_posterior_date, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } } @@ -759,6 +767,25 @@ print '
'.$langs->trans("InvoiceCheckPosteriorDate"). ' ' ; +print $form->textwithpicto('', $langs->trans("InvoiceCheckPosteriorDateHelp"), 1, 'help') . ''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('INVOICE_CHECK_POSTERIOR_DATE'); +} else { + print '
'; + print ''; + print ''; + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("INVOICE_CHECK_POSTERIOR_DATE", $arrval, $conf->global->INVOICE_CHECK_POSTERIOR_DATE); + print '
'; + print ''; + print ''; +} +print '
'; print ''; diff --git a/htdocs/admin/facture_situation.php b/htdocs/admin/facture_situation.php index 91134671692..609a6605d1a 100644 --- a/htdocs/admin/facture_situation.php +++ b/htdocs/admin/facture_situation.php @@ -28,24 +28,93 @@ */ require '../main.inc.php'; + +// Libraries require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice.lib.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formsetup.class.php'; // Load translation files required by the page $langs->loadLangs(array('admin', 'errors', 'other', 'bills')); +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('situationinvoicesetup', 'globalsetup')); + +// Access control if (!$user->admin) { accessforbidden(); } $action = GETPOST('action', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + $value = GETPOST('value', 'alpha'); $label = GETPOST('label', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $scandir = GETPOST('scan_dir', 'alpha'); $type = 'invoice'; +$form = new Form($db); +$formSetup = new FormSetup($db); + + +// Setup conf MYMODULE_MYPARAM4 : exemple of quick define write style +$formSetup->newItem('INVOICE_USE_SITUATION') + ->setAsYesNo() + ->nameText = $langs->trans('UseSituationInvoices'); + +$item = $formSetup->newItem('INVOICE_USE_SITUATION_CREDIT_NOTE') + ->setAsYesNo() + ->nameText = $langs->trans('UseSituationInvoicesCreditNote'); + +//$item = $formSetup->newItem('INVOICE_USE_RETAINED_WARRANTY') +// ->setAsYesNo() +// ->nameText = $langs->trans('Retainedwarranty'); + + +$item = $formSetup->newItem('INVOICE_USE_RETAINED_WARRANTY'); +$item->nameText = $langs->trans('AllowedInvoiceForRetainedWarranty'); + +$arrayAvailableType = array( + Facture::TYPE_SITUATION => $langs->trans("InvoiceSituation"), + Facture::TYPE_STANDARD.'+'.Facture::TYPE_SITUATION => $langs->trans("InvoiceSituation").' + '.$langs->trans("InvoiceStandard"), +); + +if ($action == 'edit') { + $item->fieldInputOverride = $form->selectarray('INVOICE_USE_RETAINED_WARRANTY', $arrayAvailableType, $conf->global->INVOICE_USE_RETAINED_WARRANTY, 1); +} else { + $item->fieldOutputOverride= isset($arrayAvailableType[$conf->global->INVOICE_USE_RETAINED_WARRANTY])?$arrayAvailableType[$conf->global->INVOICE_USE_RETAINED_WARRANTY]:''; +} + +//$item = $formSetup->newItem('INVOICE_RETAINED_WARRANTY_LIMITED_TO_SITUATION')->setAsYesNo(); +//$item->nameText = $langs->trans('RetainedwarrantyOnlyForSituation'); + +$formSetup->newItem('INVOICE_RETAINED_WARRANTY_LIMITED_TO_FINAL_SITUATION') + ->setAsYesNo() + ->nameText = $langs->trans('RetainedwarrantyOnlyForSituationFinal'); + + +$item = $formSetup->newItem('INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_PERCENT'); +$item->nameText = $langs->trans('RetainedwarrantyDefaultPercent'); +$item->fieldAttr = array( + 'type' => 'number', + 'step' => '0.01', + 'min' => 0, + 'max' => 100 +); + + +// Conditions paiements +$item = $formSetup->newItem('INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID'); +$item->nameText = $langs->trans('PaymentConditionsShortRetainedWarranty'); +$form->load_cache_conditions_paiements(); +if (!empty($conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID) && isset($form->cache_conditions_paiements[$conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID]['label'])) { + $item->fieldOutputOverride = $form->cache_conditions_paiements[$conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID]['label']; +} +$item->fieldInputOverride = $form->getSelectConditionsPaiements($conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID, 'INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID', -1, 1); + /* * Actions @@ -67,7 +136,6 @@ llxHeader( 'EN:Invoice_Configuration|FR:Configuration_module_facture|ES:ConfiguracionFactura' ); -$form = new Form($db); $linkback = ''.$langs->trans("BackToModuleList").''; @@ -84,170 +152,25 @@ print ''.$langs->trans("InvoiceFirstSituationDesc"). * Numbering module */ -print '
'; -print ''; +if ($action == 'edit') { + print $formSetup->generateOutput(true); +} else { + print $formSetup->generateOutput(); +} +if (count($formSetup->items) > 0) { + if ($action != 'edit') { + print '
'; + print ''.$langs->trans("Modify").''; + print '
'; + } +} else { + print '
'.$langs->trans("NothingToSetup"); +} -print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table -print ''; - -print ''; -print ''; -print ''; -print ''; -print "\n"; - -_printOnOff('INVOICE_USE_SITUATION', $langs->trans('UseSituationInvoices')); -_printOnOff('INVOICE_USE_SITUATION_CREDIT_NOTE', $langs->trans('UseSituationInvoicesCreditNote')); -//_printOnOff('INVOICE_USE_RETAINED_WARRANTY', $langs->trans('Retainedwarranty')); - -$confkey = 'INVOICE_USE_RETAINED_WARRANTY'; - -$arrayAvailableType = array( - Facture::TYPE_SITUATION => $langs->trans("InvoiceSituation"), - Facture::TYPE_STANDARD.'+'.Facture::TYPE_SITUATION => $langs->trans("InvoiceSituation").' + '.$langs->trans("InvoiceStandard"), -); -$selected = $conf->global->$confkey; -$curentInput = (empty($inputCount) ? 1 : ($inputCount + 1)); -$formSelectInvoiceType = $form->selectarray('value'.$curentInput, $arrayAvailableType, $selected, 1); -_printInputFormPart($confkey, $langs->trans('AllowedInvoiceForRetainedWarranty'), '', array(), $formSelectInvoiceType); - -//_printOnOff('INVOICE_RETAINED_WARRANTY_LIMITED_TO_SITUATION', $langs->trans('RetainedwarrantyOnlyForSituation')); -_printOnOff('INVOICE_RETAINED_WARRANTY_LIMITED_TO_FINAL_SITUATION', $langs->trans('RetainedwarrantyOnlyForSituationFinal')); - -$metas = array( - 'type' => 'number', - 'step' => '0.01', - 'min' => 0, - 'max' => 100 -); -_printInputFormPart('INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_PERCENT', $langs->trans('RetainedwarrantyDefaultPercent'), '', $metas); - -// Conditions paiements -$inputCount = empty($inputCount) ? 1 : ($inputCount + 1); -print ''; -print ''; -print ''; -print ''; - - -print '
'.$langs->trans("Parameter").''.$langs->trans("Value").' 
'.$langs->trans('PaymentConditionsShortRetainedWarranty').' '; -print ''; -$form->select_conditions_paiements($conf->global->INVOICE_SITUATION_DEFAULT_RETAINED_WARRANTY_COND_ID, 'value'.$inputCount, -1, 1); -print '
'; -print '
'; - -print '
'; - -_updateBtn(); - -print '
'; print dol_get_fiche_end(); // End of page llxFooter(); $db->close(); - -/** - * Print an update button - * - * @return void - */ -function _updateBtn() -{ - global $langs; - print '
'; - print ''; - print '
'; -} - -/** - * Print a On/Off button - * - * @param string $confkey the conf key - * @param bool $title Title of conf - * @param string $desc Description - * - * @return void - */ -function _printOnOff($confkey, $title = false, $desc = '') -{ - global $langs; - - print '
'.($title ? $title : $langs->trans($confkey)); - if (!empty($desc)) { - print '
'.$langs->trans($desc).''; - } - print '
 '; - print ajax_constantonoff($confkey); - print '
'; - - if (!empty($help)) { - print $form->textwithtooltip(($title ? $title : $langs->trans($confkey)), $langs->trans($help), 2, 1, img_help(1, '')); - } else { - print $title ? $title : $langs->trans($confkey); - } - - if (!empty($desc)) { - print '
'.$langs->trans($desc).''; - } - - print '
 '; - print ''; - print ''; - if ($type == 'textarea') { - print ''; - } elseif ($type == 'input') { - print ''; - } else { - // custom - print $type; - } - print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; $constforvar = 'HRMTEST_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $file) { + if (getDolGlobalString($constforvar) == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { print ''; @@ -419,7 +421,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Default print ''; $constforvar = 'HRMTEST_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $name) { + if (getDolGlobalString($constforvar) == $name) { //print img_picto($langs->trans("Default"), 'on'); // Even if choice is the default value, we allow to disable it. Replace this with previous line if you need to disable unset print 'scandir.'&label='.urlencode($module->name).'&type='.urlencode($type).'" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 6f7f373b7da..aedd91a34eb 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -5,6 +5,7 @@ * Copyright (C) 2016 Juanjo Menent * Copyright (C) 2018 Ferran Marcet * Copyright (C) 2021 Alexandre Spangaro + * Copyright (C) 2021 Anthony Berton * * 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 @@ -101,9 +102,14 @@ if ($action == 'update') { dolibarr_set_const($db, "MAIN_THEME", GETPOST("main_theme", 'aZ09'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", getDolGlobalInt('MAIN_IHM_PARAMS_REV') + 1, 'chaine', 0, '', $conf->entity); - /*$val=GETPOST('THEME_TOPMENU_DISABLE_IMAGE'); - if (! $val) dolibarr_del_const($db, 'THEME_TOPMENU_DISABLE_IMAGE', $conf->entity); - else dolibarr_set_const($db, 'THEME_TOPMENU_DISABLE_IMAGE', GETPOST('THEME_TOPMENU_DISABLE_IMAGE'), 'chaine', 0, '', $conf->entity);*/ + if (GETPOSTISSET('THEME_TOPMENU_DISABLE_IMAGE')) { + $val=GETPOST('THEME_TOPMENU_DISABLE_IMAGE'); + if (!$val) { + dolibarr_del_const($db, 'THEME_TOPMENU_DISABLE_IMAGE', $conf->entity); + } else { + dolibarr_set_const($db, 'THEME_TOPMENU_DISABLE_IMAGE', GETPOST('THEME_TOPMENU_DISABLE_IMAGE'), 'chaine', 0, '', $conf->entity); + } + } $val = (implode(',', (colorStringToArray(GETPOST('THEME_ELDY_BACKBODY'), array())))); if ($val == '') { @@ -200,6 +206,20 @@ if ($action == 'update') { } else { dolibarr_set_const($db, "THEME_ELDY_USE_CHECKED", $val, 'chaine', 0, '', $conf->entity); } + + $val=(implode(',', (colorStringToArray(GETPOST('THEME_ELDY_BTNACTION'), array())))); + if ($val == '') { + dolibarr_del_const($db, 'THEME_ELDY_BTNACTION', $conf->entity); + } else { + dolibarr_set_const($db, 'THEME_ELDY_BTNACTION', $val, 'chaine', 0, '', $conf->entity); + } + + $val=(implode(',', (colorStringToArray(GETPOST('THEME_ELDY_TEXTBTNACTION'), array())))); + if ($val == '') { + dolibarr_del_const($db, 'THEME_ELDY_TEXTBTNACTION', $conf->entity); + } else { + dolibarr_set_const($db, 'THEME_ELDY_TEXTBTNACTION', $val, 'chaine', 0, '', $conf->entity); + } } if ($mode == 'dashboard') { @@ -266,6 +286,10 @@ if ($action == 'update') { $_SESSION["mainmenu"] = ""; // The menu manager may have changed + if (GETPOST('dol_resetcache')) { + dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", ((int) $conf->global->MAIN_IHM_PARAMS_REV) + 1, 'chaine', 0, '', $conf->entity); + } + header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup".'&mode='.$mode.(GETPOSTISSET('page_y') ? '&page_y='.GETPOST('page_y', 'int') : '')); exit; } @@ -295,6 +319,7 @@ print ''; print ''; print ''; print ''; +print ''; $head = ihm_prepare_head(); @@ -304,11 +329,153 @@ print '
'; clearstatcache(); +if ($mode == 'other') { + print '
'; + print ''; + + print ''; + + // Default language + print ''; + print ''; + + // Multilingual GUI + print ''; + print ''; + + print '
'; + print $langs->trans("Language"); + print ''; + print '
'.$langs->trans("DefaultLanguage").''; + print img_picto('', 'language', 'class="pictofixedwidth"'); + print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'MAIN_LANG_DEFAULT', 1, null, '', 0, 0, 'minwidth300', 2); + //print ''; + print '
' . $langs->trans("EnableMultilangInterface") . ''; + print ajax_constantonoff("MAIN_MULTILANGS", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '', 'language'); + print '
' . "\n"; + print '
'; + + print '
'; + print ''; + print ''; + print '
'; + + print '
'; + print '
'; + + // Other + print '
'; + print ''; + + print ''; + print ''; + print ''; + + // Max size of lists + print ''; + print ''; + + // Max size of short lists on customer card + print ''; + print ''; + + // show input border + /* + print ''; + print ''; + */ + + // First day for weeks + print ''; + print ''; + + // DefaultWorkingDays + print ''; + print ''; + + // DefaultWorkingHours + print ''; + print ''; + + // Firstname/Name + print ''; + print ''; + + // Hide unauthorized menus + print ''; + print ''; + + // Hide unauthorized button + print ''; + print ''; + + // Hide version link + /* + + print ''; + print ''; + */ + + // Show Quick Add link + print ''; + print ''; + + // Show bugtrack link + print ''; + print ''; + + // Hide wiki link on login page + $pictohelp = ''; + print ''; + print ''; + + // Disable javascript and ajax + print ''; + print ''; + + print '
'; + print $langs->trans("Miscellaneous"); + print '
' . $langs->trans("DefaultMaxSizeList") . '
' . $langs->trans("DefaultMaxSizeShortList") . '
'.$langs->trans("showInputBorder").''; + print $form->selectyesno('main_showInputBorder',isset($conf->global->THEME_ELDY_SHOW_BORDER_INPUT)?$conf->global->THEME_ELDY_SHOW_BORDER_INPUT:0,1); + print '
' . $langs->trans("WeekStartOnDay") . ''; + print $formother->select_dayofweek((isset($conf->global->MAIN_START_WEEK) ? $conf->global->MAIN_START_WEEK : '1'), 'MAIN_START_WEEK', 0); + print '
' . $langs->trans("DefaultWorkingDays") . ''; + print ''; + print '
' . $langs->trans("DefaultWorkingHours") . ''; + print ''; + print '
' . $langs->trans("FirstnameNamePosition") . ''; + $array = array(0 => $langs->trans("Firstname") . ' ' . $langs->trans("Lastname"), 1 => $langs->trans("Lastname") . ' ' . $langs->trans("Firstname")); + print $form->selectarray('MAIN_FIRSTNAME_NAME_POSITION', $array, (isset($conf->global->MAIN_FIRSTNAME_NAME_POSITION) ? $conf->global->MAIN_FIRSTNAME_NAME_POSITION : 0)); + print '
' . $langs->trans("HideUnauthorizedMenu") . ''; + //print $form->selectyesno('MAIN_MENU_HIDE_UNAUTHORIZED', isset($conf->global->MAIN_MENU_HIDE_UNAUTHORIZED) ? $conf->global->MAIN_MENU_HIDE_UNAUTHORIZED : 0, 1); + print ajax_constantonoff("MAIN_MENU_HIDE_UNAUTHORIZED", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '', 'other'); + print '
' . $langs->trans("ButtonHideUnauthorized") . ''; + //print $form->selectyesno('MAIN_BUTTON_HIDE_UNAUTHORIZED', isset($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED) ? $conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED : 0, 1); + print ajax_constantonoff("MAIN_BUTTON_HIDE_UNAUTHORIZED", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '', 'other'); + print '
'.$langs->trans("HideVersionLink").''; + print $form->selectyesno('MAIN_HIDE_VERSION',$conf->global->MAIN_HIDE_VERSION,1); + print '
' . $langs->trans("ShowQuickAddLink") . ''; + print ajax_constantonoff("MAIN_USE_TOP_MENU_QUICKADD_DROPDOWN", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '', 'other'); + print '
'; + print $form->textwithpicto($langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")), $langs->trans("ShowBugTrackLinkDesc")); + print ''; + print ''; + print '
' . str_replace('{picto}', $pictohelp, $langs->trans("DisableLinkToHelp", '{picto}')) . ''; + print ajax_constantonoff("MAIN_HELP_DISABLELINK", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '', 'other'); + //print $form->selectyesno('MAIN_HELP_DISABLELINK', isset($conf->global->MAIN_HELP_DISABLELINK) ? $conf->global->MAIN_HELP_DISABLELINK : 0, 1); + print '
' . $form->textwithpicto($langs->trans("DisableJavascript"), $langs->trans("DisableJavascriptNote")) . ''; + print ajax_constantonoff("MAIN_DISABLE_JAVASCRIPT", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '', 'other'); + print '
' . "\n"; + print '
'; +} + + if ($mode == 'template') { // Themes and themes options showSkins(null, 1); } + if ($mode == 'dashboard') { print '
'; print ''; @@ -332,11 +499,11 @@ if ($mode == 'dashboard') { print '' . "\n"; /* no more need for this option. It is now a widget already controlled by end user - print ''; - print ''; - */ + print ''; + print ''; + */ print '
' . $langs->trans('BoxstatsDisableGlobal') . ''; - print ajax_constantonoff("MAIN_DISABLE_GLOBAL_BOXSTATS", array(), $conf->entity, 0, 0, 1, 0); - print '
' . $langs->trans('BoxstatsDisableGlobal') . ''; + print ajax_constantonoff("MAIN_DISABLE_GLOBAL_BOXSTATS", array(), $conf->entity, 0, 0, 1, 0); + print '
'; print '
'; @@ -428,152 +595,6 @@ if ($mode == 'dashboard') { print ''; } -if ($mode == 'other') { - print '
'; - print ''; - - print ''; - - // Default language - print ''; - print ''; - - // Multilingual GUI - print ''; - print ''; - - print '
'; - print $langs->trans("Language"); - print ''; - print '
'.$langs->trans("DefaultLanguage").''; - print img_picto('', 'language', 'class="pictofixedwidth"'); - print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'MAIN_LANG_DEFAULT', 1, null, '', 0, 0, 'minwidth300', 2); - //print ''; - print '
' . $langs->trans("EnableMultilangInterface") . ''; - print ajax_constantonoff("MAIN_MULTILANGS", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '', 'language'); - print '
' . "\n"; - print '
'; - - print '
'; - print ''; - print '
'; - - print '
'; - print '
'; - - // Other - print '
'; - print ''; - - print ''; - - // Max size of lists - print ''; - print ''; - print ''; - - // Max size of short lists on customer card - print ''; - print ''; - print ''; - - // show input border - /* - print ''; - print ''; - print ''; - */ - - // First day for weeks - print ''; - print ''; - print ''; - - // DefaultWorkingDays - print ''; - print ''; - print ''; - - // DefaultWorkingHours - print ''; - print ''; - print ''; - - // Firstname/Name - print ''; - print ''; - print ''; - - // Hide unauthorized menus - print ''; - print ''; - print ''; - - // Hide unauthorized button - print ''; - print ''; - print ''; - - // Hide version link - /* - - print ''; - print ''; - print ''; - */ - - // Show bugtrack link - print ''; - print ''; - print ''; - - // Hide wiki link on login page - $pictohelp = ''; - print ''; - print ''; - print ''; - - // Disable javascript and ajax - print ''; - print ''; - print ''; - - print '
'; - print $langs->trans("Miscelaneous"); - print ''; - print '
' . $langs->trans("DefaultMaxSizeList") . ' 
' . $langs->trans("DefaultMaxSizeShortList") . ' 
'.$langs->trans("showInputBorder").''; - print $form->selectyesno('main_showInputBorder',isset($conf->global->THEME_ELDY_SHOW_BORDER_INPUT)?$conf->global->THEME_ELDY_SHOW_BORDER_INPUT:0,1); - print ' 
' . $langs->trans("WeekStartOnDay") . ''; - print $formother->select_dayofweek((isset($conf->global->MAIN_START_WEEK) ? $conf->global->MAIN_START_WEEK : '1'), 'MAIN_START_WEEK', 0); - print ' 
' . $langs->trans("DefaultWorkingDays") . ''; - print ''; - print ' 
' . $langs->trans("DefaultWorkingHours") . ''; - print ''; - print ' 
' . $langs->trans("FirstnameNamePosition") . ''; - $array = array(0 => $langs->trans("Firstname") . ' ' . $langs->trans("Lastname"), 1 => $langs->trans("Lastname") . ' ' . $langs->trans("Firstname")); - print $form->selectarray('MAIN_FIRSTNAME_NAME_POSITION', $array, (isset($conf->global->MAIN_FIRSTNAME_NAME_POSITION) ? $conf->global->MAIN_FIRSTNAME_NAME_POSITION : 0)); - print ' 
' . $langs->trans("HideUnauthorizedMenu") . ''; - //print $form->selectyesno('MAIN_MENU_HIDE_UNAUTHORIZED', isset($conf->global->MAIN_MENU_HIDE_UNAUTHORIZED) ? $conf->global->MAIN_MENU_HIDE_UNAUTHORIZED : 0, 1); - print ajax_constantonoff("MAIN_MENU_HIDE_UNAUTHORIZED", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '', 'other'); - print ' 
' . $langs->trans("ButtonHideUnauthorized") . ''; - //print $form->selectyesno('MAIN_BUTTON_HIDE_UNAUTHORIZED', isset($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED) ? $conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED : 0, 1); - print ajax_constantonoff("MAIN_BUTTON_HIDE_UNAUTHORIZED", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '', 'other'); - print ' 
'.$langs->trans("HideVersionLink").''; - print $form->selectyesno('MAIN_HIDE_VERSION',$conf->global->MAIN_HIDE_VERSION,1); - print ' 
'; - print $form->textwithpicto($langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")), $langs->trans("ShowBugTrackLinkDesc")); - print ''; - print ''; - print ' 
' . str_replace('{picto}', $pictohelp, $langs->trans("DisableLinkToHelp", '{picto}')) . ''; - print ajax_constantonoff("MAIN_HELP_DISABLELINK", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '', 'other'); - //print $form->selectyesno('MAIN_HELP_DISABLELINK', isset($conf->global->MAIN_HELP_DISABLELINK) ? $conf->global->MAIN_HELP_DISABLELINK : 0, 1); - print ' 
' . $langs->trans("DisableJavascript") . ''; - print ajax_constantonoff("MAIN_DISABLE_JAVASCRIPT", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '', 'other'); - print ' ' . $langs->trans("DisableJavascriptNote") . ''; - print ''; - print '
' . "\n"; - print '
'; -} if ($mode == 'login') { // Other @@ -635,6 +656,7 @@ if ($mode == 'login') { print '
'; print ''; +print ''; print '
'; print ''; diff --git a/htdocs/admin/import.php b/htdocs/admin/import.php index cd9d7b44074..37168baa3d4 100644 --- a/htdocs/admin/import.php +++ b/htdocs/admin/import.php @@ -41,6 +41,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + /* * Actions diff --git a/htdocs/admin/knowledgemanagement.php b/htdocs/admin/knowledgemanagement.php index 8d93c16741a..041216014b0 100644 --- a/htdocs/admin/knowledgemanagement.php +++ b/htdocs/admin/knowledgemanagement.php @@ -37,8 +37,9 @@ $langs->loadLangs(array("admin", "knowledgemanagement")); // Parameters $action = GETPOST('action', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); - $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'knowledgemanagement'; @@ -402,7 +403,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print '
'; $constforvar = 'KNOWLEDGEMANAGEMENT_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $file) { + if (getDolGlobalString($constforvar) == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { print ''; @@ -544,7 +545,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Default print ''; $constforvar = 'KNOWLEDGEMANAGEMENT_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $name) { + if (getDolGlobalString($constforvar) == $name) { //print img_picto($langs->trans("Default"), 'on'); // Even if choice is the default value, we allow to disable it. Replace this with previous line if you need to disable unset print 'scandir.'&label='.urlencode($module->name).'&type='.urlencode($type).'" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; diff --git a/htdocs/admin/knowledgerecord_extrafields.php b/htdocs/admin/knowledgerecord_extrafields.php index d6c94e4ceeb..62580d585c3 100644 --- a/htdocs/admin/knowledgerecord_extrafields.php +++ b/htdocs/admin/knowledgerecord_extrafields.php @@ -88,7 +88,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index 6b700119e8a..f065760f62d 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -46,11 +46,12 @@ if ($action == 'test' || $action == 'send') { $substitutionarrayfortest = array( '__DOL_MAIN_URL_ROOT__'=>DOL_MAIN_URL_ROOT, + '__CHECK_READ__' => (!empty($object) && is_object($object) && is_object($object->thirdparty)) ? '' : '', + '__USER_LOGIN__' => $user->login, + '__USER_EMAIL__' => $user->email, + '__USER_SIGNATURE__' => (($user->signature && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN)) ? $usersignature : ''), // Done into actions_sendmails '__ID__' => 'RecipientIdRecord', //'__EMAIL__' => 'RecipientEMail', // Done into actions_sendmails - '__CHECK_READ__' => (!empty($object) && is_object($object) && is_object($object->thirdparty)) ? '' : '', - '__USER_SIGNATURE__' => (($user->signature && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN)) ? $usersignature : ''), // Done into actions_sendmails - '__LOGIN__' => $user->login, '__LASTNAME__' => 'RecipientLastname', '__FIRSTNAME__' => 'RecipientFirstname', '__ADDRESS__'=> 'RecipientAddress', @@ -762,9 +763,18 @@ if ($action == 'edit') { print '
'.$langs->trans("MAIN_MAIL_AUTOCOPY_TO").''; if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) { - print $conf->global->MAIN_MAIL_AUTOCOPY_TO; - if (!isValidEmail($conf->global->MAIN_MAIL_AUTOCOPY_TO)) { - print img_warning($langs->trans("ErrorBadEMail")); + $listofemail = explode(',', $conf->global->MAIN_MAIL_AUTOCOPY_TO); + $i = 0; + foreach ($listofemail as $key => $val) { + if ($i) { + print ', '; + } + $val = trim($val); + print $val; + if (!isValidEmail($val, 0, 1)) { + print img_warning($langs->trans("ErrorBadEMail", $val)); + } + $i++; } } else { print ' '; @@ -902,8 +912,8 @@ if ($action == 'edit') { include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; $formmail = new FormMail($db); $formmail->trackid = (($action == 'testhtml') ? "testhtml" : "test"); - $formmail->fromname = (GETPOSTISSET('fromname') ? $_POST['fromname'] : $conf->global->MAIN_MAIL_EMAIL_FROM); - $formmail->frommail = (GETPOSTISSET('frommail') ? $_POST['frommail'] : $conf->global->MAIN_MAIL_EMAIL_FROM); + $formmail->fromname = (GETPOSTISSET('fromname') ? GETPOST('fromname') : $conf->global->MAIN_MAIL_EMAIL_FROM); + $formmail->frommail = (GETPOSTISSET('frommail') ? GETPOST('frommail') : $conf->global->MAIN_MAIL_EMAIL_FROM); $formmail->fromid = $user->id; $formmail->fromalsorobot = 1; $formmail->fromtype = (GETPOSTISSET('fromtype') ?GETPOST('fromtype', 'aZ09') : (!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE) ? $conf->global->MAIN_MAIL_DEFAULT_FROMTYPE : 'user')); @@ -911,9 +921,9 @@ if ($action == 'edit') { $formmail->withsubstit = 1; $formmail->withfrom = 1; $formmail->witherrorsto = 1; - $formmail->withto = (!empty($_POST['sendto']) ? GETPOST('sendto', 'restricthtml') : ($user->email ? $user->email : 1)); - $formmail->withtocc = (!empty($_POST['sendtocc']) ? GETPOST('sendtocc', 'restricthtml') : 1); // ! empty to keep field if empty - $formmail->withtoccc = (!empty($_POST['sendtoccc']) ? GETPOST('sendtoccc', 'restricthtml') : 1); // ! empty to keep field if empty + $formmail->withto = (GETPOSTISSET('sendto') ? GETPOST('sendto', 'restricthtml') : ($user->email ? $user->email : 1)); + $formmail->withtocc = (GETPOSTISSET('sendtocc') ? GETPOST('sendtocc', 'restricthtml') : 1); // ! empty to keep field if empty + $formmail->withtoccc = (GETPOSTISSET('sendtoccc') ? GETPOST('sendtoccc', 'restricthtml') : 1); // ! empty to keep field if empty $formmail->withtopic = (GETPOSTISSET('subject') ? GETPOST('subject') : $langs->trans("Test")); $formmail->withtopicreadonly = 0; $formmail->withfile = 2; diff --git a/htdocs/admin/mails_senderprofile_list.php b/htdocs/admin/mails_senderprofile_list.php index d3441cf2e21..8e31d0e6d62 100644 --- a/htdocs/admin/mails_senderprofile_list.php +++ b/htdocs/admin/mails_senderprofile_list.php @@ -169,7 +169,7 @@ if (empty($reshook)) { foreach ($object->fields as $key => $val) { $search[$key] = ''; } - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index 506661900db..abc434ed58f 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -57,6 +57,7 @@ $langs->loadLangs($langsArray); $action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; $massaction = GETPOST('massaction', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation +$mode = GETPOST('mode', 'aZ09'); $id = GETPOST('id', 'int'); $rowid = GETPOST('rowid', 'alpha'); @@ -66,10 +67,6 @@ $search_lang = GETPOST('search_lang', 'alpha'); $search_fk_user = GETPOST('search_fk_user', 'intcomma'); $search_topic = GETPOST('search_topic', 'alpha'); -if (!empty($user->socid)) { - accessforbidden(); -} - $acts = array(); $actl = array(); $acts[0] = "activate"; @@ -100,6 +97,7 @@ if (empty($sortorder)) { // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('emailtemplates')); + // Name of SQL tables of dictionaries $tabname = array(); $tabname[25] = MAIN_DB_PREFIX."c_email_templates"; @@ -246,6 +244,12 @@ if ($reshook == 0) { } } + + +if (!empty($user->socid)) { + accessforbidden(); +} + $permissiontoadd = 1; //asort($elementList); @@ -273,6 +277,9 @@ if ($reshook < 0) { } if (empty($reshook)) { + // Selection of new fields + include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + // 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 @@ -281,7 +288,7 @@ if (empty($reshook)) { $search_lang = ''; $search_fk_user = ''; $search_topic = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } @@ -308,7 +315,7 @@ if (empty($reshook)) { // Rename some POST variables into a generic name if (GETPOST('actionmodify', 'alpha') && $value == 'topic') { - $_POST['topic'] = $_POST['topic-'.$rowid]; + $_POST['topic'] = GETPOST('topic-'.$rowid); } if ((!GETPOSTISSET($value) || GETPOST($value) == '' || GETPOST($value) == '-1') && $value != 'lang' && $value != 'fk_user' && $value != 'position') { @@ -395,7 +402,7 @@ if (empty($reshook)) { } } elseif ($keycode == 'content') { $sql .= "'".$db->escape(GETPOST($keycode, 'restricthtml'))."'"; - } elseif (in_array($keycode, array('joinfiles', 'private', 'position'))) { + } elseif (in_array($keycode, array('joinfiles', 'private', 'position', 'entity'))) { $sql .= (int) GETPOST($keycode, 'int'); } else { $sql .= "'".$db->escape(GETPOST($keycode, 'nohtml'))."'"; @@ -502,9 +509,9 @@ if (empty($reshook)) { if ($action == 'confirm_delete' && $confirm == 'yes') { // delete $rowidcol = "rowid"; - $sql = "DELETE from ".$tabname[$id]." WHERE ".$rowidcol."=".((int) $rowid); + $sql = "DELETE from ".$tabname[$id]." WHERE ".$rowidcol." = ".((int) $rowid); if (!$user->admin) { // A non admin user can only edit its own template - $sql .= " AND fk_user = ".((int) $user->id); + $sql .= " AND fk_user = ".((int) $user->id); } dol_syslog("delete", LOG_DEBUG); $result = $db->query($sql); @@ -548,47 +555,20 @@ if (empty($reshook)) { */ $form = new Form($db); + +$now = dol_now(); + $formadmin = new FormAdmin($db); +//$help_url = "EN:Module_MyObject|FR:Module_MyObject_FR|ES:Módulo_MyObject"; $help_url = ''; if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { $title = $langs->trans("EMailsSetup"); } else { - $title = $langs->trans("EMailsTemplates"); + $title = $langs->trans("EMailTemplates"); } - -llxHeader('', $title, $help_url); - -$linkback = ''; -$titlepicto = 'title_setup'; - - -$url = DOL_URL_ROOT.'/admin/mails_templates.php?action=add'; -$newcardbutton = dolGetButtonTitle($langs->trans('NewEMailTemplate'), '', 'fa fa-plus-circle', $url, '', $permissiontoadd); - - -if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { - print load_fiche_titre($title, '', $titlepicto); -} else { - print load_fiche_titre($title, $newcardbutton, $titlepicto); -} - -if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { - $head = email_admin_prepare_head(); - - print dol_get_fiche_head($head, 'templates', '', -1); - - if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { - print load_fiche_titre('', $newcardbutton, ''); - } -} - - -// Confirmation de la suppression de la ligne -if ($action == 'delete') { - print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.$rowid.'&code='.$code.'&id='.$id, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1); -} - +$morejs = array(); +$morecss = array(); $sql = "SELECT rowid as rowid, module, label, type_template, lang, fk_user, private, position, topic, joinfiles, content_lines, content, enabled, active"; $sql .= " FROM ".MAIN_DB_PREFIX."c_email_templates"; @@ -623,6 +603,80 @@ $sql .= $db->order($sortfield, $sortorder); $sql .= $db->plimit($listlimit + 1, $offset); //print $sql; +// Output page +// -------------------------------------------------------------------- + +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); + +$arrayofselected = is_array($toselect) ? $toselect : array(); + +$param = ''; +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='.urlencode($limit); +} +if (!empty($search) && is_array($search)) { + foreach ($search as $key => $val) { + if (is_array($search[$key]) && count($search[$key])) { + foreach ($search[$key] as $skey) { + if ($skey != '') { + $param .= '&search_'.$key.'[]='.urlencode($skey); + } + } + } elseif ($search[$key] != '') { + $param .= '&search_'.$key.'='.urlencode($search[$key]); + } + } +} +if ($optioncss != '') { + $param .= '&optioncss='.urlencode($optioncss); +} +// Add $param from extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; +// Add $param from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook +$param .= $hookmanager->resPrint; + + +$linkback = ''; +$titlepicto = 'title_setup'; + + +$url = DOL_URL_ROOT.'/admin/mails_templates.php?action=add&token='.newToken(); +$newcardbutton = dolGetButtonTitle($langs->trans('NewEMailTemplate'), '', 'fa fa-plus-circle', $url, '', $permissiontoadd); + + +if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { + print load_fiche_titre($title, '', $titlepicto); +} else { + print load_fiche_titre($title, $newcardbutton, $titlepicto); +} + +if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { + $head = email_admin_prepare_head(); + + print dol_get_fiche_head($head, 'templates', '', -1); + + if (!empty($user->admin) && (empty($_SESSION['leftmenu']) || $_SESSION['leftmenu'] != 'email_templates')) { + print load_fiche_titre('', $newcardbutton, ''); + } +} + + +// Confirmation de la suppression de la ligne +if ($action == 'delete') { + print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.$rowid.'&code='.$code.'&id='.$id, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1); +} + + + + $fieldlist = explode(',', $tabfield[$id]); if ($action == 'add') { @@ -681,7 +735,7 @@ if ($action == 'add') { } if ($valuetoshow != '') { - print ''; + print ''; if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { print ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; } elseif (!empty($tabhelp[$id][$value])) { @@ -693,12 +747,12 @@ if ($action == 'add') { } else { print $valuetoshow; } - print ''; + print ''; + print ''; print ''; - print ''; + print '
'; + print '
'; // Label if ($tmpfieldlist == 'topic') { @@ -769,28 +823,37 @@ if ($action == 'add') { if (empty($conf->global->FCKEDITOR_ENABLE_MAIL)) { $okforextended = false; } - $doleditor = new DolEditor($tmpfieldlist, (!empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 180, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_4, '90%'); + $doleditor = new DolEditor($tmpfieldlist, (!empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 180, 'dolibarr_mailings', 'In', 0, true, $okforextended, ROWS_4, '90%'); print $doleditor->Create(1); } print ''; - if ($action != 'edit') { - print '
'; - print ''; - } - print '
'; + + if ($action != 'edit') { + print '
'; + print ' '; + print ''; + print '
'; + } + print '
'; print ''; - print '
'; + print '

'; } // END IF not edit +// List of available record in database +dol_syslog("htdocs/admin/dict", LOG_DEBUG); +$resql = $db->query($sql); +if (!$resql) { + dol_print_error($db); + exit; +} + +$num = $db->num_rows($resql); + print '
'; print ''; print ''; @@ -798,157 +861,155 @@ print ''; print ''; -// List of available record in database -dol_syslog("htdocs/admin/dict", LOG_DEBUG); -$resql = $db->query($sql); -if ($resql) { - $num = $db->num_rows($resql); - $i = 0; +$i = 0; - $param = '&id='.$id; - if ($search_label) { - $param .= '&search_label='.urlencode($search_label); - } - if ($search_lang > 0) { - $param .= '&search_lang='.urlencode($search_lang); - } - if ($search_type_template != '-1') { - $param .= '&search_type_template='.urlencode($search_type_template); - } - if ($search_fk_user > 0) { - $param .= '&search_fk_user='.urlencode($search_fk_user); - } - if ($search_topic) { - $param .= '&search_topic='.urlencode($search_topic); - } +$param = '&id='.$id; +if ($search_label) { + $param .= '&search_label='.urlencode($search_label); +} +if ($search_lang > 0) { + $param .= '&search_lang='.urlencode($search_lang); +} +if ($search_type_template != '-1') { + $param .= '&search_type_template='.urlencode($search_type_template); +} +if ($search_fk_user > 0) { + $param .= '&search_fk_user='.urlencode($search_fk_user); +} +if ($search_topic) { + $param .= '&search_topic='.urlencode($search_topic); +} - $paramwithsearch = $param; - if ($sortorder) { - $paramwithsearch .= '&sortorder='.urlencode($sortorder); - } - if ($sortfield) { - $paramwithsearch .= '&sortfield='.urlencode($sortfield); - } - if (GETPOST('from', 'alpha')) { - $paramwithsearch .= '&from='.urlencode(GETPOST('from', 'alpha')); - } +$paramwithsearch = $param; +if ($sortorder) { + $paramwithsearch .= '&sortorder='.urlencode($sortorder); +} +if ($sortfield) { + $paramwithsearch .= '&sortfield='.urlencode($sortfield); +} +if (GETPOST('from', 'alpha')) { + $paramwithsearch .= '&from='.urlencode(GETPOST('from', 'alpha')); +} - // There is several pages - if ($num > $listlimit) { - print ''; - } +// There is several pages +if ($num > $listlimit) { + print ''; +} - // Title line with search boxes - print ''; +// Title line with search boxes +print ''; - foreach ($fieldlist as $field => $value) { - if ($value == 'label') { - print ''; - } elseif ($value == 'lang') { - print ''; - } elseif ($value == 'fk_user') { - print ''; - } elseif ($value == 'topic') { - print ''; - } elseif ($value == 'type_template') { - print ''; - } elseif (!in_array($value, array('content', 'content_lines'))) { - print ''; - } - } - - if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { +foreach ($fieldlist as $field => $value) { + if ($value == 'label') { + print ''; + } elseif ($value == 'lang') { + print ''; + } elseif ($value == 'fk_user') { + print ''; + } elseif ($value == 'topic') { + print ''; + } elseif ($value == 'type_template') { + print ''; + } elseif (!in_array($value, array('content', 'content_lines'))) { print ''; } +} - // Action column - print ''; - print ''; +if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { + print ''; +} - // Title of lines - print ''; - foreach ($fieldlist as $field => $value) { - $showfield = 1; // By defaut - $align = "left"; - $sortable = 1; - $valuetoshow = ''; - $forcenowrap = 1; - /* - $tmparray=getLabelOfField($fieldlist[$field]); - $showfield=$tmp['showfield']; - $valuetoshow=$tmp['valuetoshow']; - $align=$tmp['align']; - $sortable=$tmp['sortable']; - */ - $valuetoshow = ucfirst($fieldlist[$field]); // By defaut - $valuetoshow = $langs->trans($valuetoshow); // try to translate - if ($fieldlist[$field] == 'fk_user') { - $valuetoshow = $langs->trans("Owner"); - } - if ($fieldlist[$field] == 'lang') { - $valuetoshow = $langs->trans("Language"); - } - if ($fieldlist[$field] == 'type') { - $valuetoshow = $langs->trans("Type"); - } - if ($fieldlist[$field] == 'libelle' || $fieldlist[$field] == 'label') { - $valuetoshow = $langs->trans("Code"); - } - if ($fieldlist[$field] == 'type_template') { - $align = 'center'; - $valuetoshow = $langs->trans("TypeOfTemplate"); - } - if ($fieldlist[$field] == 'private') { - $align = 'center'; - } - if ($fieldlist[$field] == 'position') { - $align = 'center'; - } +// Action column +print ''; +print ''; - if ($fieldlist[$field] == 'joinfiles') { - $valuetoshow = $langs->trans("FilesAttachedToEmail"); $align = 'center'; $forcenowrap = 0; - } - if ($fieldlist[$field] == 'content') { - $valuetoshow = $langs->trans("Content"); $showfield = 0; - } - if ($fieldlist[$field] == 'content_lines') { - $valuetoshow = $langs->trans("ContentForLines"); $showfield = 0; - } - - // Show fields - if ($showfield) { - if (!empty($tabhelp[$id][$value])) { - if (in_array($value, array('topic'))) { - $valuetoshow = $form->textwithpicto($valuetoshow, $tabhelp[$id][$value], 1, 'help', '', 0, 2, 'tooltip'.$value, $forcenowrap); // Tooltip on click - } else { - $valuetoshow = $form->textwithpicto($valuetoshow, $tabhelp[$id][$value], 1, 'help', '', 0, 2, '', $forcenowrap); // Tooltip on hover - } - } - print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], ($sortable ? $fieldlist[$field] : ''), ($page ? 'page='.$page.'&' : ''), $param, "align=".$align, $sortfield, $sortorder); - } +// Title of lines +print ''; +foreach ($fieldlist as $field => $value) { + $showfield = 1; // By defaut + $align = "left"; + $sortable = 1; + $valuetoshow = ''; + $forcenowrap = 1; + /* + $tmparray=getLabelOfField($fieldlist[$field]); + $showfield=$tmp['showfield']; + $valuetoshow=$tmp['valuetoshow']; + $align=$tmp['align']; + $sortable=$tmp['sortable']; + */ + $valuetoshow = ucfirst($fieldlist[$field]); // By defaut + $valuetoshow = $langs->trans($valuetoshow); // try to translate + if ($fieldlist[$field] == 'fk_user') { + $valuetoshow = $langs->trans("Owner"); + } + if ($fieldlist[$field] == 'lang') { + $valuetoshow = $langs->trans("Language"); + } + if ($fieldlist[$field] == 'type') { + $valuetoshow = $langs->trans("Type"); + } + if ($fieldlist[$field] == 'libelle' || $fieldlist[$field] == 'label') { + $valuetoshow = $langs->trans("Code"); + } + if ($fieldlist[$field] == 'type_template') { + $align = 'center'; + $valuetoshow = $langs->trans("TypeOfTemplate"); + } + if ($fieldlist[$field] == 'private') { + $align = 'center'; + } + if ($fieldlist[$field] == 'position') { + $align = 'center'; } - print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], "active", ($page ? 'page='.$page.'&' : ''), $param, 'align="center"', $sortfield, $sortorder); - print getTitleFieldOfList(''); - print ''; + if ($fieldlist[$field] == 'joinfiles') { + $valuetoshow = $langs->trans("FilesAttachedToEmail"); $align = 'center'; $forcenowrap = 0; + } + if ($fieldlist[$field] == 'content') { + $valuetoshow = $langs->trans("Content"); $showfield = 0; + } + if ($fieldlist[$field] == 'content_lines') { + $valuetoshow = $langs->trans("ContentForLines"); $showfield = 0; + } - if ($num) { - // Lines with values - while ($i < $num) { - $obj = $db->fetch_object($resql); + // Show fields + if ($showfield) { + if (!empty($tabhelp[$id][$value])) { + if (in_array($value, array('topic'))) { + $valuetoshow = $form->textwithpicto($valuetoshow, $tabhelp[$id][$value], 1, 'help', '', 0, 2, 'tooltip'.$value, $forcenowrap); // Tooltip on click + } else { + $valuetoshow = $form->textwithpicto($valuetoshow, $tabhelp[$id][$value], 1, 'help', '', 0, 2, '', $forcenowrap); // Tooltip on hover + } + } + print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], ($sortable ? $fieldlist[$field] : ''), ($page ? 'page='.$page.'&' : ''), $param, "align=".$align, $sortfield, $sortorder); + } +} +print getTitleFieldOfList($langs->trans("Status"), 0, $_SERVER["PHP_SELF"], "active", ($page ? 'page='.$page.'&' : ''), $param, 'align="center"', $sortfield, $sortorder); +print getTitleFieldOfList(''); +print ''; + +if ($num) { + $nbqualified = 0; + + // Lines with values + while ($i < $num) { + $obj = $db->fetch_object($resql); + + if ($obj) { if ($action == 'edit' && ($rowid == (!empty($obj->rowid) ? $obj->rowid : $obj->code))) { print ''; @@ -1000,7 +1061,7 @@ if ($resql) { if (empty($conf->global->FCKEDITOR_ENABLE_MAIL)) { $okforextended = false; } - $doleditor = new DolEditor($tmpfieldlist.'-'.$rowid, (!empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 500, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_6, '90%'); + $doleditor = new DolEditor($tmpfieldlist.'-'.$rowid, (!empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 500, 'dolibarr_mailings', 'In', 0, true, $okforextended, ROWS_6, '90%'); print $doleditor->Create(1); } if ($tmpfieldlist == 'content_lines') { @@ -1018,6 +1079,8 @@ if ($resql) { } print "\n"; + + $nbqualified++; } else { // If template is for a module, check module is enabled. if ($obj->module) { @@ -1039,6 +1102,8 @@ if ($resql) { continue; // Email template not qualified } + $nbqualified++; + print ''; $tmpaction = 'view'; @@ -1152,15 +1217,19 @@ if ($resql) { //else print ''.img_delete().''; // Some dictionary can be edited by other profile than admin } print ''; + print "\n"; } - - - $i++; } + + $i++; } -} else { - dol_print_error($db); +} + +// If no record found +if ($nbqualified == 0) { + $colspan = 10; + print ''; } print '
'; - print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num > $listlimit), ''); - print '
'; + print_fleche_navigation($page, $_SERVER["PHP_SELF"], $paramwithsearch, ($num > $listlimit), ''); + print '
'; - print $formadmin->select_language($search_lang, 'search_lang', 0, null, 1, 0, 0, 'maxwidth150'); - print ''; - print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, ($user->admin ? '' : 'hierarchyme'), null, 0, 0, 0, '', 0, '', 'maxwidth150'); - print ''; - print $form->selectarray('search_type_template', $elementList, $search_type_template, 1, 0, 0, '', 0, 0, 0, '', 'minwidth150', 1, '', 0, 1); - print ''; + print $formadmin->select_language($search_lang, 'search_lang', 0, null, 1, 0, 0, 'maxwidth150'); + print ''; + print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, ($user->admin ? '' : 'hierarchyme'), null, 0, 0, 0, '', 0, '', 'maxwidth150'); + print ''; + print $form->selectarray('search_type_template', $elementList, $search_type_template, 1, 0, 0, '', 0, 0, 0, '', 'minwidth150', 1, '', 0, 1); + print ''; - $searchpicto = $form->showFilterButtons(); - print $searchpicto; - print '
'; +$searchpicto = $form->showFilterButtons(); +print $searchpicto; +print '
'.$langs->trans("NoRecordFound").'
'; diff --git a/htdocs/admin/mails_ticket.php b/htdocs/admin/mails_ticket.php index 79c549c0609..481fcad212c 100644 --- a/htdocs/admin/mails_ticket.php +++ b/htdocs/admin/mails_ticket.php @@ -537,16 +537,16 @@ if ($action == 'edit') { // Cree l'objet formulaire mail include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; $formmail = new FormMail($db); - $formmail->fromname = (GETPOSTISSET('fromname') ? $_POST['fromname'] : $conf->global->MAIN_MAIL_EMAIL_FROM); - $formmail->frommail = (GETPOSTISSET('frommail') ? $_POST['frommail'] : $conf->global->MAIN_MAIL_EMAIL_FROM); + $formmail->fromname = (GETPOSTISSET('fromname') ? GETPOST('fromname') : $conf->global->MAIN_MAIL_EMAIL_FROM); + $formmail->frommail = (GETPOSTISSET('frommail') ? GETPOST('frommail') : $conf->global->MAIN_MAIL_EMAIL_FROM); $formmail->trackid = (($action == 'testhtml') ? "testhtml" : "test"); $formmail->withfromreadonly = 0; $formmail->withsubstit = 0; $formmail->withfrom = 1; $formmail->witherrorsto = 1; - $formmail->withto = (!empty($_POST['sendto']) ? GETPOST('sendto', 'restricthtml') : ($user->email ? $user->email : 1)); - $formmail->withtocc = (!empty($_POST['sendtocc']) ? GETPOST('sendtocc', 'restricthtml') : 1); // ! empty to keep field if empty - $formmail->withtoccc = (!empty($_POST['sendtoccc']) ? GETPOST('sendtoccc', 'restricthtml') : 1); // ! empty to keep field if empty + $formmail->withto = (GETPOSTISSET('sendto') ? GETPOST('sendto', 'restricthtml') : ($user->email ? $user->email : 1)); + $formmail->withtocc = (GETPOSTISSET('sendtocc') ? GETPOST('sendtocc', 'restricthtml') : 1); + $formmail->withtoccc = (GETPOSTISSET('sendtoccc') ? GETPOST('sendtoccc', 'restricthtml') : 1); $formmail->withtopic = (GETPOSTISSET('subject') ? GETPOST('subject') : $langs->trans("Test")); $formmail->withtopicreadonly = 0; $formmail->withfile = 2; diff --git a/htdocs/admin/menus/edit.php b/htdocs/admin/menus/edit.php index a9e2fe9287f..bf4ac3f8979 100644 --- a/htdocs/admin/menus/edit.php +++ b/htdocs/admin/menus/edit.php @@ -152,32 +152,32 @@ if ($action == 'add') { $langs->load("errors"); $error = 0; - if (!$error && !$_POST['menu_handler']) { + if (!$error && !GETPOST('menu_handler')) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("MenuHandler")), null, 'errors'); $action = 'create'; $error++; } - if (!$error && !$_POST['type']) { + if (!$error && !GETPOST('type')) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Type")), null, 'errors'); $action = 'create'; $error++; } - if (!$error && !$_POST['url']) { + if (!$error && !GETPOST('url')) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("URL")), null, 'errors'); $action = 'create'; $error++; } - if (!$error && !$_POST['titre']) { + if (!$error && !GETPOST('titre')) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Title")), null, 'errors'); $action = 'create'; $error++; } - if (!$error && $_POST['menuId'] && $_POST['type'] == 'top') { + if (!$error && GETPOST('menuId') && GETPOST('type') == 'top') { setEventMessages($langs->trans("ErrorTopMenuMustHaveAParentWithId0"), null, 'errors'); $action = 'create'; $error++; } - if (!$error && !$_POST['menuId'] && $_POST['type'] == 'left') { + if (!$error && !GETPOST('menuId') && GETPOST('type') == 'left') { setEventMessages($langs->trans("ErrorLeftMenuMustHaveAParentId"), null, 'errors'); $action = 'create'; $error++; diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index 716dbc32ca7..0c53bebfc52 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -172,6 +172,10 @@ foreach ($modulesdir as $dir) { $moduleposition = '80'; // External modules at end by default } + if (empty($familyinfo[$familykey]['position'])) { + $familyinfo[$familykey]['position'] = '0'; + } + $orders[$i] = $familyinfo[$familykey]['position']."_".$familykey."_".$moduleposition."_".$j; // Sort by family, then by module position then number $dirmod[$i] = $dir; //print $i.'-'.$dirmod[$i].'
'; @@ -250,19 +254,19 @@ if (!empty($conf->global->$const_name)) { $text .= $langs->trans("Disabled"); } $tmp = $objMod->getLastActivationInfo(); -$authorid = $tmp['authorid']; +$authorid = (empty($tmp['authorid']) ? '' : $tmp['authorid']); if ($authorid > 0) { $tmpuser = new User($db); $tmpuser->fetch($authorid); $text .= '
'.$langs->trans("LastActivationAuthor").': '; $text .= $tmpuser->getNomUrl(1); } -$ip = $tmp['ip']; +$ip = (empty($tmp['ip']) ? '' : $tmp['ip']); if ($ip) { $text .= '
'.$langs->trans("LastActivationIP").': '; $text .= $ip; } -$lastactivationversion = $tmp['lastactivationversion']; +$lastactivationversion = (empty($tmp['lastactivationversion']) ? '' : $tmp['lastactivationversion']); if ($lastactivationversion) { $text .= '
'.$langs->trans("LastActivationVersion").': '; $text .= $lastactivationversion; diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 29d2335a0f9..0db1b26dc7d 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -48,7 +48,6 @@ if (empty($mode)) { $mode = 'common'; } $action = GETPOST('action', 'aZ09'); -//var_dump($_POST);exit; $value = GETPOST('value', 'alpha'); $page_y = GETPOST('page_y', 'int'); $search_keyword = GETPOST('search_keyword', 'alpha'); @@ -482,9 +481,9 @@ $deschelp = ''; if ($mode == 'common' || $mode == 'commonkanban') { $desc = $langs->trans("ModulesDesc", '{picto}'); $desc .= ' '.$langs->trans("ModulesDesc2", '{picto2}'); - $desc = str_replace('{picto}', img_picto('', 'switch_off'), $desc); - $desc = str_replace('{picto2}', img_picto('', 'setup'), $desc); - if (count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled + $desc = str_replace('{picto}', img_picto('', 'switch_off', 'class="size15x"'), $desc); + $desc = str_replace('{picto2}', img_picto('', 'setup', 'class="size15x"'), $desc); + if (!count($conf->modules) <= (empty($conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING) ? 1 : $conf->global->MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING)) { // If only minimal initial modules enabled $deschelp = '
'.$desc."

\n"; } } @@ -529,8 +528,8 @@ if ($mode == 'common' || $mode == 'commonkanban') { $moreforfilter .= ''; //$moreforfilter .= '
'.$moreinfo.' '.$moreinfo2.'
'; diff --git a/htdocs/admin/mrp.php b/htdocs/admin/mrp.php index 54efdc4df19..fac6a3f3d41 100644 --- a/htdocs/admin/mrp.php +++ b/htdocs/admin/mrp.php @@ -37,6 +37,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'mrp'; diff --git a/htdocs/admin/mrp_extrafields.php b/htdocs/admin/mrp_extrafields.php index d3c03056fef..768ec487165 100644 --- a/htdocs/admin/mrp_extrafields.php +++ b/htdocs/admin/mrp_extrafields.php @@ -84,7 +84,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php index b622ef192ce..c91af2fcc36 100644 --- a/htdocs/admin/multicurrency.php +++ b/htdocs/admin/multicurrency.php @@ -332,8 +332,8 @@ foreach ($TCurrency as &$currency) { print ''; print '1 '.$conf->currency.' = '; print ' '.$currency->code.' '; - print ' '; - print ''; + print ' '; + print ''; print '
'; print ''; } diff --git a/htdocs/admin/notification.php b/htdocs/admin/notification.php index f6d71fe6817..38245b5e204 100644 --- a/htdocs/admin/notification.php +++ b/htdocs/admin/notification.php @@ -1,9 +1,10 @@ * Copyright (C) 2005-2015 Laurent Destailleur - * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2013 Juanjo Menent * Copyright (C) 2015 Bahfir Abbes * Copyright (C) 2020 Thibault FOUCART + * Copyright (C) 2022 Anthony Berton * * 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 @@ -267,7 +268,8 @@ $constantes = array(); foreach ($listofnotifiedevents as $notifiedevent) { $label = $langs->trans("Notify_".$notifiedevent['code']); //!=$langs->trans("Notify_".$notifiedevent['code'])?$langs->trans("Notify_".$notifiedevent['code']):$notifiedevent['label']; $elementLabel = $langs->trans(ucfirst($notifiedevent['elementtype'])); - $model = $notifiedevent['elementtype'].'_send'; + + $model = $notifiedevent['elementtype']; if ($notifiedevent['elementtype'] == 'order_supplier') { $elementLabel = $langs->trans('SupplierOrder'); diff --git a/htdocs/admin/oauth.php b/htdocs/admin/oauth.php index 9bf5be2c294..a0d82d1d6bd 100644 --- a/htdocs/admin/oauth.php +++ b/htdocs/admin/oauth.php @@ -27,6 +27,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; +// $supportedoauth2array is defined into oauth.lib.php // Define $urlwithroot $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); @@ -96,10 +97,12 @@ print ''; $i = 0; -// $list is defined into oauth.lib.php +// $list is defined into oauth.lib.php to the list of supporter OAuth providers. foreach ($list as $key) { $supported = 0; - if (in_array($key[0], array_keys($supportedoauth2array))) { + $keyforsupportedoauth2array = $key[0]; + + if (in_array($keyforsupportedoauth2array, array_keys($supportedoauth2array))) { $supported = 1; } if (!$supported) { @@ -110,20 +113,23 @@ foreach ($list as $key) { print ''; // Api Name - $label = $langs->trans($key[0]); - print ''; + $label = $langs->trans($keyforsupportedoauth2array); print ''; + print ''; print ''; if ($supported) { - $redirect_uri = $urlwithroot.'/core/modules/oauth/'.$supportedoauth2array[$key[0]].'_oauthcallback.php'; + $redirect_uri = $urlwithroot.'/core/modules/oauth/'.$supportedoauth2array[$keyforsupportedoauth2array]['callbackfile'].'_oauthcallback.php'; print ''; print ''; - print ''; } else { print ''; diff --git a/htdocs/admin/oauthlogintokens.php b/htdocs/admin/oauthlogintokens.php index 8697b400a2b..73a9139f856 100644 --- a/htdocs/admin/oauthlogintokens.php +++ b/htdocs/admin/oauthlogintokens.php @@ -25,17 +25,13 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // This define $list +require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // This define $list and $supportedoauth2array require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; use OAuth\Common\Storage\DoliStorage; // Load translation files required by the page $langs->loadLangs(array('admin', 'printing', 'oauth')); -if (!$user->admin) { - accessforbidden(); -} - $action = GETPOST('action', 'aZ09'); $mode = GETPOST('mode', 'alpha'); $value = GETPOST('value', 'alpha'); @@ -50,6 +46,10 @@ if (!$mode) { $mode = 'setup'; } +if (!$user->admin) { + accessforbidden(); +} + /* * Action @@ -122,7 +122,7 @@ $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domai $form = new Form($db); -llxHeader('', $langs->trans("PrintingSetup")); +llxHeader('', $langs->trans("TokenManager")); $linkback = ''.$langs->trans("BackToModuleList").''; print load_fiche_titre($langs->trans('ConfigOAuth'), $linkback, 'title_setup'); @@ -140,7 +140,9 @@ if ($mode == 'setup' && $user->admin) { foreach ($list as $key) { $supported = 0; - if (in_array($key[0], array_keys($supportedoauth2array))) { + $keyforsupportedoauth2array = $key[0]; + + if (in_array($keyforsupportedoauth2array, array_keys($supportedoauth2array))) { $supported = 1; } if (!$supported) { @@ -148,34 +150,44 @@ if ($mode == 'setup' && $user->admin) { } - $OAUTH_SERVICENAME = 'Unknown'; - if ($key[0] == 'OAUTH_GITHUB_NAME') { - $OAUTH_SERVICENAME = 'GitHub'; + $OAUTH_SERVICENAME = empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name']; + + // Define $shortscope, $urltorenew, $urltodelete, $urltocheckperms + // TODO Use array $supportedoauth2array + if ($keyforsupportedoauth2array == 'OAUTH_GITHUB_NAME') { // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service). // We pass this param list in to 'state' because we need it before and after the redirect. $shortscope = 'user,public_repo'; $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltocheckperms = 'https://github.com/settings/applications/'; - } elseif ($key[0] == 'OAUTH_GOOGLE_NAME') { - $OAUTH_SERVICENAME = 'Google'; + } elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') { // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service). - // We pass this param list in to 'state' because we need it before and after the redirect. - $shortscope = 'userinfo_email,userinfo_profile,cloud_print'; - if (!empty($conf->global->OAUTH_GSUITE)) { + // List of scopes for Google are here: https://developers.google.com/identity/protocols/oauth2/scopes + // We pass this key list into the param 'state' because we need it before and after the redirect. + $shortscope = 'userinfo_email,userinfo_profile'; + $shortscope .= ',openid,email,profile'; // For openid connect + if (!empty($conf->printing->enabled)) { + $shortscope .= ',cloud_print'; + } + if (!empty($conf->global->OAUTH_GOOGLE_GSUITE)) { $shortscope .= ',admin_directory_user'; } - //$scope.=',gmail_full'; - $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + if (!empty($conf->global->OAUTH_GOOGLE_GMAIL)) { + $shortscope.=',gmail_full'; + } + + $oauthstateanticsrf = bin2hex(random_bytes(128/8)); + $_SESSION['oauthstateanticsrf'] = $shortscope.'-'.$oauthstateanticsrf; + + $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltocheckperms = 'https://security.google.com/settings/security/permissions'; - } elseif ($key[0] == 'OAUTH_STRIPE_TEST_NAME') { - $OAUTH_SERVICENAME = 'StripeTest'; + } elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_TEST_NAME') { $urltorenew = $urlwithroot.'/core/modules/oauth/stripetest_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = ''; $urltocheckperms = ''; - } elseif ($key[0] == 'OAUTH_STRIPE_LIVE_NAME') { - $OAUTH_SERVICENAME = 'StripeLive'; + } elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_LIVE_NAME') { $urltorenew = $urlwithroot.'/core/modules/oauth/stripelive_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = ''; $urltocheckperms = ''; @@ -230,11 +242,14 @@ if ($mode == 'setup' && $user->admin) { print ''; print ''; - print '
'; + print '
'; print '
'.$label.''; - if (!empty($key[3])) { - print $langs->trans($key[3]); + print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"'); + print $label; + print ''; + if (!empty($supportedoauth2array[$keyforsupportedoauth2array]['urlforapp'])) { + print $langs->trans($supportedoauth2array[$keyforsupportedoauth2array]['urlforapp']); } print '
'.$langs->trans("UseTheFollowingUrlAsRedirectURI").''; + print ''; print '
'."\n"; print ''; - print ''; + print ''; print ''; print ''; print "\n"; @@ -244,7 +259,7 @@ if ($mode == 'setup' && $user->admin) { //var_dump($key); print $langs->trans("OAuthIDSecret").''; print ''; print ''; @@ -259,7 +274,7 @@ if ($mode == 'setup' && $user->admin) { if (is_object($tokenobj)) { print $langs->trans("HasAccessToken"); } else { - print $langs->trans("NoAccessToken"); + print ''.$langs->trans("NoAccessToken").''; } print ''; print ''; print ''; print ''; print ''; + // Create third-party with contact if email not linked to a contact + print ''; + print ''; + print ''; + print ''; + /*if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { // Show logo for module @@ -327,33 +394,6 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { print $form->textwithpicto('', $langs->trans("TicketPublicInterfaceTextHelpMessageHelpAdmin"), 1, 'help'); print ''; - // Activate email creation to user - print ''; - print ''; - print ''; - print ''; - - // Texte de création d'un ticket - $mail_mesg_new = $conf->global->TICKET_MESSAGE_MAIL_NEW ? $conf->global->TICKET_MESSAGE_MAIL_NEW : $langs->trans('TicketNewEmailBody'); - print ''; - print ''; - // Url public interface $url_interface = $conf->global->TICKET_URL_PUBLIC_INTERFACE; print ''; + print '
'.$langs->trans($key[0]).''; + print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"'); + print $langs->trans($keyforsupportedoauth2array); + print '
'; - print $langs->trans("SeePreviousTab"); + print ''.$langs->trans("SeePreviousTab").''; print ''; print ''; @@ -346,7 +361,7 @@ if ($mode == 'setup' && $user->admin) { if ($mode == 'test' && $user->admin) { print $langs->trans('PrintTestDesc'.$driver)."

\n"; - print '
'; + print '
'; print ''; if (!empty($driver)) { require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; diff --git a/htdocs/admin/order_extrafields.php b/htdocs/admin/order_extrafields.php index e11ac077cc6..b66f004295d 100644 --- a/htdocs/admin/order_extrafields.php +++ b/htdocs/admin/order_extrafields.php @@ -88,7 +88,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/orderdet_extrafields.php b/htdocs/admin/orderdet_extrafields.php index c89ff3e3655..3f8102d076a 100644 --- a/htdocs/admin/orderdet_extrafields.php +++ b/htdocs/admin/orderdet_extrafields.php @@ -89,7 +89,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/pdf.php b/htdocs/admin/pdf.php index 33f8f5b87f2..8729fce71d3 100644 --- a/htdocs/admin/pdf.php +++ b/htdocs/admin/pdf.php @@ -4,7 +4,7 @@ * Copyright (C) 2005-2011 Regis Houssin * Copyright (C) 2012-2107 Juanjo Menent * Copyright (C) 2019 Ferran Marcet - * Copyright (C) 2021 Anthony Berton + * Copyright (C) 2021-2022 Anthony Berton * * 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 @@ -96,9 +96,9 @@ if ($action == 'update') { dolibarr_set_const($db, "MAIN_PDF_NO_RECIPENT_FRAME", GETPOST("MAIN_PDF_NO_RECIPENT_FRAME"), 'chaine', 0, '', $conf->entity); } - if (GETPOSTISSET('MAIN_PDF_HIDE_SENDER_NAME')) { + /*if (GETPOSTISSET('MAIN_PDF_HIDE_SENDER_NAME')) { dolibarr_set_const($db, "MAIN_PDF_HIDE_SENDER_NAME", GETPOST("MAIN_PDF_HIDE_SENDER_NAME"), 'chaine', 0, '', $conf->entity); - } + }*/ if (GETPOSTISSET('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT')) { dolibarr_set_const($db, "MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT", GETPOST("MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT"), 'chaine', 0, '', $conf->entity); @@ -166,6 +166,10 @@ if ($action == 'update') { dolibarr_set_const($db, "PDF_SHOW_LINK_TO_ONLINE_PAYMENT", GETPOST('PDF_SHOW_LINK_TO_ONLINE_PAYMENT', 'alpha'), 'chaine', 0, '', $conf->entity); } + if (GETPOSTISSET('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME')) { + dolibarr_set_const($db, "PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME", GETPOST('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME', 'alpha'), 'chaine', 0, '', $conf->entity); + } + if (GETPOSTISSET('PDF_USE_A')) { dolibarr_set_const($db, "PDF_USE_A", GETPOST('PDF_USE_A', 'alpha'), 'chaine', 0, '', $conf->entity); } @@ -307,9 +311,21 @@ print '
'; print '
'; print ''; +// Show sender name + +/* Set option as hidden because no need of this for 99.99% of users. Having it as hidden feature is enough. +print ''; +*/ + // Hide VAT Intra on address -print ''; - //Invert sender and recipient print ''; -print ''; - -print ''; - // Desc print ''; +// Swicth in Bold + +print ''; + +// Swicth in Bold + +print ''; + // SHOW_SUBPRODUCT_REF_IN_PDF - Option to show the detail of product ref for kits. print 'selectarray('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS', $arraydetailsforpdffoot, (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS) ? $conf->global->MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS : 0)); print ''; +// Show alias in thirdparty name + +/* Disabled because not yet completely implemented (does not work when we force a contact on object) +print '\n"; print "\n"; // Option to force stock to be enough before adding a line into document -if ($conf->invoice->enabled) { +if (!empty($conf->invoice->enabled)) { print ''; print ''; print '\n"; } -if ($conf->order->enabled) { +if (!empty($conf->order->enabled)) { print ''; print ''; print '\n"; } -if ($conf->expedition->enabled) { +if (!empty($conf->expedition->enabled)) { print ''; print ''; print '\n"; print ''; -if ($conf->banque->enabled) { +if (!empty($conf->banque->enabled)) { print '"; print getResultColumn($name, $activatedExtensions, $loadedExtensions, $functions); print ""; +$functions = ["easter_date"]; +$name = "Calendar"; + +print ""; +print ""; +print getResultColumn($name, $activatedExtensions, $loadedExtensions, $functions); +print ""; + +$functions = ["simplexml_load_string"]; +$name = "Xml"; + +print ""; +print ""; +print getResultColumn($name, $activatedExtensions, $loadedExtensions, $functions); +print ""; + if (empty($_SERVER["SERVER_ADMIN"]) || $_SERVER["SERVER_ADMIN"] != 'doliwamp@localhost') { $functions = ["locale_get_primary_language", "locale_get_region"]; $name = "Intl"; diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 118fab39f80..8a480ea49ca 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -99,6 +99,7 @@ if (!ini_get('session.cookie_samesite') || ini_get('session.cookie_samesite') == } print "
\n"; print "PHP open_basedir = ".(ini_get('open_basedir') ? ini_get('open_basedir') : yn(0).'   ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("ARestrictedPath").', '.$langs->transnoentitiesnoconv("Example").': '.$_SERVER["DOCUMENT_ROOT"].','.DOL_DATA_ROOT).')')."
\n"; +print "PHP short_open_tag = ".((empty(ini_get('short_open_tag')) || ini_get('short_open_tag') == 'Off') ? yn(0) : img_warning().' '.yn(0)).'   ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("No")).')'."
\n"; print "PHP allow_url_fopen = ".(ini_get('allow_url_fopen') ? img_picto($langs->trans("YouShouldSetThisToOff"), 'warning').' '.ini_get('allow_url_fopen') : yn(0)).'   ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("No")).")
\n"; print "PHP allow_url_include = ".(ini_get('allow_url_include') ? img_picto($langs->trans("YouShouldSetThisToOff"), 'warning').' '.ini_get('allow_url_include') : yn(0)).'   ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("No")).")
\n"; //print "PHP safe_mode = ".(ini_get('safe_mode') ? ini_get('safe_mode') : yn(0)).'   '.$langs->trans("Deprecated")." (removed in PHP 5.4)
\n"; @@ -265,10 +266,20 @@ print '
'; print '$dolibarr_main_restrict_ip: '; if (empty($dolibarr_main_restrict_ip)) { - print ''.$langs->trans("None").''; + print $langs->trans("None"); //print ' ('.$langs->trans("RecommendedValueIs", $langs->transnoentitiesnoconv("IPsOfUsers")).')'; +} else { + print $dolibarr_main_restrict_ip; } +print '
'; +print '$dolibarr_main_restrict_os_commands: '; +if (empty($dolibarr_main_restrict_os_commands)) { + print $langs->trans("None"); +} else { + print $dolibarr_main_restrict_os_commands; +} +print ' ('.$langs->trans("RecommendedValueIs", 'mysqldump, mysql, pg_dump, pgrestore').')'; print '
'; if (empty($conf->global->SECURITY_DISABLE_TEST_ON_OBFUSCATED_CONF)) { diff --git a/htdocs/admin/system/xcache.php b/htdocs/admin/system/xcache.php index 8bdca5be40e..4e2f881a14c 100644 --- a/htdocs/admin/system/xcache.php +++ b/htdocs/admin/system/xcache.php @@ -58,23 +58,6 @@ print $langs->trans("xcache.optimizer").': '.yn(ini_get('xcache.optimizer')).' ( print $langs->trans("xcache.stat").': '.yn(ini_get('xcache.stat')).'
'."\n"; print $langs->trans("xcache.coverager").': '.yn(ini_get('xcache.coverager')).'
'."\n"; -//print xcache_get(); -/* -$cacheinfos = array(); -for ($i = 0; $i < 10; $i ++) -{ - $data = xcache_info(XC_TYPE_PHP, $i); - $data['cacheid'] = $i; - $cacheinfos[] = $data; -} - -var_dump($cacheinfos); - -if ($action == 'clear') -{ - xcache_clear_cache(); -} -*/ // End of page llxFooter(); diff --git a/htdocs/admin/ticket.php b/htdocs/admin/ticket.php index 03fd647dd29..f902c3fb39b 100644 --- a/htdocs/admin/ticket.php +++ b/htdocs/admin/ticket.php @@ -26,6 +26,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"; require_once DOL_DOCUMENT_ROOT."/ticket/class/ticket.class.php"; require_once DOL_DOCUMENT_ROOT."/core/lib/ticket.lib.php"; +require_once DOL_DOCUMENT_ROOT."/core/class/html.formcategory.class.php"; // Load translation files required by the page $langs->loadLangs(array("admin", "ticket")); @@ -38,6 +39,8 @@ if (!$user->admin) { // Parameters $value = GETPOST('value', 'alpha'); $action = GETPOST('action', 'aZ09'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scandir', 'alpha'); $type = 'ticket'; @@ -96,82 +99,9 @@ if ($action == 'updateMask') { // par appel methode canBeActivated dolibarr_set_const($db, "TICKET_ADDON", $value, 'chaine', 0, '', $conf->entity); -} elseif ($action == 'setvar') { - include_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"; - - $notification_email = GETPOST('TICKET_NOTIFICATION_EMAIL_FROM', 'alpha'); - if (!empty($notification_email)) { - $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_EMAIL_FROM', $notification_email, 'chaine', 0, '', $conf->entity); - } else { - $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_EMAIL_FROM', '', 'chaine', 0, '', $conf->entity); - } - if (!($res > 0)) { - $error++; - } - - // altairis : differentiate notification email FROM and TO - $notification_email_to = GETPOST('TICKET_NOTIFICATION_EMAIL_TO', 'alpha'); - if (!empty($notification_email_to)) { - $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_EMAIL_TO', $notification_email_to, 'chaine', 0, '', $conf->entity); - } else { - $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_EMAIL_TO', '', 'chaine', 0, '', $conf->entity); - } - if (!($res > 0)) { - $error++; - } - - $mail_intro = GETPOST('TICKET_MESSAGE_MAIL_INTRO', 'restricthtml'); - if (!empty($mail_intro)) { - $res = dolibarr_set_const($db, 'TICKET_MESSAGE_MAIL_INTRO', $mail_intro, 'chaine', 0, '', $conf->entity); - } else { - $res = dolibarr_set_const($db, 'TICKET_MESSAGE_MAIL_INTRO', $langs->trans('TicketMessageMailIntroText'), 'chaine', 0, '', $conf->entity); - } - if (!($res > 0)) { - $error++; - } - - $mail_signature = GETPOST('TICKET_MESSAGE_MAIL_SIGNATURE', 'restricthtml'); - if (!empty($mail_signature)) { - $res = dolibarr_set_const($db, 'TICKET_MESSAGE_MAIL_SIGNATURE', $mail_signature, 'chaine', 0, '', $conf->entity); - } else { - $res = dolibarr_set_const($db, 'TICKET_MESSAGE_MAIL_SIGNATURE', $langs->trans('TicketMessageMailSignatureText'), 'chaine', 0, '', $conf->entity); - } - if (!($res > 0)) { - $error++; - } -} - -if ($action == 'setvarother') { - $param_must_exists = GETPOST('TICKET_EMAIL_MUST_EXISTS', 'alpha'); - $res = dolibarr_set_const($db, 'TICKET_EMAIL_MUST_EXISTS', $param_must_exists, 'chaine', 0, '', $conf->entity); - if (!($res > 0)) { - $error++; - } - - $param_disable_email = GETPOST('TICKET_DISABLE_NOTIFICATION_MAILS', 'alpha'); - $res = dolibarr_set_const($db, 'TICKET_DISABLE_NOTIFICATION_MAILS', $param_disable_email, 'chaine', 0, '', $conf->entity); - if (!($res > 0)) { - $error++; - } - - if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - $param_show_module_logo = GETPOST('TICKET_SHOW_MODULE_LOGO', 'alpha'); - $res = dolibarr_set_const($db, 'TICKET_SHOW_MODULE_LOGO', $param_show_module_logo, 'chaine', 0, '', $conf->entity); - if (!($res > 0)) { - $error++; - } - } - - if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - $param_notification_also_main_addressemail = GETPOST('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS', 'alpha'); - $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS', $param_notification_also_main_addressemail, 'chaine', 0, '', $conf->entity); - if (!($res > 0)) { - $error++; - } - } - - $param_limit_view = GETPOST('TICKET_LIMIT_VIEW_ASSIGNED_ONLY', 'alpha'); - $res = dolibarr_set_const($db, 'TICKET_LIMIT_VIEW_ASSIGNED_ONLY', $param_limit_view, 'chaine', 0, '', $conf->entity); +} elseif ($action == 'setvarworkflow') { + $param_auto_read = GETPOST('TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND', 'alpha'); + $res = dolibarr_set_const($db, 'TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND', $param_auto_read, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { $error++; } @@ -181,8 +111,94 @@ if ($action == 'setvarother') { if (!($res > 0)) { $error++; } -} + $param_limit_view = GETPOST('TICKET_LIMIT_VIEW_ASSIGNED_ONLY', 'alpha'); + $res = dolibarr_set_const($db, 'TICKET_LIMIT_VIEW_ASSIGNED_ONLY', $param_limit_view, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } + + if (GETPOSTISSET('product_category_id')) { + $param_ticket_product_category = GETPOST('product_category_id', 'int'); + $res = dolibarr_set_const($db, 'TICKET_PRODUCT_CATEGORY', $param_ticket_product_category, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } + } + + $param_delay_first_response = GETPOST('delay_first_response', 'int'); + $res = dolibarr_set_const($db, 'TICKET_DELAY_BEFORE_FIRST_RESPONSE', $param_delay_first_response, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } + + $param_delay_between_responses = GETPOST('delay_between_responses', 'int'); + $res = dolibarr_set_const($db, 'TICKET_DELAY_SINCE_LAST_RESPONSE', $param_delay_between_responses, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } + + $param_auto_notify_close = GETPOST('TICKET_NOTIFY_AT_CLOSING', 'alpha'); + $res = dolibarr_set_const($db, 'TICKET_NOTIFY_AT_CLOSING', $param_auto_notify_close, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } +} elseif ($action == 'setvar') { + include_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"; + + $notification_email = GETPOST('TICKET_NOTIFICATION_EMAIL_FROM', 'alpha'); + $notification_email_description = "Sender of ticket replies sent from Dolibarr"; + if (!empty($notification_email)) { + $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_EMAIL_FROM', $notification_email, 'chaine', 0, $notification_email_description, $conf->entity); + } else { // If an empty e-mail address is providen, use the global "FROM" since an empty field will cause other issues + $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_EMAIL_FROM', $conf->global->MAIN_MAIL_EMAIL_FROM, 'chaine', 0, $notification_email_description, $conf->entity); + } + if (!($res > 0)) { + $error++; + } + + // altairis : differentiate notification email FROM and TO + $notification_email_to = GETPOST('TICKET_NOTIFICATION_EMAIL_TO', 'alpha'); + $notification_email_to_description = "Notified e-mail for ticket replies sent from Dolibarr"; + if (!empty($notification_email_to)) { + $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_EMAIL_TO', $notification_email_to, 'chaine', 0, $notification_email_to_description, $conf->entity); + } else { + $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_EMAIL_TO', '', 'chaine', 0, $notification_email_to_description, $conf->entity); + } + if (!($res > 0)) { + $error++; + } + + $mail_intro = GETPOST('TICKET_MESSAGE_MAIL_INTRO', 'restricthtml'); + $mail_intro_description = "Introduction text of ticket replies sent from Dolibarr"; + if (!empty($mail_intro)) { + $res = dolibarr_set_const($db, 'TICKET_MESSAGE_MAIL_INTRO', $mail_intro, 'chaine', 0, $mail_intro_description, $conf->entity); + } else { + $res = dolibarr_set_const($db, 'TICKET_MESSAGE_MAIL_INTRO', '', 'chaine', 0, $mail_intro_description, $conf->entity); + } + if (!($res > 0)) { + $error++; + } + + $mail_signature = GETPOST('TICKET_MESSAGE_MAIL_SIGNATURE', 'restricthtml'); + $signature_description = "Signature of ticket replies sent from Dolibarr"; + if (!empty($mail_signature)) { + $res = dolibarr_set_const($db, 'TICKET_MESSAGE_MAIL_SIGNATURE', $mail_signature, 'chaine', 0, $signature_description, $conf->entity); + } else { + $res = dolibarr_set_const($db, 'TICKET_MESSAGE_MAIL_SIGNATURE', '', 'chaine', 0, $signature_description, $conf->entity); + } + if (!($res > 0)) { + $error++; + } + + if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { + $param_notification_also_main_addressemail = GETPOST('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS', 'alpha'); + $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS', $param_notification_also_main_addressemail, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } + } +} /* @@ -191,7 +207,7 @@ if ($action == 'setvarother') { $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); -$form = new Form($db); +$formcategory = new FormCategory($db); $help_url = "FR:Module_Ticket"; $page_name = "TicketSetup"; @@ -298,7 +314,7 @@ foreach ($dirmodels as $reldir) { } print ''; print ''; @@ -343,8 +359,8 @@ if ($resql) { print '
'; -print "
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("MAIN_PDF_HIDE_SENDER_NAME").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('MAIN_PDF_HIDE_SENDER_NAME'); +} else { + print $form->selectyesno('MAIN_PDF_HIDE_SENDER_NAME', (!empty($conf->global->MAIN_PDF_HIDE_SENDER_NAME)) ? $conf->global->MAIN_PDF_HIDE_SENDER_NAME : 0, 1); +} +print '
'.$langs->trans("ShowVATIntaInAddress").''; +print '
'.$langs->trans("ShowVATIntaInAddress").' - '.$langs->trans("ThirdPartyAddress").''; if ($conf->use_javascript_ajax) { print ajax_constantonoff('MAIN_TVAINTRA_NOT_IN_ADDRESS'); } else { @@ -328,7 +344,7 @@ for ($i = 1; $i <= 6; $i++) { $pid = img_warning().' '.$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CompanyCountry")).''; } if ($pid) { - print '
'.$langs->trans("ShowProfIdInAddress").' - '.$pid.''; + print '
'.$langs->trans("ShowProfIdInAddress").' - '.$pid.' - '.$langs->trans("ThirdPartyAddress").''; $keyforconstant = 'MAIN_PROFID'.$i.'_IN_ADDRESS'; if ($conf->use_javascript_ajax) { print ajax_constantonoff($keyforconstant); @@ -358,16 +374,6 @@ if ($conf->use_javascript_ajax) { print $form->selectarray("MAIN_PDF_NO_RECIPENT_FRAME", $arrval, $conf->global->MAIN_PDF_NO_RECIPENT_FRAME); } -// Show sender name - -print '
'.$langs->trans("MAIN_PDF_HIDE_SENDER_NAME").''; -if ($conf->use_javascript_ajax) { - print ajax_constantonoff('MAIN_PDF_HIDE_SENDER_NAME'); -} else { - print $form->selectyesno('MAIN_PDF_HIDE_SENDER_NAME', (!empty($conf->global->MAIN_PDF_HIDE_SENDER_NAME)) ? $conf->global->MAIN_PDF_HIDE_SENDER_NAME : 0, 1); -} -print '
'.$langs->trans("SwapSenderAndRecipientOnPDF").''; @@ -506,22 +512,6 @@ if ($conf->use_javascript_ajax) { } print '
'.$langs->trans("BoldLabelOnPDF").''; -if ($conf->use_javascript_ajax) { - print ajax_constantonoff('PDF_BOLD_PRODUCT_LABEL'); -} else { - print $form->selectyesno('PDF_BOLD_PRODUCT_LABEL', (!empty($conf->global->PDF_BOLD_PRODUCT_LABEL)) ? $conf->global->PDF_BOLD_PRODUCT_LABEL : 0, 1); -} -print '
'.$langs->trans("BoldRefAndPeriodOnPDF").''; -if ($conf->use_javascript_ajax) { - print ajax_constantonoff('PDF_BOLD_PRODUCT_REF_AND_PERIOD'); -} else { - print $form->selectyesno('PDF_BOLD_PRODUCT_REF_AND_PERIOD', (!empty($conf->global->PDF_BOLD_PRODUCT_REF_AND_PERIOD)) ? $conf->global->PDF_BOLD_PRODUCT_REF_AND_PERIOD : 0, 1); -} -print '
'.$langs->trans("HideDescOnPDF").''; @@ -542,6 +532,26 @@ if ($conf->use_javascript_ajax) { } print '
'.$langs->trans("BoldLabelOnPDF").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('PDF_BOLD_PRODUCT_LABEL'); +} else { + print $form->selectyesno('PDF_BOLD_PRODUCT_LABEL', (!empty($conf->global->PDF_BOLD_PRODUCT_LABEL)) ? $conf->global->PDF_BOLD_PRODUCT_LABEL : 0, 1); +} +print '
'.$langs->trans("BoldRefAndPeriodOnPDF").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('PDF_BOLD_PRODUCT_REF_AND_PERIOD'); +} else { + print $form->selectyesno('PDF_BOLD_PRODUCT_REF_AND_PERIOD', (!empty($conf->global->PDF_BOLD_PRODUCT_REF_AND_PERIOD)) ? $conf->global->PDF_BOLD_PRODUCT_REF_AND_PERIOD : 0, 1); +} +print '
'.$langs->trans("SHOW_SUBPRODUCT_REF_IN_PDF", $langs->transnoentitiesnoconv("AssociatedProductsAbility"), $langs->transnoentitiesnoconv("Products")).''; @@ -558,6 +568,16 @@ print '
'.$langs->trans("ShowDetailsInPDFPageFoot").'
'.$langs->trans("PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME").''; +if ($conf->use_javascript_ajax) { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("THIRDPARTY_ALIAS"), '2' => $langs->trans("ALIAS_THIRDPARTY")); + print $form->selectarray("PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME", $arrval, getDolGlobalInt('PDF_INCLUDE_ALIAS_IN_THIRDPARTY_NAME')); +} +*/ + // Show online payment link on invoices print '
'.$langs->trans("PDF_SHOW_LINK_TO_ONLINE_PAYMENT").''; diff --git a/htdocs/admin/pdf_other.php b/htdocs/admin/pdf_other.php index 72acf7fbf4f..5a51535e04d 100644 --- a/htdocs/admin/pdf_other.php +++ b/htdocs/admin/pdf_other.php @@ -60,6 +60,9 @@ if ($action == 'update') { if (GETPOSTISSET('MAIN_DOCUMENTS_WITH_PICTURE_WIDTH')) { dolibarr_set_const($db, "MAIN_DOCUMENTS_WITH_PICTURE_WIDTH", GETPOST("MAIN_DOCUMENTS_WITH_PICTURE_WIDTH", 'int'), 'chaine', 0, '', $conf->entity); } + if (GETPOSTISSET('INVOICE_ADD_ZATCA_QR_CODE')) { + dolibarr_set_const($db, "INVOICE_ADD_ZATCA_QR_CODE", GETPOST("INVOICE_ADD_ZATCA_QR_CODE", 'int'), 'chaine', 0, '', $conf->entity); + } setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); @@ -90,19 +93,19 @@ $tooltiptext = ''; print ''.$form->textwithpicto($langs->trans("PDFOtherDesc"), $tooltiptext)."
\n"; print "
\n"; +print '
'; +print ''; +print ''; + if (!empty($conf->propal->enabled)) { print load_fiche_titre($langs->trans("Proposal"), '', ''); - print ''; - print ''; - print ''; - print '
'; print ''; print ''; - print ''; + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'.$langs->trans("MAIN_GENERATE_PROPOSALS_WITH_PICTURE"); - print ' ('.$langs->trans("RandomlySelectedIfSeveral").')'; + print '
'; + print $form->textwithpicto($langs->trans("MAIN_GENERATE_PROPOSALS_WITH_PICTURE"), $langs->trans("RandomlySelectedIfSeveral")); print ''; if ($conf->use_javascript_ajax) { print ajax_constantonoff('MAIN_GENERATE_PROPOSALS_WITH_PICTURE'); @@ -112,6 +115,29 @@ if (!empty($conf->propal->enabled)) { } print '
'; + print '
'; +} + + +if (!empty($conf->facture->enabled)) { + print load_fiche_titre($langs->trans("Invoices"), '', ''); + + print '
'; + print ''; + print ''; + + print ''; + /* print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +*/ + /* print ''; print ''; diff --git a/htdocs/admin/reception_extrafields.php b/htdocs/admin/reception_extrafields.php index 8e4205a7bdc..aa83fca230c 100644 --- a/htdocs/admin/reception_extrafields.php +++ b/htdocs/admin/reception_extrafields.php @@ -94,7 +94,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/reception_setup.php b/htdocs/admin/reception_setup.php index 218cc1ef853..26300ece329 100644 --- a/htdocs/admin/reception_setup.php +++ b/htdocs/admin/reception_setup.php @@ -36,6 +36,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'reception'; diff --git a/htdocs/admin/resource.php b/htdocs/admin/resource.php index ebd1269f74a..1d3e29c9cd4 100644 --- a/htdocs/admin/resource.php +++ b/htdocs/admin/resource.php @@ -78,7 +78,7 @@ print '
'; print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + print $form->textwithpicto($langs->trans("INVOICE_ADD_ZATCA_QR_CODE"), $langs->trans("INVOICE_ADD_ZATCA_QR_CODEMore")); + print ''; + if ($conf->use_javascript_ajax) { + print ajax_constantonoff('INVOICE_ADD_ZATCA_QR_CODE'); + } else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("INVOICE_ADD_ZATCA_QR_CODE", $arrval, $conf->global->INVOICE_ADD_ZATCA_QR_CODE); + } + print '
'.$langs->trans("MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING").''; if ($conf->use_javascript_ajax) { diff --git a/htdocs/admin/propal.php b/htdocs/admin/propal.php index 22ce045a7ab..3bc745a1101 100644 --- a/htdocs/admin/propal.php +++ b/htdocs/admin/propal.php @@ -43,6 +43,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'propal'; @@ -196,6 +198,37 @@ if ($action == 'updateMask') { // par appel methode canBeActivated dolibarr_set_const($db, "PROPALE_ADDON", $value, 'chaine', 0, '', $conf->entity); +} elseif (preg_match('/set_(.*)/', $action, $reg)) { + $code = $reg[1]; + $value = (GETPOST($code) ? GETPOST($code) : 1); + + $res = dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } + + if ($error) { + setEventMessages($langs->trans('Error'), null, 'errors'); + } else { + setEventMessages($langs->trans('SetupSaved'), null, 'mesgs'); + header("Location: " . $_SERVER["PHP_SELF"]); + exit(); + } +} elseif (preg_match('/del_(.*)/', $action, $reg)) { + $code = $reg[1]; + $res = dolibarr_del_const($db, $code, $conf->entity); + + if (!($res > 0)) { + $error++; + } + + if ($error) { + setEventMessages($langs->trans('Error'), null, 'errors'); + } else { + setEventMessages($langs->trans('SetupSaved'), null, 'mesgs'); + header("Location: " . $_SERVER["PHP_SELF"]); + exit(); + } } @@ -591,6 +624,28 @@ print ''; +print ''; +print '
' . $langs->trans('DefaultPuttingPricesUpToDate').''; +if (!empty($conf->use_javascript_ajax)) { + print ajax_constantonoff('PROPOSAL_CLONE_UPDATE_PRICES', array(), $conf->entity, 0, 0, 1, 0); +} else { + if (empty($conf->global->PROPOSAL_CLONE_UPDATE_PRICES)) { + print '' . img_picto($langs->trans('Disabled'), 'switch_off') . ''; + } else { + print '' . img_picto($langs->trans('Enabled'), 'switch_on') . ''; + } +} +print '
'; print ''; print ''."\n"; -print ''."\n"; +print ''."\n"; print ''; @@ -106,6 +106,15 @@ if (empty($conf->use_javascript_ajax)) { print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +/* print ''; print ''; print ''; print ''; print ''; - - -print ''; -print ''; -print ''; -print ''; -print ''; +*/ print '
'.$langs->trans("Parameters").''.$langs->trans("Value").''.$langs->trans("Value").'
'.$langs->trans('EnableResourceUsedInEventCheck').''; +echo ajax_constantonoff('RESOURCE_USED_IN_EVENT_CHECK'); +print '
'.$langs->trans('DisabledResourceLinkUser').''; @@ -122,15 +131,7 @@ echo ajax_constantonoff('RESOURCE_HIDE_ADD_CONTACT_THIPARTY'); print '
'.$langs->trans('EnableResourceUsedInEventCheck').''; -echo ajax_constantonoff('RESOURCE_USED_IN_EVENT_CHECK'); -print '
'; print '
'; diff --git a/htdocs/admin/resource_extrafields.php b/htdocs/admin/resource_extrafields.php index c4967f75313..068ae6f02d1 100644 --- a/htdocs/admin/resource_extrafields.php +++ b/htdocs/admin/resource_extrafields.php @@ -74,7 +74,6 @@ llxHeader('', $langs->trans("ResourceSetup")); $linkback = ''.$langs->trans("BackToModuleList").''; print load_fiche_titre($langs->trans("ResourceSetup"), $linkback, 'title_setup'); -print "
\n"; $head = resource_admin_prepare_head(); @@ -88,7 +87,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/sms.php b/htdocs/admin/sms.php index 05abf8c3995..19a94d05dd8 100644 --- a/htdocs/admin/sms.php +++ b/htdocs/admin/sms.php @@ -62,7 +62,7 @@ if ($action == 'update' && !$cancel) { // Send sms -if ($action == 'send' && !$_POST['cancel']) { +if ($action == 'send' && !$cancel) { $error = 0; $smsfrom = ''; diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index e8f59727c07..a5e83155f03 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -394,7 +394,7 @@ print "
'.$langs->trans("StockMustBeEnoughForInvoice").''; @@ -408,7 +408,7 @@ if ($conf->invoice->enabled) { print "
'.$langs->trans("StockMustBeEnoughForOrder").''; @@ -422,7 +422,7 @@ if ($conf->order->enabled) { print "
'.$langs->trans("StockMustBeEnoughForShipment").''; diff --git a/htdocs/admin/stocktransfer.php b/htdocs/admin/stocktransfer.php new file mode 100644 index 00000000000..541947bf442 --- /dev/null +++ b/htdocs/admin/stocktransfer.php @@ -0,0 +1,484 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 SuperAdmin + * + * 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 . + */ + +/** + * \file stocktransfer/admin/setup.php + * \ingroup stocktransfer + * \brief StockTransfer setup page. + */ + +// Load Dolibarr environment +$res = 0; +// Try main.inc.php into web root known defined into CONTEXT_DOCUMENT_ROOT (not always defined) +if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php"; +// Try main.inc.php into web root detected using web root calculated from SCRIPT_FILENAME +$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1; +while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; } +if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php"; +if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php"; +// Try main.inc.php using relative path +if (!$res && file_exists("../main.inc.php")) $res = @include "../main.inc.php"; +if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php"; +if (!$res && file_exists("../../../main.inc.php")) $res = @include "../../../main.inc.php"; +if (!$res) die("Include of main fails"); + +global $langs, $user; + +// Libraries +require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"; +require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/class/stocktransfer.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/stock/stocktransfer/lib/stocktransfer.lib.php'; + +// Translations +$langs->loadLangs(array("admin", "stocks")); + +// Access control +if (!$user->admin) accessforbidden(); + +// Parameters +$action = GETPOST('action', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); + +$value = GETPOST('value', 'alpha'); + +$arrayofparameters = array( + 'STOCKTRANSFER_MYPARAM1'=>array('css'=>'minwidth200', 'enabled'=>1), + 'STOCKTRANSFER_MYPARAM2'=>array('css'=>'minwidth500', 'enabled'=>1) +); + +$error = 0; +$setupnotempty = 0; + + +/* + * Actions + */ + +if ((float) DOL_VERSION >= 6) { + include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; +} + +if ($action == 'updateMask') { + $maskconststocktransfer = GETPOST('maskconststocktransfer', 'alpha'); + $maskstocktransfer = GETPOST('maskStockTransfer', 'alpha'); + + if ($maskconststocktransfer) $res = dolibarr_set_const($db, $maskconststocktransfer, $maskstocktransfer, 'chaine', 0, '', $conf->entity); + + if (!$res > 0) $error++; + + if (!$error) { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } else { + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} elseif ($action == 'specimen') { + $modele = GETPOST('module', 'alpha'); + $tmpobjectkey = 'StockTransfer'; + + $tmpobject = new $tmpobjectkey($db); + $tmpobject->initAsSpecimen(); + + // Search template files + $file = ''; $classname = ''; $filefound = 0; + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $file = dol_buildpath($reldir."core/modules/stocktransfer/doc/pdf_".$modele.".modules.php", 0); + if (file_exists($file)) { + $filefound = 1; + $classname = "pdf_".$modele; + break; + } + } + + if ($filefound) { + require_once $file; + + $module = new $classname($db); + + if ($module->write_file($tmpobject, $langs) > 0) { + header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf"); + return; + } else { + setEventMessages($module->error, null, 'errors'); + dol_syslog($module->error, LOG_ERR); + } + } else { + setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors'); + dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); + } +} elseif ($action == 'set') { // Activate a model + $ret = addDocumentModel($value, 'stocktransfer', $label, $scandir); +} elseif ($action == 'del') { + $tmpobjectkey = 'StockTransfer'; + + $ret = delDocumentModel($value, 'stocktransfer'); + if ($ret > 0) { + $constforval = strtoupper($tmpobjectkey).'_ADDON_PDF'; + if ($conf->global->$constforval == "$value") dolibarr_del_const($db, $constforval, $conf->entity); + } +} elseif ($action == 'setdoc') { // Set default model + $tmpobjectkey = 'StockTransfer'; + $constforval = strtoupper($tmpobjectkey).'_ADDON_PDF'; + if (dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity)) { + // The constant that was read before the new set + // We therefore requires a variable to have a coherent view + $conf->global->$constforval = $value; + } + + // On active le modele + $ret = delDocumentModel($value, 'stocktransfer'); + if ($ret > 0) { + $ret = addDocumentModel($value, 'stocktransfer', $label, $scandir); + } +} elseif ($action == 'setmod') { + // TODO Check if numbering module chosen can be activated + // by calling method canBeActivated + $tmpobjectkey = 'StockTransfer'; + $constforval = 'STOCKTRANSFER_'.strtoupper($tmpobjectkey)."_ADDON"; + dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity); +} + + + +/* + * View + */ + +$form = new Form($db); + +$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + +$page_name = "StockTransferSetup"; +llxHeader('', $langs->trans($page_name)); + +// Subheader +$linkback = ''.$langs->trans("BackToModuleList").''; + +print load_fiche_titre($langs->trans($page_name), $linkback, 'stock'); + +// Configuration header +$head = stocktransferAdminPrepareHead(); +print dol_get_fiche_head($head, 'settings', '', -1, "stocktransfer@stocktransfer"); + +// Setup page goes here +print ''.$langs->trans("StockTransferSetupPage").''; + + +/*if ($action == 'edit') +{ + print ''; + print ''; + print ''; + + print ''; + print ''; + + foreach ($arrayofparameters as $key => $val) + { + print ''; + } + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + $tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : ''); + print $form->textwithpicto($langs->trans($key), $tooltiphelp); + print '
'; + + print '
'; + print ''; + print '
'; + + print ''; + print '
'; +} else { + if (!empty($arrayofparameters)) + { + print ''; + print ''; + + foreach ($arrayofparameters as $key => $val) + { + $setupnotempty++; + + print ''; + } + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + $tooltiphelp = (($langs->trans($key.'Tooltip') != $key.'Tooltip') ? $langs->trans($key.'Tooltip') : ''); + print $form->textwithpicto($langs->trans($key), $tooltiphelp); + print ''.$conf->global->$key.'
'; + + print '
'; + print ''.$langs->trans("Modify").''; + print '
'; + } + else + { + print '
'.$langs->trans("NothingToSetup"); + } +}*/ + + +$moduledir = 'stocktransfer'; +$myTmpObjects = array(); +$myTmpObjects[$moduledir]=array('includerefgeneration'=>1, 'includedocgeneration'=>1); + +foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { + if ($myTmpObjectKey == 'MyObject') continue; + if ($myTmpObjectArray['includerefgeneration']) { + /* + * Orders Numbering model + */ + $setupnotempty++; + + print load_fiche_titre($langs->trans("NumberingModules", $myTmpObjectKey), '', ''); + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''."\n"; + + clearstatcache(); + + foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/".$moduledir); + + if (is_dir($dir)) { + $handle = opendir($dir); + if (is_resource($handle)) { + while (($file = readdir($handle)) !== false) { + if (strpos($file, 'mod_'.strtolower($myTmpObjectKey).'_') === 0 && substr($file, dol_strlen($file) - 3, 3) == 'php') { + $file = substr($file, 0, dol_strlen($file) - 4); + + require_once $dir.'/'.$file.'.php'; + + $module = new $file($db); + + // Show modules according to features level + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; + + if ($module->isEnabled()) { + dol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php'); + + print ''; + + // Show example of numbering model + print ''."\n"; + + print ''; + + $mytmpinstance = new $myTmpObjectKey($db); + $mytmpinstance->initAsSpecimen(); + + // Info + $htmltooltip = ''; + $htmltooltip .= ''.$langs->trans("Version").': '.$module->getVersion().'
'; + + $nextval = $module->getNextValue($mytmpinstance); + if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval + $htmltooltip .= ''.$langs->trans("NextValue").': '; + if ($nextval) { + if (preg_match('/^Error/', $nextval) || $nextval == 'NotConfigured') + $nextval = $langs->trans($nextval); + $htmltooltip .= $nextval.'
'; + } else { + $htmltooltip .= $langs->trans($module->error).'
'; + } + } + + print ''; + + print "\n"; + } + } + } + closedir($handle); + } + } + } + print "
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Status").''.$langs->trans("ShortInfo").'
'.$module->name."\n"; + print $module->info(); + print ''; + $tmp = $module->getExample(); + if (preg_match('/^Error/', $tmp)) print '
'.$langs->trans($tmp).'
'; + elseif ($tmp == 'NotConfigured') print $langs->trans($tmp); + else print $tmp; + print '
'; + $constforvar = 'STOCKTRANSFER_'.strtoupper($myTmpObjectKey).'_ADDON'; + if ($conf->global->$constforvar == $file) { + print img_picto($langs->trans("Activated"), 'switch_on'); + } else { + print ''; + print img_picto($langs->trans("Disabled"), 'switch_off'); + print ''; + } + print ''; + print $form->textwithpicto('', $htmltooltip, 1, 0); + print '

\n"; + } + + if ($myTmpObjectArray['includedocgeneration']) { + /* + * Document templates generators + */ + $setupnotempty++; + $type = strtolower($myTmpObjectKey); + + print load_fiche_titre($langs->trans("DocumentModules", $myTmpObjectKey), '', ''); + + // Load array def with activated templates + $def = array(); + $sql = "SELECT nom"; + $sql .= " FROM ".MAIN_DB_PREFIX."document_model"; + $sql .= " WHERE type = '".$db->escape($type)."'"; + $sql .= " AND entity = ".$conf->entity; + $resql = $db->query($sql); + if ($resql) { + $i = 0; + $num_rows = $db->num_rows($resql); + while ($i < $num_rows) { + $array = $db->fetch_array($resql); + array_push($def, $array[0]); + $i++; + } + } else { + dol_print_error($db); + } + + print "\n"; + print "\n"; + print ''; + print ''; + print '\n"; + print '\n"; + print ''; + print ''; + print "\n"; + + clearstatcache(); + + foreach ($dirmodels as $reldir) { + foreach (array('', '/doc') as $valdir) { + $realpath = $reldir."core/modules/".$moduledir.$valdir; + $dir = dol_buildpath($realpath); + + if (is_dir($dir)) { + $handle = opendir($dir); + if (is_resource($handle)) { + while (($file = readdir($handle)) !== false) { + $filelist[] = $file; + } + closedir($handle); + arsort($filelist); + + foreach ($filelist as $file) { + if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) { + if (file_exists($dir.'/'.$file)) { + $name = substr($file, 4, dol_strlen($file) - 16); + $classname = substr($file, 0, dol_strlen($file) - 12); + + require_once $dir.'/'.$file; + $module = new $classname($db); + + $modulequalified = 1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified = 0; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified = 0; + + if ($modulequalified) { + print ''; + + // Active + if (in_array($name, $def)) { + print ''; + } else { + print '"; + } + + // Default + print ''; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip .= '
'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown")); + if ($module->type == 'pdf') { + $htmltooltip .= '
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + } + $htmltooltip .= '
'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file; + + $htmltooltip .= '

'.$langs->trans("FeaturesSupported").':'; + $htmltooltip .= '
'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1); + $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); + + print ''; + + // Preview + print ''; + + print "\n"; + } + } + } + } + } + } + } + } + + print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
'; + print (empty($module->name) ? $name : $module->name); + print "\n"; + if (method_exists($module, 'info')) print $module->info($langs); + else print $module->description; + print ''."\n"; + print ''; + print img_picto($langs->trans("Enabled"), 'switch_on'); + print ''; + print ''."\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; + print "'; + $constforvar = strtoupper($myTmpObjectKey).'_ADDON_PDF'; + if ($conf->global->$constforvar == $name) { + print img_picto($langs->trans("Default"), 'on'); + } else { + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; + } + print ''; + print $form->textwithpicto('', $htmltooltip, 1, 0); + print ''; + if ($module->type == 'pdf') { + print ''.img_object($langs->trans("Preview"), 'generic').''; + } else { + print img_object($langs->trans("PreviewNotAvailable"), 'generic'); + } + print '
'; + } +} + +if (empty($setupnotempty)) { + print '
'.$langs->trans("NothingToSetup"); +} + +// Page end +print dol_get_fiche_end(); + +llxFooter(); +$db->close(); diff --git a/htdocs/admin/supplier_order.php b/htdocs/admin/supplier_order.php index 808528cdc0a..0da79845d14 100644 --- a/htdocs/admin/supplier_order.php +++ b/htdocs/admin/supplier_order.php @@ -43,6 +43,8 @@ if (!$user->admin) { $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'); diff --git a/htdocs/admin/supplier_payment.php b/htdocs/admin/supplier_payment.php index b31e4c9a433..a41f9fdf80c 100644 --- a/htdocs/admin/supplier_payment.php +++ b/htdocs/admin/supplier_payment.php @@ -37,6 +37,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scandir', 'alpha'); $type = 'supplier_payment'; diff --git a/htdocs/admin/supplier_proposal.php b/htdocs/admin/supplier_proposal.php index 6e3f190aeb6..80f2c6a62f4 100644 --- a/htdocs/admin/supplier_proposal.php +++ b/htdocs/admin/supplier_proposal.php @@ -38,6 +38,8 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); $type = 'supplier_proposal'; @@ -496,7 +498,7 @@ print '
'; print $langs->trans("BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_PROPOSAL").' '; if (!empty($conf->use_javascript_ajax)) { diff --git a/htdocs/admin/supplierinvoice_extrafields.php b/htdocs/admin/supplierinvoice_extrafields.php index 4121073dec2..6105e6a716b 100644 --- a/htdocs/admin/supplierinvoice_extrafields.php +++ b/htdocs/admin/supplierinvoice_extrafields.php @@ -89,7 +89,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/supplierinvoicedet_extrafields.php b/htdocs/admin/supplierinvoicedet_extrafields.php index 0156eed5072..3bdf8e1e8cc 100644 --- a/htdocs/admin/supplierinvoicedet_extrafields.php +++ b/htdocs/admin/supplierinvoicedet_extrafields.php @@ -91,7 +91,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/supplierorder_extrafields.php b/htdocs/admin/supplierorder_extrafields.php index 5a49c8f5bfd..e45f8d63cc1 100644 --- a/htdocs/admin/supplierorder_extrafields.php +++ b/htdocs/admin/supplierorder_extrafields.php @@ -89,7 +89,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/supplierorderdet_extrafields.php b/htdocs/admin/supplierorderdet_extrafields.php index 07f223d59c8..8fd2516a41d 100644 --- a/htdocs/admin/supplierorderdet_extrafields.php +++ b/htdocs/admin/supplierorderdet_extrafields.php @@ -90,7 +90,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/system/filecheck.php b/htdocs/admin/system/filecheck.php index 10edae1a24b..58c27cbb1e4 100644 --- a/htdocs/admin/system/filecheck.php +++ b/htdocs/admin/system/filecheck.php @@ -407,10 +407,10 @@ if (empty($error) && !empty($xml)) { $checksumget = md5(join(',', $checksumconcat)); $checksumtoget = trim((string) $xml->dolibarr_htdocs_dir_checksum); - /*var_dump(count($file_list['added'])); - var_dump($checksumget); - var_dump($checksumtoget); - var_dump($checksumget == $checksumtoget);*/ + //var_dump(count($file_list['added'])); + //var_dump($checksumget); + //var_dump($checksumtoget); + //var_dump($checksumget == $checksumtoget); $resultcomment = ''; diff --git a/htdocs/admin/system/phpinfo.php b/htdocs/admin/system/phpinfo.php index ac51ce33dc3..c9324565e5b 100644 --- a/htdocs/admin/system/phpinfo.php +++ b/htdocs/admin/system/phpinfo.php @@ -183,6 +183,22 @@ print "".$name."
".$name."
".$name."
'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $formcategory->textwithpicto('', $htmltooltip, 1, 0); print '
\n"; -print "\n"; +print '
'."\n"; +print ''."\n"; print ''; print ''; print '\n"; @@ -436,7 +452,7 @@ foreach ($dirmodels as $reldir) { print ''; // Preview @@ -462,13 +478,13 @@ print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'; - print $form->textwithpicto('', $htmltooltip, 1, 0); + print $formcategory->textwithpicto('', $htmltooltip, 1, 0); print '
'; print '

'; -if (!$conf->use_javascript_ajax) { - print '
'; - print ''; - print ''; -} +print ''; +print ''; +print ''; +print ''; print load_fiche_titre($langs->trans("Other"), '', ''); +print '
'; print ''; print ''; @@ -477,35 +493,102 @@ print ''; print ''; print "\n"; +// Auto mark ticket read when created from backoffice +print ''; +print ''; +print ''; +print ''; + // Auto assign ticket at user who created it -print ''; +print ''; +print ''; print ''; print ''; +print ''; + +// Auto notify contacts when closing the ticket +print ''; +print ''; +print ''; +print ''; + +if (! empty($conf->product->enabled)) { + print ''; + print ''; + print ''; + print ''; +} + +print ''; +print '"; +print ''; +print ''; +print ''; + +print ''; +print '"; +print ''; +print ''; print ''; print '
'.$langs->trans("TicketsAutoReadTicket").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND'); +} else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $formcategory->selectarray("TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND", $arrval, $conf->global->TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND); +} +print ''; +print $formcategory->textwithpicto('', $langs->trans("TicketsAutoReadTicketHelp"), 1, 'help'); +print '
'.$langs->trans("TicketsAutoAssignTicket").'
'.$langs->trans("TicketsAutoAssignTicket").''; if ($conf->use_javascript_ajax) { print ajax_constantonoff('TICKET_AUTO_ASSIGN_USER_CREATE'); } else { $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("TICKET_AUTO_ASSIGN_USER_CREATE", $arrval, $conf->global->TICKET_AUTO_ASSIGN_USER_CREATE); + print $formcategory->selectarray("TICKET_AUTO_ASSIGN_USER_CREATE", $arrval, $conf->global->TICKET_AUTO_ASSIGN_USER_CREATE); } print ''; -print $form->textwithpicto('', $langs->trans("TicketsAutoAssignTicketHelp"), 1, 'help'); +print $formcategory->textwithpicto('', $langs->trans("TicketsAutoAssignTicketHelp"), 1, 'help'); +print '
'.$langs->trans("TicketsAutoNotifyClose").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('TICKET_NOTIFY_AT_CLOSING'); +} else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $formcategory->selectarray("TICKET_NOTIFY_AT_CLOSING", $arrval, $conf->global->TICKET_NOTIFY_AT_CLOSING); +} +print ''; +print $formcategory->textwithpicto('', $langs->trans("TicketsAutoNotifyCloseHelp"), 1, 'help'); +print '
'.$langs->trans("TicketChooseProductCategory").''; + $formcategory->selectProductCategory($conf->global->TICKET_PRODUCT_CATEGORY, 'product_category_id'); + if ($conf->use_javascript_ajax) { + print ajax_combobox('select_'.$htmlname); + } + print ''; + print $formcategory->textwithpicto('', $langs->trans("TicketChooseProductCategoryHelp"), 1, 'help'); + print '
'.$langs->trans("TicketsDelayBeforeFirstAnswer")." + + '; +print $formcategory->textwithpicto('', $langs->trans("TicketsDelayBeforeFirstAnswerHelp"), 1, 'help'); +print '
'.$langs->trans("TicketsDelayBetweenAnswers")." + + '; +print $formcategory->textwithpicto('', $langs->trans("TicketsDelayBetweenAnswersHelp"), 1, 'help'); print '

'; -if (!$conf->use_javascript_ajax) { - print ''; -} +print $formcategory->buttonsSaveCancel("Save", '', array(), 0, 'reposition'); + +print ''; + // Admin var of module print load_fiche_titre($langs->trans("Notification"), '', ''); print ''; -print ''; +print ''; print ''; print ''; +print ''; print ''; print ''; @@ -524,16 +607,16 @@ print ''; print ''; print ''; // Email for notification of TICKET_CREATE -print ''; +print ''; print ''; print ''; print ''; @@ -545,25 +628,25 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { print ajax_constantonoff('TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS'); } else { $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS", $arrval, $conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS); + print $formcategory->selectarray("TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS", $arrval, $conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS); } print ''; print ''; print ''; } // Texte d'introduction $mail_intro = $conf->global->TICKET_MESSAGE_MAIL_INTRO ? $conf->global->TICKET_MESSAGE_MAIL_INTRO : $langs->trans('TicketMessageMailIntroText'); -print ''; print ''; // Texte de signature @@ -575,12 +658,12 @@ $doleditor = new DolEditor('TICKET_MESSAGE_MAIL_SIGNATURE', $mail_signature, '10 $doleditor->Create(); print ''; print ''; print '
'.$langs->trans("Email").'
'.$langs->trans("TicketEmailNotificationFrom").'< print ''; print ''; -print $form->textwithpicto('', $langs->trans("TicketEmailNotificationFromHelp"), 1, 'help'); +print $formcategory->textwithpicto('', $langs->trans("TicketEmailNotificationFromHelp"), 1, 'help'); print '
'.$langs->trans("TicketEmailNotificationTo").' ('.$langs->trans("Creation").')
'.$langs->trans("TicketEmailNotificationTo").''; print ''; -print $form->textwithpicto('', $langs->trans("TicketEmailNotificationToHelp"), 1, 'help'); +print $formcategory->textwithpicto('', $langs->trans("TicketEmailNotificationToHelp"), 1, 'help'); print '
'; - print $form->textwithpicto('', $langs->trans("TicketsEmailAlsoSendToMainAddressHelp"), 1, 'help'); + print $formcategory->textwithpicto('', $langs->trans("TicketsEmailAlsoSendToMainAddressHelp"), 1, 'help'); print '
'.$langs->trans("TicketMessageMailIntroLabelAdmin").' ('.$langs->trans("Responses").')'; +print '
'.$langs->trans("TicketMessageMailIntroLabelAdmin"); print ''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $doleditor = new DolEditor('TICKET_MESSAGE_MAIL_INTRO', $mail_intro, '100%', 120, 'dolibarr_mailings', '', false, true, $conf->global->FCKEDITOR_ENABLE_MAIL, ROWS_2, 70); $doleditor->Create(); print ''; -print $form->textwithpicto('', $langs->trans("TicketMessageMailIntroHelpAdmin"), 1, 'help'); +print $formcategory->textwithpicto('', $langs->trans("TicketMessageMailIntroHelpAdmin"), 1, 'help'); print '
'; -print $form->textwithpicto('', $langs->trans("TicketMessageMailSignatureHelpAdmin"), 1, 'help'); +print $formcategory->textwithpicto('', $langs->trans("TicketMessageMailSignatureHelpAdmin"), 1, 'help'); print '
'; -print $form->buttonsSaveCancel("Save", ''); +print $formcategory->buttonsSaveCancel("Save", '', array(), 0, 'reposition'); print ''; diff --git a/htdocs/admin/ticket_extrafields.php b/htdocs/admin/ticket_extrafields.php index 0a4a851dae2..be75f604542 100644 --- a/htdocs/admin/ticket_extrafields.php +++ b/htdocs/admin/ticket_extrafields.php @@ -80,7 +80,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/admin/ticket_public.php b/htdocs/admin/ticket_public.php index 818141e5cde..621eceb50a3 100644 --- a/htdocs/admin/ticket_public.php +++ b/htdocs/admin/ticket_public.php @@ -42,21 +42,24 @@ $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scandir', 'alpha'); $type = 'ticket'; -$error = 0; /* * Actions */ +$error = 0; +$errors = array(); if ($action == 'setTICKET_ENABLE_PUBLIC_INTERFACE') { if (GETPOST('value')) { - dolibarr_set_const($db, 'TICKET_ENABLE_PUBLIC_INTERFACE', 1, 'chaine', 0, '', $conf->entity); + $res = dolibarr_set_const($db, 'TICKET_ENABLE_PUBLIC_INTERFACE', 1, 'chaine', 0, '', $conf->entity); } else { - dolibarr_set_const($db, 'TICKET_ENABLE_PUBLIC_INTERFACE', 0, 'chaine', 0, '', $conf->entity); + $res = dolibarr_set_const($db, 'TICKET_ENABLE_PUBLIC_INTERFACE', 0, 'chaine', 0, '', $conf->entity); } -} - -if ($action == 'setvar') { + if (!($res > 0)) { + $error++; + $errors[] = $db->lasterror(); + } +} elseif ($action == 'setvar') { include_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"; if (GETPOSTISSET('TICKET_ENABLE_PUBLIC_INTERFACE')) { // only for no js case @@ -64,14 +67,7 @@ if ($action == 'setvar') { $res = dolibarr_set_const($db, 'TICKET_ENABLE_PUBLIC_INTERFACE', $param_enable_public_interface, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { $error++; - } - } - - if (GETPOSTISSET('TICKET_EMAIL_MUST_EXISTS')) { // only for no js case - $param_must_exists = GETPOST('TICKET_EMAIL_MUST_EXISTS', 'alpha'); - $res = dolibarr_set_const($db, 'TICKET_EMAIL_MUST_EXISTS', $param_must_exists, 'chaine', 0, '', $conf->entity); - if (!($res > 0)) { - $error++; + $errors[] = $db->lasterror(); } } @@ -80,6 +76,7 @@ if ($action == 'setvar') { $res = dolibarr_set_const($db, 'TICKET_DISABLE_CUSTOMER_MAILS', $param_disable_email, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } } @@ -88,6 +85,7 @@ if ($action == 'setvar') { $res = dolibarr_set_const($db, 'TICKET_SHOW_COMPANY_LOGO', $param_show_module_logo, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } } @@ -99,6 +97,7 @@ if ($action == 'setvar') { } if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } $text_home = GETPOST('TICKET_PUBLIC_TEXT_HOME', 'restricthtml'); @@ -109,6 +108,7 @@ if ($action == 'setvar') { } if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } $text_help = GETPOST('TICKET_PUBLIC_TEXT_HELP_MESSAGE', 'restricthtml'); @@ -119,6 +119,7 @@ if ($action == 'setvar') { } if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } $mail_new_ticket = GETPOST('TICKET_MESSAGE_MAIL_NEW', 'restricthtml'); @@ -129,6 +130,7 @@ if ($action == 'setvar') { } if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } $url_interface = GETPOST('TICKET_URL_PUBLIC_INTERFACE', 'alpha'); @@ -139,12 +141,14 @@ if ($action == 'setvar') { } if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } $param_public_notification_new_message_default_email = GETPOST('TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL', 'alpha'); $res = dolibarr_set_const($db, 'TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL', $param_public_notification_new_message_default_email, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { @@ -152,10 +156,60 @@ if ($action == 'setvar') { $res = dolibarr_set_const($db, 'TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS', $param_notification_also_main_addressemail, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { $error++; + $errors[] = $db->lasterror(); } } +} elseif (preg_match('/set_(.*)/', $action, $reg)) { + $code = $reg[1]; + $value = GETPOSTISSET($code) ? GETPOST($code, 'int') : 1; + $res = dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + $errors[] = $db->lasterror(); + } + + if (!$error) { + if ($code == 'TICKET_EMAIL_MUST_EXISTS') { + $res = dolibarr_del_const($db, 'TICKET_CREATE_THIRD_PARTY_WITH_CONTACT_IF_NOT_EXIST', $conf->entity); + if (!($res > 0)) { + $error++; + $errors[] = $db->lasterror(); + } + } elseif ($code == 'TICKET_CREATE_THIRD_PARTY_WITH_CONTACT_IF_NOT_EXIST') { + $res = dolibarr_del_const($db, 'TICKET_EMAIL_MUST_EXISTS', $conf->entity); + if (!($res > 0)) { + $error++; + $errors[] = $db->lasterror(); + } + + // enable captcha by default + $res = dolibarr_set_const($db, 'MAIN_SECURITY_ENABLECAPTCHA', 1, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + $errors[] = $db->lasterror(); + } + } + } +} elseif (preg_match('/del_(.*)/', $action, $reg)) { + $code = $reg[1]; + $res = dolibarr_del_const($db, $code, $conf->entity); + if (!($res > 0)) { + $error++; + $errors[] = $db->lasterror(); + } } +if ($action != '') { + if (!$error) { + $db->commit(); + setEventMessage($langs->trans('SetupSaved')); + header("Location: " . $_SERVER['PHP_SELF']); + exit; + } else { + $db->rollback(); + setEventMessages('', $errors, 'errors'); + } +} /* @@ -180,7 +234,7 @@ $head = ticketAdminPrepareHead(); print dol_get_fiche_head($head, 'public', $langs->trans("Module56000Name"), -1, "ticket"); -print ''.$langs->trans("TicketPublicAccess").' : '.dol_buildpath('/public/ticket/index.php', 2).''; +print ''.$langs->trans("TicketPublicAccess").' : '.dol_buildpath('/public/ticket/index.php?entity='.$conf->entity, 2).''; print dol_get_fiche_end(); @@ -220,11 +274,10 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { // Check if email exists print '
'.$langs->trans("TicketsEmailMustExist").''; - if ($conf->use_javascript_ajax) { - print ajax_constantonoff('TICKET_EMAIL_MUST_EXISTS'); + if (empty(getDolGlobalInt('TICKET_EMAIL_MUST_EXISTS'))) { + print '' . img_picto($langs->trans('Disabled'), 'switch_off') . ''; } else { - $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("TICKET_EMAIL_MUST_EXISTS", $arrval, $conf->global->TICKET_EMAIL_MUST_EXISTS); + print '' . img_picto($langs->trans('Enabled'), 'switch_on') . ''; } print ''; @@ -232,6 +285,20 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { print '
'.$langs->trans("TicketCreateThirdPartyWithContactIfNotExist").''; + if (empty(getDolGlobalInt('TICKET_CREATE_THIRD_PARTY_WITH_CONTACT_IF_NOT_EXIST'))) { + print '' . img_picto($langs->trans('Disabled'), 'switch_off') . ''; + } else { + print '' . img_picto($langs->trans('Enabled'), 'switch_on') . ''; + } + print ''; + print $form->textwithpicto('', $langs->trans("TicketCreateThirdPartyWithContactIfNotExistHelp"), 1, 'help'); + print '
'.$langs->trans("TicketsDisableCustomerEmail").''; - if ($conf->use_javascript_ajax) { - print ajax_constantonoff('TICKET_DISABLE_CUSTOMER_MAILS'); - } else { - $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("TICKET_DISABLE_CUSTOMER_MAILS", $arrval, $conf->global->TICKET_DISABLE_CUSTOMER_MAILS); - } - print ''; - print $form->textwithpicto('', $langs->trans("TicketsDisableEmailHelp"), 1, 'help'); - print '
'.$langs->trans("TicketNewEmailBodyLabel").''; - print ''; - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('TICKET_MESSAGE_MAIL_NEW', $mail_mesg_new, '100%', 120, 'dolibarr_mailings', '', false, true, $conf->global->FCKEDITOR_ENABLE_MAIL, ROWS_2, 70); - $doleditor->Create(); - print ''; - print $form->textwithpicto('', $langs->trans("TicketNewEmailBodyHelp"), 1, 'help'); - print '
'.$langs->trans("TicketUrlPublicInterfaceLabelAdmin").''; @@ -364,8 +404,45 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { print $form->textwithpicto('', $langs->trans("TicketUrlPublicInterfaceHelpAdmin"), 1, 'help'); print '
'; + + print '

'; + + print load_fiche_titre($langs->trans("Emails")); + + print '
'; + print ''; + + // Activate email creation to user + print ''; + print ''; + print ''; + + // Text of email after creatio of a ticket + $mail_mesg_new = $conf->global->TICKET_MESSAGE_MAIL_NEW ? $conf->global->TICKET_MESSAGE_MAIL_NEW : $langs->trans('TicketNewEmailBody'); + print ''; + print ''; + // Activate email notification when a new message is added - print ''; + print ''; print ''; - print ''; print ''; // Send notification when a new message is added to a email if a user is not assigned to the ticket - print ''; print ''; - print ''; + print ''; print '
'; + print $form->textwithpicto($langs->trans("TicketsDisableCustomerEmail"), $langs->trans("TicketsDisableEmailHelp"), 1, 'help'); + print ''; + if ($conf->use_javascript_ajax) { + print ajax_constantonoff('TICKET_DISABLE_CUSTOMER_MAILS'); + } else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("TICKET_DISABLE_CUSTOMER_MAILS", $arrval, $conf->global->TICKET_DISABLE_CUSTOMER_MAILS); + } + print '
'; + print $form->textwithpicto($langs->trans("TicketNewEmailBodyLabel"), $langs->trans("TicketNewEmailBodyHelp"), 1, 'help'); + print ''; + print ''; + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor = new DolEditor('TICKET_MESSAGE_MAIL_NEW', $mail_mesg_new, '100%', 120, 'dolibarr_mailings', '', false, true, $conf->global->FCKEDITOR_ENABLE_MAIL, ROWS_2, 70); + $doleditor->Create(); + print '
'.$langs->trans("TicketsPublicNotificationNewMessage").'
'; + print $form->textwithpicto($langs->trans("TicketsPublicNotificationNewMessage"), $langs->trans("TicketsPublicNotificationNewMessageHelp"), 1, 'help'); + print ''; if ($conf->use_javascript_ajax) { print ajax_constantonoff('TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED'); @@ -374,19 +451,15 @@ if (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { print $form->selectarray("TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED", $arrval, $conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED); } print ''; - print $form->textwithpicto('', $langs->trans("TicketsPublicNotificationNewMessageHelp"), 1, 'help'); - print '
'.$langs->trans("TicketPublicNotificationNewMessageDefaultEmail").''; + print '
'; + print $form->textwithpicto($langs->trans("TicketPublicNotificationNewMessageDefaultEmail"), $langs->trans("TicketPublicNotificationNewMessageDefaultEmailHelp"), 1, 'help'); print ''; print ''; - print $form->textwithpicto('', $langs->trans("TicketPublicNotificationNewMessageDefaultEmailHelp"), 1, 'help'); - print '
'; print '
'; diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index 6ed3bd00863..7d02aea0e73 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -214,10 +214,6 @@ if (in_array($type, array('mysql', 'mysqli'))) { print '
'; print '
'.$langs->trans("ExportOptions").''; - print '
'; - print ''; - print ''; - print '
'; if (!empty($conf->global->MYSQL_OLD_OPTION_DISABLE_FK)) { print '
'; @@ -239,14 +235,35 @@ if (in_array($type, array('mysql', 'mysqli'))) { print ''; print ''; print ''; - print '
'; + print '

'; - print ''; + print '
'; + print ''; + print ''; + print '
'; + + print ''; print ''; print '
'; + $execmethod = 0; + if (!empty($conf->global->MAIN_EXEC_USE_POPEN)) { + $execmethod = $conf->global->MAIN_EXEC_USE_POPEN; + } + if (empty($execmethod)) { + $execmethod = 1; + } + if ($execmethod == 1) { + // If we use the "exec" method for shell, we ask if we need to use the alternative low memory exec mode. + print ''; + print ''; + print '
'; + } + print ''; @@ -422,7 +439,7 @@ if (in_array($type, array('pgsql'))) { $prefix = 'pg_dump'; $ext = 'sql'; } -$file = $prefix.'_'.$dolibarr_main_db_name.'_'.dol_sanitizeFileName(DOL_VERSION).'_'.strftime("%Y%m%d%H%M").'.'.$ext; +$file = $prefix.'_'.$dolibarr_main_db_name.'_'.dol_sanitizeFileName(DOL_VERSION).'_'.dol_print_date(dol_now('gmt'), "dayhourlogsmall", 'tzuser').'.'.$ext; print ''; print '
'; print '
'; @@ -542,10 +559,10 @@ print ''; print "
\n"; -print '
'; +print '
'; $filearray = dol_dir_list($conf->admin->dir_output.'/backup', 'files', 0, '', '', $sortfield, (strtolower($sortorder) == 'asc' ?SORT_ASC:SORT_DESC), 1); -$result = $formfile->list_of_documents($filearray, null, 'systemtools', '', 1, 'backup/', 1, 0, $langs->trans("NoBackupFileAvailable"), 0, $langs->trans("PreviousDumpFiles")); +$result = $formfile->list_of_documents($filearray, null, 'systemtools', '', 1, 'backup/', 1, 0, $langs->trans("NoBackupFileAvailable"), 0, $langs->trans("PreviousDumpFiles"), '', 0, -1, '', '', 'ASC', 1, 0, -1, 'style="height:480px; overflow: auto;"'); print '
'; print '
'; @@ -577,7 +594,7 @@ print load_fiche_titre($title); print '
'; $prefix = 'documents'; $ext = 'zip'; -$file = $prefix.'_'.$dolibarr_main_db_name.'_'.dol_sanitizeFileName(DOL_VERSION).'_'.strftime("%Y%m%d%H%M"); +$file = $prefix.'_'.$dolibarr_main_db_name.'_'.dol_sanitizeFileName(DOL_VERSION).'_'.dol_print_date(dol_now('gmt'), "dayhourlogsmall", 'tzuser'); print '
'; print '
'; @@ -622,10 +639,10 @@ print '
'; print '
'; -print '
'; +print '
'; $filearray = dol_dir_list($conf->admin->dir_output.'/documents', 'files', 0, '', '', $sortfield, (strtolower($sortorder) == 'asc' ?SORT_ASC:SORT_DESC), 1); -$result = $formfile->list_of_documents($filearray, null, 'systemtools', '', 1, 'documents/', 1, 0, $langs->trans("NoBackupFileAvailable"), 0, $langs->trans("PreviousArchiveFiles")); +$result = $formfile->list_of_documents($filearray, null, 'systemtools', '', 1, 'documents/', 1, 0, $langs->trans("NoBackupFileAvailable"), 0, $langs->trans("PreviousArchiveFiles"), '', 0, -1, '', '', 'ASC', 1, 0, -1, 'style="height:250px; overflow: auto;"'); print '
'; print '
'; diff --git a/htdocs/admin/tools/update.php b/htdocs/admin/tools/update.php index ea9ca86e994..902e68b381e 100644 --- a/htdocs/admin/tools/update.php +++ b/htdocs/admin/tools/update.php @@ -61,7 +61,11 @@ $version = '0.0'; if ($action == 'getlastversion') { $result = getURLContent('https://sourceforge.net/projects/dolibarr/rss'); //var_dump($result['content']); - $sfurl = simplexml_load_string($result['content'], 'SimpleXMLElement', LIBXML_NOCDATA|LIBXML_NONET); + if (function_exists('simplexml_load_string')) { + $sfurl = simplexml_load_string($result['content'], 'SimpleXMLElement', LIBXML_NOCDATA|LIBXML_NONET); + } else { + $sfurl = 'xml_not_available'; + } } @@ -82,7 +86,10 @@ if (function_exists('curl_init')) { $conf->global->MAIN_USE_RESPONSE_TIMEOUT = 10; if ($action == 'getlastversion') { - if ($sfurl) { + if ($sfurl == 'xml_not_available') { + $langs->load("errors"); + print $langs->trans("LastStableVersion").' : '.$langs->trans("ErrorFunctionNotAvailableInPHP", 'simplexml_load_string').'
'; + } elseif ($sfurl) { $i = 0; while (!empty($sfurl->channel[0]->item[$i]->title) && $i < 10000) { $title = $sfurl->channel[0]->item[$i]->title; diff --git a/htdocs/admin/translation.php b/htdocs/admin/translation.php index bb42808ebd4..4968e75989a 100644 --- a/htdocs/admin/translation.php +++ b/htdocs/admin/translation.php @@ -90,7 +90,7 @@ include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers $transkey = ''; $transvalue = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } @@ -271,7 +271,8 @@ $recordtoshow = array(); // Search modules dirs $modulesdir = dolGetModulesDirs(); -$nbtotaloffiles = 0; +$listoffiles = array(); +$listoffilesexternalmodules = array(); // Search into dir of modules (the $modulesdir is already a list that loop on $conf->file->dol_document_root) $i = 0; @@ -298,7 +299,10 @@ foreach ($modulesdir as $keydir => $tmpsearchdir) { if ($result < 0) { print 'Failed to load language file '.$tmpfile.'
'."\n"; } else { - $nbtotaloffiles++; + $listoffiles[$langkey] = $tmpfile; + if (strpos($langkey, '@') !== false) { + $listoffilesexternalmodules[$langkey] = $tmpfile; + } } //print 'After loading lang '.$langkey.', newlang has '.count($newlang->tab_translate).' records
'."\n"; @@ -307,6 +311,8 @@ foreach ($modulesdir as $keydir => $tmpsearchdir) { $i++; } +$nbtotaloffiles = count($listoffiles); +$nbtotaloffilesexternal = count($listoffilesexternalmodules); if ($mode == 'overwrite') { print ''; @@ -358,7 +364,7 @@ if ($mode == 'overwrite') { print ''; print ''; print ''; - print ''; + print ''; print "\n"; print ''; @@ -438,9 +444,9 @@ if ($mode == 'overwrite') { if ($mode == 'searchkey') { $nbempty = 0; - /*var_dump($langcode); - var_dump($transkey); - var_dump($transvalue);*/ + //var_dump($langcode); + //var_dump($transkey); + //var_dump($transvalue); if (empty($langcode) || $langcode == '-1') { $nbempty++; } @@ -477,7 +483,7 @@ if ($mode == 'searchkey') { //print 'param='.$param.' $_SERVER["PHP_SELF"]='.$_SERVER["PHP_SELF"].' num='.$num.' page='.$page.' nbtotalofrecords='.$nbtotalofrecords." sortfield=".$sortfield." sortorder=".$sortorder; $title = $langs->trans("Translation"); if ($nbtotalofrecords > 0) { - $title .= ' ('.$nbtotalofrecords.' / '.$nbtotalofrecordswithoutfilters.' - '.$nbtotaloffiles.' '.$langs->trans("Files").')'; + $title .= ' ('.$nbtotalofrecords.' / '.$nbtotalofrecordswithoutfilters.' - '.$nbtotaloffiles.' '.$langs->trans("Files").')'; } print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, -1 * $nbtotalofrecords, '', 0, '', '', $limit, 0, 0, 1); diff --git a/htdocs/admin/user.php b/htdocs/admin/user.php index 85ab0f0e9a8..53de8fe2502 100644 --- a/htdocs/admin/user.php +++ b/htdocs/admin/user.php @@ -43,9 +43,11 @@ $extrafields = new ExtraFields($db); $action = GETPOST('action', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php $value = GETPOST('value', 'alpha'); $label = GETPOST('label', 'alpha'); + $scandir = GETPOST('scandir', 'alpha'); $type = 'user'; diff --git a/htdocs/admin/usergroup.php b/htdocs/admin/usergroup.php index 3319ab994a6..709b60068f7 100644 --- a/htdocs/admin/usergroup.php +++ b/htdocs/admin/usergroup.php @@ -42,6 +42,8 @@ $extrafields = new ExtraFields($db); $action = GETPOST('action', 'aZ09'); $value = GETPOST('value', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php + $type = 'group'; /* diff --git a/htdocs/admin/website.php b/htdocs/admin/website.php index d1a24ff072c..53760aaa586 100644 --- a/htdocs/admin/website.php +++ b/htdocs/admin/website.php @@ -113,7 +113,7 @@ $tabcond[1] = (!empty($conf->website->enabled)); // List of help for fields $tabhelp = array(); -$tabhelp[1] = array('ref'=>$langs->trans("EnterAnyCode"), 'virtualhost'=>$langs->trans("SetHereVirtualHost", DOL_DATA_ROOT.'/website/websiteref')); +$tabhelp[1] = array('ref'=>$langs->trans("EnterAnyCode"), 'virtualhost'=>$langs->trans("SetHereVirtualHost", DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/website/websiteref')); // List of check for fields (NOT USED YET) $tabfieldcheck = array(); @@ -198,15 +198,15 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { $_POST[$listfieldvalue[$i]] = $conf->entity; } if ($value == 'ref') { - $_POST[$listfieldvalue[$i]] = strtolower($_POST[$listfieldvalue[$i]]); + $_POST[$listfieldvalue[$i]] = strtolower(GETPOST($listfieldvalue[$i])); } if ($i) { $sql .= ","; } - if ($_POST[$listfieldvalue[$i]] == '') { + if (GETPOST($listfieldvalue[$i]) == '') { $sql .= "null"; } else { - $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; } $i++; } @@ -259,7 +259,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { if ($_POST[$listfieldvalue[$i]] == '') { $sql .= "null"; } else { - $sql .= "'".$db->escape($_POST[$listfieldvalue[$i]])."'"; + $sql .= "'".$db->escape(GETPOST($listfieldvalue[$i]))."'"; } $i++; } @@ -271,8 +271,8 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { if ($resql) { $newname = dol_sanitizeFileName(GETPOST('ref', 'aZ09')); if ($newname != $website->ref) { - $srcfile = DOL_DATA_ROOT.'/website/'.$website->ref; - $destfile = DOL_DATA_ROOT.'/website/'.$newname; + $srcfile = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/website/'.$website->ref; + $destfile = DOL_DATA_ROOT.($conf->entity > 1 ? '/'.$conf->entity : '').'/website/'.$newname; if (dol_is_dir($destfile)) { $error++; diff --git a/htdocs/admin/workflow.php b/htdocs/admin/workflow.php index a58c3378ecd..a68f49e36e3 100644 --- a/htdocs/admin/workflow.php +++ b/htdocs/admin/workflow.php @@ -71,6 +71,12 @@ $workflowcodes = array( 'enabled'=>(!empty($conf->commande->enabled) && !empty($conf->facture->enabled)), 'picto'=>'bill' ), + 'WORKFLOW_TICKET_CREATE_INTERVENTION' => array ( + 'family'=>'create', + 'position'=>25, + 'enabled'=>(!empty($conf->ticket->enabled) && !empty($conf->ficheinter->enabled)), + 'picto'=>'ticket' + ), 'separator1'=>array('family'=>'separator', 'position'=>25, 'title'=>''), @@ -161,7 +167,21 @@ $workflowcodes = array( 'position' => 90, 'enabled' => ! empty($conf->expedition->enabled) && ! empty($conf->facture->enabled), 'picto' => 'shipment' - ) + ), + + // Automatic link ticket -> contract + 'WORKFLOW_TICKET_LINK_CONTRACT' => array( + 'family' => 'link_ticket', + 'position' => 75, + 'enabled' => ! empty($conf->ticket->enabled) && ! empty($conf->contract->enabled), + 'picto' => 'ticket' + ), + 'WORKFLOW_TICKET_USE_PARENT_COMPANY_CONTRACTS' => array( + 'family' => 'link_ticket', + 'position' => 76, + 'enabled' => ! empty($conf->ticket->enabled) && ! empty($conf->contract->enabled), + 'picto' => 'ticket' + ), ); if (!empty($conf->modules_parts['workflow']) && is_array($conf->modules_parts['workflow'])) { @@ -237,6 +257,11 @@ foreach ($workflowcodes as $key => $params) { if ($reg[1] == 'shipping') { $header .= ' - '.$langs->trans('Shipment'); } + } elseif (preg_match('/link_(.*)/', $params['family'], $reg)) { + $header = $langs->trans("AutomaticLinking"); + if ($reg[1] == 'ticket') { + $header .= ' - '.$langs->trans('Ticket'); + } } else { $header = $langs->trans("Description"); } diff --git a/htdocs/admin/workstation.php b/htdocs/admin/workstation.php index e89cbb2fd41..6ac7a425246 100644 --- a/htdocs/admin/workstation.php +++ b/htdocs/admin/workstation.php @@ -36,6 +36,7 @@ $langs->loadLangs(array("admin", "workstation")); // Parameters $action = GETPOST('action', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php $value = GETPOST('value', 'alpha'); @@ -294,7 +295,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { print ''; $constforvar = 'WORKSTATION_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $file) { + if (getDolGlobalString($constforvar) == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { print ''; @@ -436,7 +437,7 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Default print ''; $constforvar = 'WORKSTATION_'.strtoupper($myTmpObjectKey).'_ADDON'; - if ($conf->global->$constforvar == $name) { + if (getDolGlobalString($constforvar) == $name) { print img_picto($langs->trans("Default"), 'on'); } else { print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; diff --git a/htdocs/api/README.md b/htdocs/api/README.md index 7ab85cc26bb..1af112920ce 100644 --- a/htdocs/api/README.md +++ b/htdocs/api/README.md @@ -41,7 +41,7 @@ https://**yourdolibarr.tld**/mydolibarr/api/index.php/otherservice?DOLAPIKEY=**a Develop an API -------------- -The API uses Lucarast Restler framework. Please check documentation https://www.luracast.com/products/restler and examples http://help.luracast.com/restler/examples/ +The API uses Lucarast Restler framework. Please check documentation https://www.luracast.com/products/restler and examples https://restler3.luracast.com/examples/index.html Github contains also useful information : https://github.com/Luracast/Restler diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index 2a6b5f33a27..32d691400d6 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -88,9 +88,9 @@ class DolibarrApi // phpcs:enable // TODO Use type detected in $object->fields if (in_array($field, array('note', 'note_private', 'note_public', 'desc', 'description'))) { - return checkVal($value, 'restricthtml'); + return sanitizeVal($value, 'restricthtml'); } else { - return checkVal($value, 'alphanohtml'); + return sanitizeVal($value, 'alphanohtml'); } } @@ -173,6 +173,7 @@ class DolibarrApi unset($object->stats_mrptoproduce); unset($object->element); + unset($object->element_for_permission); unset($object->fk_element); unset($object->table_element); unset($object->table_element_line); diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index 44c3b1fcb52..d4d652f3e74 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -458,6 +458,20 @@ class Documents extends DolibarrApi } $upload_dir = $conf->expensereport->dir_output.'/'.dol_sanitizeFileName($object->ref); + } elseif ($modulepart == 'knowledgemanagement') { + require_once DOL_DOCUMENT_ROOT.'/knowledgemanagement/class/knowledgerecord.class.php'; + + if (!DolibarrApiAccess::$user->rights->knowledgemanagement->knowledgerecord->read && !DolibarrApiAccess::$user->rights->knowledgemanagement->knowledgerecord->read) { + throw new RestException(401); + } + + $object = new KnowledgeRecord($this->db); + $result = $object->fetch($id, $ref); + if (!$result) { + throw new RestException(404, 'KM article not found'); + } + + $upload_dir = $conf->knowledgemanagement->dir_output.'/knowledgerecord/'.dol_sanitizeFileName($object->ref); } elseif ($modulepart == 'categorie' || $modulepart == 'category') { require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; @@ -554,10 +568,9 @@ class Documents extends DolibarrApi { global $db, $conf; - /*var_dump($modulepart); - var_dump($filename); - var_dump($filecontent); - exit;*/ + //var_dump($modulepart); + //var_dump($filename); + //var_dump($filecontent);exit; if (empty($modulepart)) { throw new RestException(400, 'Modulepart not provided.'); diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php index 2ab8c7837ac..9c7cc01630d 100644 --- a/htdocs/api/class/api_setup.class.php +++ b/htdocs/api/class/api_setup.class.php @@ -209,7 +209,7 @@ class Setup extends DolibarrApi if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; + $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -239,7 +239,6 @@ class Setup extends DolibarrApi return $list; } - /** * Get the list of states/provinces. * @@ -252,27 +251,34 @@ class Setup extends DolibarrApi * @param string $sortorder Sort order * @param int $limit Number of items per page * @param int $page Page number (starting from zero) - * @param string $filter To filter the countries by name + * @param int $country To filter on country + * @param string $filter To filter the states by name * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" - * @return array List of countries + * @return array List of states * * @url GET dictionary/states * * @throws RestException */ - public function getListOfStates($sortfield = "code_departement", $sortorder = 'ASC', $limit = 100, $page = 0, $filter = '', $sqlfilters = '') + public function getListOfStates($sortfield = "code_departement", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $filter = '', $sqlfilters = '') { $list = array(); // Note: The filter is not applied in the SQL request because it must // be applied to the translated names, not to the names in database. - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."c_departements as t"; + $sql = "SELECT t.rowid FROM ".MAIN_DB_PREFIX."c_departements as t"; + if ($country) { + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_regions as d ON t.fk_region = d.code_region"; + } $sql .= " WHERE 1 = 1"; + if ($country) { + $sql .= " AND d.fk_pays = ".((int) $country); + } // Add sql filters if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -373,7 +379,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -665,7 +671,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -729,7 +735,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -797,7 +803,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -860,7 +866,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -933,7 +939,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1004,7 +1010,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1078,7 +1084,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1143,9 +1149,9 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(400, 'error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; + $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -1202,9 +1208,9 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(400, 'error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; + $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -1261,7 +1267,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1301,7 +1307,7 @@ class Setup extends DolibarrApi * @param string $sortorder Sort order * @param int $limit Number of items per page * @param int $page Page number (starting from zero) - * @param string $country To filter on country + * @param int $country To filter on country * @param int $active Lega form is active or not {@min 0} {@max 1} * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.code:like:'A%') and (t.active:>=:0)" * @return array List of legal form @@ -1310,7 +1316,7 @@ class Setup extends DolibarrApi * * @throws RestException */ - public function getListOfLegalForm($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $country = '', $active = 1, $sqlfilters = '') + public function getListOfLegalForm($sortfield = "rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $country = 0, $active = 1, $sqlfilters = '') { $list = array(); @@ -1318,13 +1324,13 @@ class Setup extends DolibarrApi $sql .= " FROM ".MAIN_DB_PREFIX."c_forme_juridique as t"; $sql .= " WHERE t.active = ".((int) $active); if ($country) { - $sql .= " AND t.fk_pays = '".$this->db->escape($country)."'"; + $sql .= " AND t.fk_pays = ".((int) $country); } // Add sql filters if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1383,7 +1389,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1449,7 +1455,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1508,7 +1514,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1567,7 +1573,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; @@ -1628,7 +1634,7 @@ class Setup extends DolibarrApi if ($sqlfilters) { $errormessage = ''; if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; diff --git a/htdocs/api/index.php b/htdocs/api/index.php index d5bc7e273e2..afb0289aa32 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -100,7 +100,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; $url = $_SERVER['PHP_SELF']; if (preg_match('/api\/index\.php$/', $url)) { // sometimes $_SERVER['PHP_SELF'] is 'api\/index\.php' instead of 'api\/index\.php/explorer.php' or 'api\/index\.php/method' - $url = $_SERVER['PHP_SELF'].$_SERVER['PATH_INFO']; + $url = $_SERVER['PHP_SELF'].(empty($_SERVER['PATH_INFO']) ? $_SERVER['ORIG_PATH_INFO'] : $_SERVER['PATH_INFO']); } // Fix for some NGINX setups (this should not be required even with NGINX, however setup of NGINX are often mysterious and this may help is such cases) if (!empty($conf->global->MAIN_NGINX_FIX)) { @@ -158,6 +158,25 @@ if (!empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/swagger.json' || $ $api = new DolibarrApi($db, '', $refreshcache); //var_dump($api->r->apiVersionMap); +// If MAIN_API_DEBUG is set to 1, we save logs into file "dolibarr_api.log" +if (!empty($conf->global->MAIN_API_DEBUG)) { + $r = $api->r; + $r->onCall(function () use ($r) { + // Don't log Luracast Restler Explorer recources calls + //if (!preg_match('/^explorer/', $r->url)) { + // 'method' => $api->r->requestMethod, + // 'url' => $api->r->url, + // 'route' => $api->r->apiMethodInfo->className.'::'.$api->r->apiMethodInfo->methodName, + // 'version' => $api->r->getRequestedApiVersion(), + // 'data' => $api->r->getRequestData(), + //dol_syslog("Debug API input ".var_export($r, true), LOG_DEBUG, 0, '_api'); + dol_syslog("Debug API url ".var_export($r->url, true), LOG_DEBUG, 0, '_api'); + dol_syslog("Debug API input ".var_export($r->getRequestData(), true), LOG_DEBUG, 0, '_api'); + //} + }); +} + + // Enable the Restler API Explorer. // See https://github.com/Luracast/Restler-API-Explorer for more info. $api->r->addAPIClass('Luracast\\Restler\\Explorer'); diff --git a/htdocs/asset/accountancy_codes.php b/htdocs/asset/accountancy_codes.php new file mode 100644 index 00000000000..431b4ba7c68 --- /dev/null +++ b/htdocs/asset/accountancy_codes.php @@ -0,0 +1,189 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * 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 . + */ + +/** + * \file htdocs/asset/accountancy_code.php + * \ingroup asset + * \brief Card with accountancy code on Asset + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new Asset($db); +$assetaccountancycodes = new AssetAccountancyCodes($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('assetaccountancycodes', '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->asset->multidir_output[$object->entity] . "/" . $object->id; +} + +$permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); + +$result = $assetaccountancycodes->fetchAccountancyCodes($object->id); +if ($result < 0) { + setEventMessages($assetaccountancycodes->error, $assetaccountancycodes->errors, 'errors'); +} + + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', array(), $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)) { + $backurlforlist = DOL_URL_ROOT.'/asset/list.php'; + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = DOL_URL_ROOT.'/asset/accountancy_codes.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__'); + } + } + } + + if ($cancel) { + /*var_dump($cancel);var_dump($backtopage);var_dump($backtopageforcancel);exit;*/ + if (!empty($backtopageforcancel)) { + header("Location: ".$backtopageforcancel); + exit; + } elseif (!empty($backtopage)) { + header("Location: ".$backtopage); + exit; + } + $action = ''; + } + + if ($action == "update") { + $assetaccountancycodes->setAccountancyCodesFromPost(); + + $result = $assetaccountancycodes->updateAccountancyCodes($user, $object->id); + if ($result < 0) { + setEventMessages($assetaccountancycodes->error, $assetaccountancycodes->errors, 'errors'); + $action = 'edit'; + } else { + setEventMessage($langs->trans('RecordSaved')); + header("Location: " . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit; + } + } +} + + +/* + * View + */ + +$form = new Form($db); + +$help_url = ''; +llxHeader('', $langs->trans('Asset'), $help_url); + +if ($id > 0 || !empty($ref)) { + $head = assetPrepareHead($object); + print dol_get_fiche_head($head, 'accountancy_codes', $langs->trans("Asset"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
'; + $morehtmlref .= '
'; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
'; + print '
'; + print '
'; + + if ($action == 'edit') { + print '
'; + print ''; + print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } + + print dol_get_fiche_head(array(), ''); + + include DOL_DOCUMENT_ROOT . '/asset/tpl/accountancy_codes_edit.tpl.php'; + + print dol_get_fiche_end(); + + print $form->buttonsSaveCancel(); + + print '
'; + } else { + include DOL_DOCUMENT_ROOT . '/asset/tpl/accountancy_codes_view.tpl.php'; + } + + print dol_get_fiche_end(); + + if ($action != 'edit') { + print '
' . "\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + + if (empty($reshook)) { + if ($object->status == $object::STATUS_DRAFT/* && !empty($object->enabled_modes)*/) { + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&token=' . newToken(), '', $permissiontoadd); + } + } + print '
' . "\n"; + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/admin/assets_type_extrafields.php b/htdocs/asset/admin/asset_extrafields.php similarity index 56% rename from htdocs/asset/admin/assets_type_extrafields.php rename to htdocs/asset/admin/asset_extrafields.php index 165361f7f57..321041d754d 100644 --- a/htdocs/asset/admin/assets_type_extrafields.php +++ b/htdocs/asset/admin/asset_extrafields.php @@ -1,5 +1,11 @@ +/* Copyright (C) 2001-2002 Rodolphe Quiedeville + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2012 Regis Houssin + * Copyright (C) 2014 Florian Henry + * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2018 Alexandre Spangaro * * 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 @@ -13,20 +19,20 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * or see https://www.gnu.org/ */ /** - * \file htdocs/asset/admin/assets_type_extrafields.php - * \ingroup asset - * \brief Page to setup extra fields type of assets + * \file htdocs/asset/admin/asset_extrafields.php + * \ingroup asset + * \brief Page to setup extra fields of asset */ + require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/asset.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; // Load translation files required by the page -$langs->loadLangs(array('assets', 'admin')); +$langs->loadLangs(array("assets", "admin", "companies")); $extrafields = new ExtraFields($db); $form = new Form($db); @@ -40,7 +46,7 @@ foreach ($tmptype2label as $key => $val) { $action = GETPOST('action', 'aZ09'); $attrname = GETPOST('attrname', 'alpha'); -$elementtype = 'adherent_type'; //Must be the $table_element of the class that manage extrafield +$elementtype = 'asset'; //Must be the $table_element of the class that manage extrafield if (!$user->admin) { accessforbidden(); @@ -59,38 +65,47 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; * View */ -$textobject = $langs->transnoentitiesnoconv("AssetsTypes"); +$help_url = ''; +$page_name = "AssetSetup"; +$textobject = $langs->transnoentitiesnoconv("Assets"); -llxHeader('', $langs->trans("AssetsSetup")); - -$linkback = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("AssetsSetup"), $linkback, 'title_setup'); +llxHeader('', $langs->trans("AssetSetup"), $help_url); -$head = asset_admin_prepare_head(); +$linkback = ''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup'); -print dol_get_fiche_head($head, 'attributes_type', $langs->trans("Assets"), -1, 'generic'); + +$head = assetAdminPrepareHead(); + +print dol_get_fiche_head($head, 'asset_extrafields', $langs->trans($page_name), -1, 'asset'); require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php'; print dol_get_fiche_end(); + // Buttons if ($action != 'create' && $action != 'edit') { print '"; } -// Creation of an optional field + +/* + * Creation of an optional field + */ if ($action == 'create') { - print "
"; + print '
'; print load_fiche_titre($langs->trans('NewAttribute')); require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php'; } -// Edition of an optional field +/* + * Edition of an optional field + */ if ($action == 'edit' && !empty($attrname)) { print "
"; print load_fiche_titre($langs->trans("FieldEdition", $attrname)); diff --git a/htdocs/asset/admin/assets_extrafields.php b/htdocs/asset/admin/assetmodel_extrafields.php similarity index 54% rename from htdocs/asset/admin/assets_extrafields.php rename to htdocs/asset/admin/assetmodel_extrafields.php index 9a68f99fe06..7b2bbc1260d 100644 --- a/htdocs/asset/admin/assets_extrafields.php +++ b/htdocs/asset/admin/assetmodel_extrafields.php @@ -1,6 +1,11 @@ - * Copyright (C) 2018 Alexandre Spangaro +/* Copyright (C) 2001-2002 Rodolphe Quiedeville + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2012 Regis Houssin + * Copyright (C) 2014 Florian Henry + * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2018 Alexandre Spangaro * * 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 @@ -17,9 +22,9 @@ */ /** - * \file htdocs/asset/admin/assets_extrafields.php + * \file htdocs/asset/admin/assetmodel_extrafields.php * \ingroup asset - * \brief Page to setup extra fields of assets + * \brief Page to setup extra fields of asset model */ require '../../main.inc.php'; @@ -41,7 +46,7 @@ foreach ($tmptype2label as $key => $val) { $action = GETPOST('action', 'aZ09'); $attrname = GETPOST('attrname', 'alpha'); -$elementtype = 'don'; //Must be the $table_element of the class that manage extrafield +$elementtype = 'asset_model'; //Must be the $table_element of the class that manage extrafield if (!$user->admin) { accessforbidden(); @@ -60,17 +65,20 @@ require DOL_DOCUMENT_ROOT.'/core/actions_extrafields.inc.php'; * View */ -$textobject = $langs->transnoentitiesnoconv("Assets"); +$help_url = ''; +$page_name = "AssetSetup"; +$textobject = $langs->transnoentitiesnoconv("AssetModels"); -llxHeader('', $langs->trans("AssetsSetup")); - -$linkback = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("AssetsSetup"), $linkback, 'title_setup'); +llxHeader('', $langs->trans("AssetSetup"), $help_url); -$head = asset_admin_prepare_head(); +$linkback = ''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup'); -print dol_get_fiche_head($head, 'attributes', $langs->trans("Assets"), -1, 'generic'); + +$head = assetAdminPrepareHead(); + +print dol_get_fiche_head($head, 'assetmodel_extrafields', $langs->trans($page_name), -1, 'asset'); require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_view.tpl.php'; @@ -80,29 +88,24 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } -/* ************************************************************************** */ -/* */ -/* Create optional field */ -/* */ -/* ************************************************************************** */ - +/* + * Creation of an optional field + */ if ($action == 'create') { - print "
"; + print '
'; print load_fiche_titre($langs->trans('NewAttribute')); require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php'; } -/* ************************************************************************** */ -/* */ -/* Edit optional field */ -/* */ -/* ************************************************************************** */ +/* + * Edition of an optional field + */ if ($action == 'edit' && !empty($attrname)) { print "
"; print load_fiche_titre($langs->trans("FieldEdition", $attrname)); diff --git a/htdocs/asset/admin/setup.php b/htdocs/asset/admin/setup.php index a90c2b479c4..29ee4b074fb 100644 --- a/htdocs/asset/admin/setup.php +++ b/htdocs/asset/admin/setup.php @@ -18,8 +18,8 @@ /** * \file htdocs/asset/admin/setup.php - * \ingroup assets - * \brief Assets setup page. + * \ingroup asset + * \brief Asset setup page. */ require '../../main.inc.php'; @@ -40,30 +40,421 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); -$arrayofparameters = array('FIXEDASSETS_MYPARAM1'=>array('css'=>'minwidth200'), 'FIXEDASSETS_MYPARAM2'=>array('css'=>'minwidth500')); +$value = GETPOST('value', 'alpha'); +$label = GETPOST('label', 'alpha'); +$scandir = GETPOST('scan_dir', 'alpha'); +$type = 'asset'; + +$arrayofparameters = array( + 'ASSET_ACCOUNTANCY_CATEGORY'=>array('type'=>'accountancy_category', 'enabled'=>1), + 'ASSET_DEPRECIATION_DURATION_PER_YEAR'=>array('type'=>'string', 'css'=>'minwidth200', 'enabled'=>1), + //'ASSET_MYPARAM2'=>array('type'=>'textarea','enabled'=>1), + //'ASSET_MYPARAM3'=>array('type'=>'category:'.Categorie::TYPE_CUSTOMER, 'enabled'=>1), + //'ASSET_MYPARAM4'=>array('type'=>'emailtemplate:thirdparty', 'enabled'=>1), + //'ASSET_MYPARAM5'=>array('type'=>'yesno', 'enabled'=>1), + //'ASSET_MYPARAM5'=>array('type'=>'thirdparty_type', 'enabled'=>1), + //'ASSET_MYPARAM6'=>array('type'=>'securekey', 'enabled'=>1), + //'ASSET_MYPARAM7'=>array('type'=>'product', 'enabled'=>1), +); + +$error = 0; +$setupnotempty = 0; + +$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); /* * Actions */ -include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; +if ((float) DOL_VERSION >= 6) { + include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; +} + +if ($action == 'updateMask') { + $maskconstorder = GETPOST('maskconstorder', 'alpha'); + $maskorder = GETPOST('maskorder', 'alpha'); + + if ($maskconstorder) { + $res = dolibarr_set_const($db, $maskconstorder, $maskorder, 'chaine', 0, '', $conf->entity); + if (!($res > 0)) { + $error++; + } + } + + if (!$error) { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } else { + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} elseif ($action == 'specimen') { + $modele = GETPOST('module', 'alpha'); + $tmpobjectkey = GETPOST('object'); + + $tmpobject = new $tmpobjectkey($db); + $tmpobject->initAsSpecimen(); + + // Search template files + $file = ''; $classname = ''; $filefound = 0; + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $file = dol_buildpath($reldir."core/modules/asset/doc/pdf_".$modele."_".strtolower($tmpobjectkey).".modules.php", 0); + if (file_exists($file)) { + $filefound = 1; + $classname = "pdf_".$modele; + break; + } + } + + if ($filefound) { + require_once $file; + + $module = new $classname($db); + + if ($module->write_file($tmpobject, $langs) > 0) { + header("Location: ".DOL_URL_ROOT."/document.php?modulepart=".strtolower($tmpobjectkey)."&file=SPECIMEN.pdf"); + return; + } else { + setEventMessages($module->error, null, 'errors'); + dol_syslog($module->error, LOG_ERR); + } + } else { + setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors'); + dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); + } +} elseif ($action == 'setmod') { + // TODO Check if numbering module chosen can be activated by calling method canBeActivated + $tmpobjectkey = GETPOST('object'); + if (!empty($tmpobjectkey)) { + $constforval = 'ASSET_'.strtoupper($tmpobjectkey)."_ADDON"; + dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity); + } +} elseif ($action == 'set') { + // Activate a model + $ret = addDocumentModel($value, $type, $label, $scandir); +} elseif ($action == 'del') { + $ret = delDocumentModel($value, $type); + if ($ret > 0) { + $tmpobjectkey = GETPOST('object'); + if (!empty($tmpobjectkey)) { + $constforval = 'ASSET_'.strtoupper($tmpobjectkey).'_ADDON_PDF'; + if ($conf->global->$constforval == "$value") { + dolibarr_del_const($db, $constforval, $conf->entity); + } + } + } +} elseif ($action == 'setdoc') { + // Set or unset default model + $tmpobjectkey = GETPOST('object'); + if (!empty($tmpobjectkey)) { + $constforval = 'ASSET_'.strtoupper($tmpobjectkey).'_ADDON_PDF'; + if (dolibarr_set_const($db, $constforval, $value, 'chaine', 0, '', $conf->entity)) { + // The constant that was read before the new set + // We therefore requires a variable to have a coherent view + $conf->global->$constforval = $value; + } + + // We disable/enable the document template (into llx_document_model table) + $ret = delDocumentModel($value, $type); + if ($ret > 0) { + $ret = addDocumentModel($value, $type, $label, $scandir); + } + } +} elseif ($action == 'unsetdoc') { + $tmpobjectkey = GETPOST('object'); + if (!empty($tmpobjectkey)) { + $constforval = 'ASSET_'.strtoupper($tmpobjectkey).'_ADDON_PDF'; + dolibarr_del_const($db, $constforval, $conf->entity); + } +} + /* * View */ -llxHeader('', $langs->trans("AssetsSetup")); +$form = new Form($db); -$linkback = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("AssetsSetup"), $linkback, 'title_setup'); +$help_url = ''; +$page_name = "AssetSetup"; + +llxHeader('', $langs->trans($page_name), $help_url); + +// Subheader +$linkback = ''.$langs->trans("BackToModuleList").''; + +print load_fiche_titre($langs->trans($page_name), $linkback, 'title_setup'); + +// Configuration header +$head = assetAdminPrepareHead(); +print dol_get_fiche_head($head, 'settings', $langs->trans($page_name), -1, "asset"); + +// Setup page goes here +echo ''.$langs->trans("AssetSetupPage").''; -$head = asset_admin_prepare_head(); +$moduledir = 'asset'; +$myTmpObjects = array(); +$myTmpObjects['Asset'] = array('includerefgeneration'=>1, 'includedocgeneration'=>0); -print dol_get_fiche_head($head, 'settings', $langs->trans("Assets"), -1, 'generic'); +foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { + if ($myTmpObjectKey == 'MyObject') { + continue; + } + if ($myTmpObjectArray['includerefgeneration']) { + /* + * Orders Numbering model + */ + $setupnotempty++; + + print load_fiche_titre($langs->trans("NumberingModules", $myTmpObjectKey), '', ''); + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''."\n"; + + clearstatcache(); + + foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/".$moduledir); + + if (is_dir($dir)) { + $handle = opendir($dir); + if (is_resource($handle)) { + while (($file = readdir($handle)) !== false) { + if (strpos($file, 'mod_'.strtolower($myTmpObjectKey).'_') === 0 && substr($file, dol_strlen($file) - 3, 3) == 'php') { + $file = substr($file, 0, dol_strlen($file) - 4); + + require_once $dir.'/'.$file.'.php'; + + $module = new $file($db); + + // Show modules according to features level + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) { + continue; + } + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) { + continue; + } + + if ($module->isEnabled()) { + dol_include_once('/'.$moduledir.'/class/'.strtolower($myTmpObjectKey).'.class.php'); + + print ''; + + // Show example of numbering model + print ''."\n"; + + print ''; + + $mytmpinstance = new $myTmpObjectKey($db); + $mytmpinstance->initAsSpecimen(); + + // Info + $htmltooltip = ''; + $htmltooltip .= ''.$langs->trans("Version").': '.$module->getVersion().'
'; + + $nextval = $module->getNextValue($mytmpinstance); + if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval + $htmltooltip .= ''.$langs->trans("NextValue").': '; + if ($nextval) { + if (preg_match('/^Error/', $nextval) || $nextval == 'NotConfigured') { + $nextval = $langs->trans($nextval); + } + $htmltooltip .= $nextval.'
'; + } else { + $htmltooltip .= $langs->trans($module->error).'
'; + } + } + + print ''; + + print "\n"; + } + } + } + closedir($handle); + } + } + } + print "
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Status").''.$langs->trans("ShortInfo").'
'.$module->name."\n"; + print $module->info(); + print ''; + $tmp = $module->getExample(); + if (preg_match('/^Error/', $tmp)) { + $langs->load("errors"); + print '
'.$langs->trans($tmp).'
'; + } elseif ($tmp == 'NotConfigured') { + print $langs->trans($tmp); + } else { + print $tmp; + } + print '
'; + $constforvar = 'ASSET_'.strtoupper($myTmpObjectKey).'_ADDON'; + if (getDolGlobalString($constforvar) == $file) { + print img_picto($langs->trans("Activated"), 'switch_on'); + } else { + print ''; + print img_picto($langs->trans("Disabled"), 'switch_off'); + print ''; + } + print ''; + print $form->textwithpicto('', $htmltooltip, 1, 0); + print '

\n"; + } + + if ($myTmpObjectArray['includedocgeneration']) { + /* + * Document templates generators + */ + $setupnotempty++; + $type = strtolower($myTmpObjectKey); + + print load_fiche_titre($langs->trans("DocumentModules", $myTmpObjectKey), '', ''); + + // Load array def with activated templates + $def = array(); + $sql = "SELECT nom"; + $sql .= " FROM ".MAIN_DB_PREFIX."document_model"; + $sql .= " WHERE type = '".$db->escape($type)."'"; + $sql .= " AND entity = ".$conf->entity; + $resql = $db->query($sql); + if ($resql) { + $i = 0; + $num_rows = $db->num_rows($resql); + while ($i < $num_rows) { + $array = $db->fetch_array($resql); + array_push($def, $array[0]); + $i++; + } + } else { + dol_print_error($db); + } + + print "\n"; + print "\n"; + print ''; + print ''; + print '\n"; + print '\n"; + print ''; + print ''; + print "\n"; + + clearstatcache(); + + foreach ($dirmodels as $reldir) { + foreach (array('', '/doc') as $valdir) { + $realpath = $reldir."core/modules/".$moduledir.$valdir; + $dir = dol_buildpath($realpath); + + if (is_dir($dir)) { + $handle = opendir($dir); + if (is_resource($handle)) { + while (($file = readdir($handle)) !== false) { + $filelist[] = $file; + } + closedir($handle); + arsort($filelist); + + foreach ($filelist as $file) { + if (preg_match('/\.modules\.php$/i', $file) && preg_match('/^(pdf_|doc_)/', $file)) { + if (file_exists($dir.'/'.$file)) { + $name = substr($file, 4, dol_strlen($file) - 16); + $classname = substr($file, 0, dol_strlen($file) - 12); + + require_once $dir.'/'.$file; + $module = new $classname($db); + + $modulequalified = 1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) { + $modulequalified = 0; + } + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) { + $modulequalified = 0; + } + + if ($modulequalified) { + print ''; + + // Active + if (in_array($name, $def)) { + print ''; + } else { + print '"; + } + + // Default + print ''; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip .= '
'.$langs->trans("Type").': '.($module->type ? $module->type : $langs->trans("Unknown")); + if ($module->type == 'pdf') { + $htmltooltip .= '
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + } + $htmltooltip .= '
'.$langs->trans("Path").': '.preg_replace('/^\//', '', $realpath).'/'.$file; + + $htmltooltip .= '

'.$langs->trans("FeaturesSupported").':'; + $htmltooltip .= '
'.$langs->trans("Logo").': '.yn($module->option_logo, 1, 1); + $htmltooltip .= '
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang, 1, 1); + + print ''; + + // Preview + print ''; + + print "\n"; + } + } + } + } + } + } + } + } + + print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
'; + print (empty($module->name) ? $name : $module->name); + print "\n"; + if (method_exists($module, 'info')) { + print $module->info($langs); + } else { + print $module->description; + } + print ''."\n"; + print ''; + print img_picto($langs->trans("Enabled"), 'switch_on'); + print ''; + print ''."\n"; + print 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; + print "'; + $constforvar = 'ASSET_'.strtoupper($myTmpObjectKey).'_ADDON'; + if (getDolGlobalString($constforvar) == $name) { + //print img_picto($langs->trans("Default"), 'on'); + // Even if choice is the default value, we allow to disable it. Replace this with previous line if you need to disable unset + print 'scandir).'&label='.urlencode($module->name).'&type='.urlencode($type).'" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; + } else { + print 'scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; + } + print ''; + print $form->textwithpicto('', $htmltooltip, 1, 0); + print ''; + if ($module->type == 'pdf') { + print ''.img_object($langs->trans("Preview"), 'pdf').''; + } else { + print img_object($langs->trans("PreviewNotAvailable"), 'generic'); + } + print '
'; + } +} if ($action == 'edit') { print '
'; @@ -73,37 +464,221 @@ if ($action == 'edit') { print ''; print ''; - foreach ($arrayofparameters as $key => $val) { - print ''; - } + foreach ($arrayofparameters as $constname => $val) { + if ($val['enabled']==1) { + $setupnotempty++; + print ''; + } + } print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; - print $form->textwithpicto($langs->trans($key), $langs->trans($key.'Tooltip')); - print '
'; + $tooltiphelp = (($langs->trans($constname . 'Tooltip') != $constname . 'Tooltip') ? $langs->trans($constname . 'Tooltip') : ''); + print ''.$form->textwithpicto($langs->trans($constname), $tooltiphelp, 1, 'info', '', 0, 3, 'tootips'.$constname).''; + print ''; + if ($val['type'] == 'textarea') { + print '\n"; + } elseif ($val['type']== 'html') { + require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; + $doleditor = new DolEditor($constname, $conf->global->{$constname}, '', 160, 'dolibarr_notes', '', false, false, $conf->fckeditor->enabled, ROWS_5, '90%'); + $doleditor->Create(); + } elseif ($val['type'] == 'yesno') { + print $form->selectyesno($constname, $conf->global->{$constname}, 1); + } elseif (preg_match('/emailtemplate:/', $val['type'])) { + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + $tmp = explode(':', $val['type']); + $nboftemplates = $formmail->fetchAllEMailTemplate($tmp[1], $user, null, 1); // We set lang=null to get in priority record with no lang + //$arraydefaultmessage = $formmail->getEMailTemplate($db, $tmp[1], $user, null, 0, 1, ''); + $arrayofmessagename = array(); + if (is_array($formmail->lines_model)) { + foreach ($formmail->lines_model as $modelmail) { + //var_dump($modelmail); + $moreonlabel = ''; + if (!empty($arrayofmessagename[$modelmail->label])) { + $moreonlabel = ' (' . $langs->trans("SeveralLangugeVariatFound") . ')'; + } + // The 'label' is the key that is unique if we exclude the language + $arrayofmessagename[$modelmail->id] = $langs->trans(preg_replace('/\(|\)/', '', $modelmail->label)) . $moreonlabel; + } + } + print $form->selectarray($constname, $arrayofmessagename, $conf->global->{$constname}, 'None', 0, 0, '', 0, 0, 0, '', '', 1); + } elseif (preg_match('/category:/', $val['type'])) { + require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; + $formother = new FormOther($db); + + $tmp = explode(':', $val['type']); + print img_picto('', 'category', 'class="pictofixedwidth"'); + print $formother->select_categories($tmp[1], $conf->global->{$constname}, $constname, 0, $langs->trans('CustomersProspectsCategoriesShort')); + } elseif (preg_match('/thirdparty_type/', $val['type'])) { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; + $formcompany = new FormCompany($db); + print $formcompany->selectProspectCustomerType($conf->global->{$constname}, $constname); + } elseif ($val['type'] == 'securekey') { + print ''; + if (!empty($conf->use_javascript_ajax)) { + print ' '.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_token'.$constname.'" class="linkobject"'); + } + if (!empty($conf->use_javascript_ajax)) { + print "\n".''; + } + } elseif ($val['type'] == 'product') { + if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { + $selected = (empty($conf->global->$constname) ? '' : $conf->global->$constname); + $form->select_produits($selected, $constname, '', 0); + } + } elseif ($val['type'] == 'accountancy_code') { + $selected = (empty($conf->global->$constname) ? '' : $conf->global->$constname); + if (!empty($conf->accounting->enabled)) { + require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php'; + $formaccounting = new FormAccounting($db); + print $formaccounting->select_account($selected, $constname, 1, null, 1, 1, 'minwidth150 maxwidth300', 1); + } else { + print ''; + } + } elseif ($val['type'] == 'accountancy_category') { + $selected = (empty($conf->global->$constname) ? '' : $conf->global->$constname); + if (!empty($conf->accounting->enabled)) { + print ''; + // autosuggest from existing account types if found + print ''; + require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountancysystem.class.php'; + $accountsystem = new AccountancySystem($db); + $accountsystem->fetch($conf->global->CHARTOFACCOUNTS); + $sql = 'SELECT DISTINCT pcg_type FROM ' . MAIN_DB_PREFIX . 'accounting_account'; + $sql .= " WHERE fk_pcg_version = '" . $db->escape($accountsystem->ref) . "'"; + $sql .= ' AND entity in ('.getEntity('accounting_account', 0).')'; // Always limit to current entity. No sharing in accountancy. + $sql .= ' LIMIT 50000'; // just as a sanity check + $resql = $db->query($sql); + if ($resql) { + while ($obj = $db->fetch_object($resql)) { + print ''; + } else { + print ''; + } + } else { + print ''; + } + print '
'; - print $form->buttonsSaveCancel("Save", ''); + print '
'; + print ''; + print '
'; print '
'; print '
'; } else { - print ''; - print ''; + if (!empty($arrayofparameters)) { + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + print ''; - foreach ($arrayofparameters as $key => $val) { - print ''; + foreach ($arrayofparameters as $constname => $val) { + if ($val['enabled']==1) { + $setupnotempty++; + print ''; + } + } + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; - print $form->textwithpicto($langs->trans($key), $langs->trans($key.'Tooltip')); - print ''.$conf->global->$key.'
'; + $tooltiphelp = (($langs->trans($constname . 'Tooltip') != $constname . 'Tooltip') ? $langs->trans($constname . 'Tooltip') : ''); + print $form->textwithpicto($langs->trans($constname), $tooltiphelp); + print ''; + + if ($val['type'] == 'textarea') { + print dol_nl2br($conf->global->{$constname}); + } elseif ($val['type']== 'html') { + print $conf->global->{$constname}; + } elseif ($val['type'] == 'yesno') { + print ajax_constantonoff($constname); + } elseif (preg_match('/emailtemplate:/', $val['type'])) { + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + $tmp = explode(':', $val['type']); + + $template = $formmail->getEMailTemplate($db, $tmp[1], $user, $langs, $conf->global->{$constname}); + if ($template<0) { + setEventMessages(null, $formmail->errors, 'errors'); + } + print $langs->trans($template->label); + } elseif (preg_match('/category:/', $val['type'])) { + $c = new Categorie($db); + $result = $c->fetch($conf->global->{$constname}); + if ($result < 0) { + setEventMessages(null, $c->errors, 'errors'); + } elseif ($result > 0 ) { + $ways = $c->print_all_ways(' >> ', 'none', 0, 1); // $ways[0] = "ccc2 >> ccc2a >> ccc2a1" with html formated text + $toprint = array(); + foreach ($ways as $way) { + $toprint[] = '
  • color ? ' style="background: #' . $c->color . ';"' : ' style="background: #bbb"') . '>' . $way . '
  • '; + } + print '
      ' . implode(' ', $toprint) . '
    '; + } + } elseif (preg_match('/thirdparty_type/', $val['type'])) { + if ($conf->global->{$constname}==2) { + print $langs->trans("Prospect"); + } elseif ($conf->global->{$constname}==3) { + print $langs->trans("ProspectCustomer"); + } elseif ($conf->global->{$constname}==1) { + print $langs->trans("Customer"); + } elseif ($conf->global->{$constname}==0) { + print $langs->trans("NorProspectNorCustomer"); + } + } elseif ($val['type'] == 'product') { + $product = new Product($db); + $resprod = $product->fetch($conf->global->{$constname}); + if ($resprod > 0) { + print $product->ref; + } elseif ($resprod < 0) { + setEventMessages(null, $object->errors, "errors"); + } + } elseif ($val['type'] == 'accountancy_code') { + if (!empty($conf->accounting->enabled)) { + require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php'; + $accountingaccount = new AccountingAccount($db); + $accountingaccount->fetch('', $conf->global->{$constname}, 1); + + print $accountingaccount->getNomUrl(0, 1, 1, '', 1); + } else { + print $conf->global->{$constname}; + } + } else { + print $conf->global->{$constname}; + } + print '
    '; + + print '
    '; + print ''.$langs->trans("Modify").''; + print '
    '; + } else { + print '
    '.$langs->trans("NothingToSetup"); } - - print ''; - - print '
    '; - print ''.$langs->trans("Modify").''; - print '
    '; } +if (empty($setupnotempty)) { + print '
    '.$langs->trans("NothingToSetup"); +} + +// Page end print dol_get_fiche_end(); -// End of page llxFooter(); $db->close(); diff --git a/htdocs/asset/agenda.php b/htdocs/asset/agenda.php new file mode 100644 index 00000000000..49a0c215701 --- /dev/null +++ b/htdocs/asset/agenda.php @@ -0,0 +1,215 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * 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 . + */ + +/** + * \file htdocs/asset/agenda.php + * \ingroup asset + * \brief Tab of events on Asset + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/asset/class/asset.class.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "other")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$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' : (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT)); +} +$search_agenda_label = GETPOST('search_agenda_label'); + +$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +if (empty($page) || $page == -1) { + $page = 0; +} // If $page is not defined, or '' or -1 +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (!$sortfield) { + $sortfield = 'a.datep,a.id'; +} +if (!$sortorder) { + $sortorder = 'DESC,DESC'; +} + +// Initialize technical objects +$object = new Asset($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('assetagenda', '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->asset->multidir_output[$object->entity]."/".$object->id; +} + +$permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); + + +/* + * 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'; + llxHeader('', $title, $help_url); + + if (!empty($conf->notification->enabled)) { + $langs->load("mails"); + } + $head = assetPrepareHead($object); + + + print dol_get_fiche_head($head, 'agenda', $langs->trans("Asset"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + print '
    '; + + $object->info($object->id); + dol_print_object_info($object, 1); + + print '
    '; + + print dol_get_fiche_end(); + + + // Actions buttons + + $objthirdparty = $object; + $objcon = new stdClass(); + + $out = '&origin=' . urlencode($object->element . '@' . $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.='trans("AddAnAction"),'filenew'); + //$out.=""; + } + + + print '
    '; + + if (!empty($conf->agenda->enabled)) { + if (!empty($user->rights->agenda->myactions->create) || !empty($user->rights->agenda->allactions->create)) { + print '' . $langs->trans("AddAction") . ''; + } else { + print '' . $langs->trans("AddAction") . ''; + } + } + + print '
    '; + + if (!empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) { + $param = '&id=' . $object->id . '&socid=' . $socid; + if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { + $param .= '&contextpage=' . urlencode($contextpage); + } + if ($limit > 0 && $limit != $conf->liste_limit) { + $param .= '&limit=' . urlencode($limit); + } + + + print load_fiche_titre($langs->trans("ActionsOnAsset"), '', ''); + + // List of all actions + $filters = array(); + $filters['search_agenda_label'] = $search_agenda_label; + + // TODO Replace this with same code than into list.php + show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder, $object->module); + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/card.php b/htdocs/asset/card.php index 35c0ffcff88..d94ba613d91 100644 --- a/htdocs/asset/card.php +++ b/htdocs/asset/card.php @@ -1,6 +1,6 @@ - * Copyright (C) 2018 Alexandre Spangaro +/* Copyright (C) 2017 Laurent Destailleur + * Copyright (C) 2018 Alexandre Spangaro * * 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 @@ -29,7 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; // Load translation files required by the page -$langs->loadLangs(array("asset")); +$langs->loadLangs(array("assets", "other")); // Get parameters $id = GETPOST('id', 'int'); @@ -68,12 +68,6 @@ if (empty($action) && empty($id) && empty($ref)) { // Load object include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. -// Security check -if (!empty($user->socid)) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'asset', $id); - $permissiontoread = $user->rights->asset->read; $permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php $permissiontodelete = $user->rights->asset->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); @@ -81,7 +75,13 @@ $permissionnote = $user->rights->asset->write; // Used by the include of actions $permissiondellink = $user->rights->asset->write; // Used by the include of actions_dellink.inc.php $upload_dir = $conf->asset->multidir_output[isset($object->entity) ? $object->entity : 1]; -$error = 0; +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +if ($user->socid > 0) $socid = $user->socid; +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); /* @@ -95,6 +95,8 @@ if ($reshook < 0) { } if (empty($reshook)) { + $error = 0; + $backurlforlist = DOL_URL_ROOT.'/asset/list.php'; if (empty($backtopage) || ($cancel && empty($id))) { @@ -107,6 +109,27 @@ if (empty($reshook)) { } } + $object->oldcopy = dol_clone($object); + $triggermodname = 'ASSET_MODIFY'; // Name of trigger action code to execute when we modify record + + // Action dispose object + if ($action == 'confirm_disposal' && $confirm == 'yes' && $permissiontoadd) { + $object->disposal_date = dol_mktime(12, 0, 0, GETPOST('disposal_datemonth', 'int'), GETPOST('disposal_dateday', 'int'), GETPOST('disposal_dateyear', 'int')); // for date without hour, we use gmt + $object->disposal_amount_ht = GETPOST('disposal_amount', 'int'); + $object->fk_disposal_type = GETPOST('fk_disposal_type', 'int'); + $disposal_invoice_id = GETPOST('disposal_invoice_id', 'int'); + $object->disposal_depreciated = ((GETPOST('disposal_depreciated') == '1' || GETPOST('disposal_depreciated') == 'on') ? 1 : 0); + $object->disposal_subject_to_vat = ((GETPOST('disposal_subject_to_vat') == '1' || GETPOST('disposal_subject_to_vat') == 'on') ? 1 : 0); + + $result = $object->dispose($user, $disposal_invoice_id); + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } + $action = ''; + } elseif ($action == "add") { + $object->supplier_invoice_id = GETPOST('supplier_invoice_id', 'int'); + } + // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php'; @@ -122,13 +145,6 @@ if (empty($reshook)) { // Action to build doc include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; - if ($action == 'set_thirdparty' && $permissiontoadd) { - $object->setValueFrom('fk_soc', GETPOST('fk_soc', 'int'), '', '', 'date', '', $user, 'MYOBJECT_MODIFY'); - } - if ($action == 'classin' && $permissiontoadd) { - $object->setProject(GETPOST('projectid', 'int')); - } - // Actions to send emails $triggersendname = 'ASSET_SENTBYMAIL'; $autocopy = 'MAIN_MAIL_AUTOCOPY_ASSET_TO'; @@ -136,6 +152,7 @@ if (empty($reshook)) { include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; } + /* * View * @@ -150,7 +167,7 @@ llxHeader('', $title, $help_url); // Part to create if ($action == 'create') { - print load_fiche_titre($langs->trans("NewAsset"), '', $object->picto); + print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("Asset")), '', 'object_'.$object->picto); print '
    '; print ''; @@ -161,9 +178,16 @@ if ($action == 'create') { if ($backtopageforcancel) { print ''; } + if (GETPOSTISSET('supplier_invoice_id')) { + $object->fields['supplier_invoice_id'] = array('type' => 'integer:FactureFournisseur:fourn/class/fournisseur.facture.class.php:1:entity IN (__SHARED_ENTITIES__)', 'label' => 'SupplierInvoice', 'enabled' => '1', 'noteditable' => '1', 'position' => 280, 'notnull' => 0, 'visible' => 1, 'index' => 1, 'validate' => '1',); + print ''; + } print dol_get_fiche_head(array(), ''); + // Set some default values + //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue'; + print ''."\n"; // Common attributes @@ -185,12 +209,11 @@ if ($action == 'create') { // Part to edit record if (($id || $ref) && $action == 'edit') { - print load_fiche_titre($langs->trans("Assets")); + print load_fiche_titre($langs->trans("Asset"), '', 'object_'.$object->picto); print ''; print ''; print ''; - print ''; print ''; if ($backtopage) { print ''; @@ -222,18 +245,60 @@ if (($id || $ref) && $action == 'edit') { if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { $res = $object->fetch_optionals(); - $head = asset_prepare_head($object); + $head = assetPrepareHead($object); print dol_get_fiche_head($head, 'card', $langs->trans("Asset"), -1, $object->picto); $formconfirm = ''; // Confirmation to delete if ($action == 'delete') { - $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteAssets'), $langs->trans('ConfirmDeleteAsset'), 'confirm_delete', '', 0, 1); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteAsset'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); + } elseif ($action == 'disposal') { + // Disposal + $langs->load('bills'); + + $disposal_date = dol_mktime(12, 0, 0, GETPOST('disposal_datemonth', 'int'), GETPOST('disposal_dateday', 'int'), GETPOST('disposal_dateyear', 'int')); // for date without hour, we use gmt + $disposal_amount = GETPOST('disposal_amount', 'int'); + $fk_disposal_type = GETPOST('fk_disposal_type', 'int'); + $disposal_invoice_id = GETPOST('disposal_invoice_id', 'int'); + $disposal_depreciated = GETPOSTISSET('disposal_depreciated') ? GETPOST('disposal_depreciated') : 1; + $disposal_depreciated = !empty($disposal_depreciated) ? 1 : 0; + $disposal_subject_to_vat = GETPOSTISSET('disposal_subject_to_vat') ? GETPOST('disposal_subject_to_vat') : 1; + $disposal_subject_to_vat = !empty($disposal_subject_to_vat) ? 1 : 0; + + $object->fields['fk_disposal_type']['visible'] = 1; + $disposal_type_form = $object->showInputField(null, 'fk_disposal_type', $fk_disposal_type, '', '', '', 0); + $object->fields['fk_disposal_type']['visible'] = -2; + + $object->fields['disposal_invoice_id'] = array('type' => 'integer:Facture:compta/facture/class/facture.class.php::entity IN (__SHARED_ENTITIES__)', 'enabled' => '1', 'notnull' => 1, 'visible' => 1, 'index' => 1, 'validate' => '1',); + $disposal_invoice_form = $object->showInputField(null, 'disposal_invoice_id', $disposal_invoice_id, '', '', '', 0); + unset($object->fields['disposal_invoice_id']); + + // Create an array for form + $formquestion = array( + array('type' => 'date', 'name' => 'disposal_date', 'tdclass' => 'fieldrequired', 'label' => $langs->trans("AssetDisposalDate"), 'value' => $disposal_date), + array('type' => 'text', 'name' => 'disposal_amount', 'tdclass' => 'fieldrequired', 'label' => $langs->trans("AssetDisposalAmount"), 'value' => $disposal_amount), + array('type' => 'other', 'name' => 'fk_disposal_type', 'tdclass' => 'fieldrequired', 'label' => $langs->trans("AssetDisposalType"), 'value' => $disposal_type_form), + array('type' => 'other', 'name' => 'disposal_invoice_id', 'label' => $langs->trans("InvoiceCustomer"), 'value' => $disposal_invoice_form), + array('type' => 'checkbox', 'name' => 'disposal_depreciated', 'label' => $langs->trans("AssetDisposalDepreciated"), 'value' => $disposal_depreciated), + array('type' => 'checkbox', 'name' => 'disposal_subject_to_vat', 'label' => $langs->trans("AssetDisposalSubjectToVat"), 'value' => $disposal_subject_to_vat), + ); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('AssetDisposal'), $langs->trans('AssetConfirmDisposalAsk', $object->ref . ' - ' . $object->label), 'confirm_disposal', $formquestion, 'yes', 1); + } elseif ($action == 'reopen') { + // Re-open + // Create an array for form + $formquestion = array(); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ReOpen'), $langs->trans('AssetConfirmReOpenAsk', $object->ref), 'confirm_reopen', $formquestion, 'yes', 1); } + // Clone confirmation + /* elseif ($action == 'clone') { + // Create an array for form + $formquestion = array(); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); + }*/ // Call Hook formConfirm - $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); + $parameters = array('formConfirm' => $formconfirm); $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { $formconfirm .= $hookmanager->resPrint; @@ -250,24 +315,19 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $linkback = ''.$langs->trans("BackToList").''; $morehtmlref = '
    '; - /* - // Ref bis - $morehtmlref.=$form->editfieldkey("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->asset->creer, 'string', '', 0, 1); - $morehtmlref.=$form->editfieldval("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->asset->creer, 'string', '', null, null, '', 1); - // Thirdparty - $morehtmlref.='
    '.$langs->trans('ThirdParty') . ' : ' . $soc->getNomUrl(1); - */ $morehtmlref .= '
    '; + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + print '
    '; print '
    '; print '
    '; - print '
    '."\n"; + print '
    '."\n"; // Common attributes - //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // We change column just after this field + $keyforbreak='date_acquisition'; // We change column just before this field //unset($object->fields['fk_project']); // Hide field already shown in banner //unset($object->fields['fk_soc']); // Hide field already shown in banner include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; @@ -277,69 +337,100 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
    '; print '
    '; + print '
    '; print '
    '; print dol_get_fiche_end(); - - /* - * Buttons - */ - if ($user->socid == 0) { - print '
    '; - + // Buttons for actions + if ($action != 'presend' && $action != 'editline') { + print '
    ' . "\n"; $parameters = array(); $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } if (empty($reshook)) { - if ($user->rights->asset->write) { - print ''.$langs->trans("Modify").''."\n"; - } else { - print ''.$langs->trans('Modify').''."\n"; + // Send + if (empty($user->socid)) { + print dolGetButtonAction($langs->trans('SendMail'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=presend&mode=init&token=' . newToken() . '#formmailbeforetitle'); } - if ($user->rights->asset->delete) { - print ''.$langs->trans('Delete').''."\n"; - } else { - print ''.$langs->trans('Delete').''."\n"; + if ($object->status == $object::STATUS_DRAFT) { + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&token=' . newToken(), '', $permissiontoadd); } + + // Clone + //print dolGetButtonAction($langs->trans('ToClone'), '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=clone&token=' . newToken(), '', false && $permissiontoadd); + + if ($object->status == $object::STATUS_DRAFT) { + print dolGetButtonAction($langs->trans('AssetDisposal'), '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=disposal&token=' . newToken(), '', $permissiontoadd); + } else { + print dolGetButtonAction($langs->trans('ReOpen'), '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=reopen&token=' . newToken(), '', $permissiontoadd); + } + + // Delete (need delete permission, or if draft, just need create/modify permission) + print dolGetButtonAction($langs->trans('Delete'), '', 'delete', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=delete&token=' . newToken(), '', $permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)); } - print "
    "; + print '
    ' . "\n"; + } + + // Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; } if ($action != 'presend') { print '
    '; print ''; // ancre - // Documents - $filename = dol_sanitizeFileName($object->ref); - $filedir = $conf->contrat->dir_output."/".dol_sanitizeFileName($object->ref); - $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; - $genallowed = $user->rights->asset->read; // If you can read, you can build the PDF to read content - $delallowed = $user->rights->asset->write; // If you can create/edit, you can remove a file on card + $includedocgeneration = 0; - print $formfile->showdocuments('asset', $filename, $filedir, $urlsource, 0, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $soc->default_lang); + // Documents + if ($includedocgeneration) { + $objref = dol_sanitizeFileName($object->ref); + $relativepath = $objref.'/'.$objref.'.pdf'; + $filedir = $conf->asset->dir_output.'/'.$objref; + $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; + $genallowed = $user->rights->asset->read; // If you can read, you can build the PDF to read content + $delallowed = $user->rights->asset->write; // If you can create/edit, you can remove a file on card + print $formfile->showdocuments('asset:Asset', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang); + } // Show links to link elements $linktoelem = $form->showLinkToObjectBlock($object, null, array('asset')); $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + print '
    '; $MAXEVENT = 10; - $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-list-alt imgforviewmode', DOL_URL_ROOT.'/asset/info.php?id='.$object->id); + $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/asset/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, $object->element, $socid, 1, '', $MAXEVENT, '', $morehtmlright); + $somethingshown = $formactions->showactions($object, $object->element, 0, 1, '', $MAXEVENT, '', $morehtmlright); print '
    '; } -} + //Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; + } + + // Presend form + $modelmail = 'asset'; + $defaulttopic = 'InformationMessage'; + $diroutput = $conf->asset->dir_output; + $trackid = 'asset'.$object->id; + + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; +} // End of page llxFooter(); diff --git a/htdocs/asset/class/asset.class.php b/htdocs/asset/class/asset.class.php index e5ec21bfa6d..410af398bc7 100644 --- a/htdocs/asset/class/asset.class.php +++ b/htdocs/asset/class/asset.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2018 Alexandre Spangaro +/* Copyright (C) 2017 Laurent Destailleur + * Copyright (C) 2018 Alexandre Spangaro * * 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 @@ -19,7 +19,7 @@ /** * \file asset/class/asset.class.php * \ingroup asset - * \brief This file is a CRUD class file for asset (Create/Read/Update/Delete) + * \brief This file is a CRUD class file for Asset (Create/Read/Update/Delete) */ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; @@ -30,22 +30,28 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; class Asset extends CommonObject { /** - * @var string ID to identify managed object + * @var string ID of module. + */ + public $module = 'asset'; + + /** + * @var string ID to identify managed object. */ public $element = 'asset'; /** - * @var string Name of table without prefix where object is stored + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. */ public $table_element = 'asset'; /** - * @var int Does module support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int Does this object support multicompany module ? + * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table */ - public $ismultientitymanaged = 0; + public $ismultientitymanaged = 1; /** - * @var int Does asset support extrafields ? 0=No, 1=Yes + * @var int Does object support extrafields ? 0=No, 1=Yes */ public $isextrafieldmanaged = 1; @@ -54,111 +60,125 @@ class Asset extends CommonObject */ public $picto = 'asset'; - - const STATUS_DRAFT = 0; - const STATUS_VALIDATED = 1; - const STATUS_CANCELED = 9; - + const STATUS_DRAFT = 0; // In progress + const STATUS_DISPOSED = 9; // Disposed /** - * 'type' if the field format. + * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:Sortfield]]]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', '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)" * 'label' the translation key. - * 'enabled' is a condition when the field must be managed. - * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only. Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'picto' is code of a picto to show before value in forms + * 'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM) + * 'position' is the sort order of field. * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. * 'index' if we want an index in database. * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). - * 'position' is the sort order of field. * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. - * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). - * 'help' is a string visible as a tooltip on field + * 'isameasure' must be set to 1 or 2 if field can be used for measure. Field type must be summable like integer or double(24,8). Use 1 in most cases, or 2 if you don't want to see the column total into list (for example for percentage) + * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200' + * 'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click. + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arrayofkeyval' to set a list of values if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar' + * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. * 'comment' is not used. You can store here any text of your choice. It is not used by application. - * 'default' is a default value for creation (can still be replaced by the global setup of default values) - * 'showoncombobox' if field must be shown into the label of combobox + * 'validate' is 1 if need to validate with $this->validateField() + * 'copytoclipboard' is 1 or 2 to allow to add a picto to copy value into clipboard (1=picto after label, 2=picto after value) + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. */ /** * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. */ - public $fields = array( - 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'visible'=>-1, 'enabled'=>1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",), - 'ref' => array('type'=>'varchar(10)', 'label'=>'Ref', 'visible'=>1, 'enabled'=>1, 'position'=>10, 'notnull'=>1, 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object", 'showoncombobox'=>1), - 'entity' => array('type'=>'integer', 'label'=>'Entity', 'visible'=>0, 'enabled'=>1, 'position'=>20, 'notnull'=>1, 'index'=>1,), - 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'notnull'=>-1, 'searchall'=>1), - 'fk_asset_type' => array('type'=>'integer:AssetType:asset/class/asset_type.class.php', 'label'=>'AssetsType', 'visible'=>1, 'enabled'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'searchall'=>1), - 'amount_ht' => array('type'=>'double(24,8)', 'label'=>'AmountHTShort', 'visible'=>1, 'enabled'=>1, 'position'=>40, 'notnull'=>-1, 'isameasure'=>'1', 'help'=>"Help text",), - 'amount_vat' => array('type'=>'double(24,8)', 'label'=>'AmountVAT', 'visible'=>1, 'enabled'=>1, 'position'=>41, 'notnull'=>-1, 'isameasure'=>'1', 'help'=>"Help text",), - 'description' => array('type'=>'text', 'label'=>'Description', 'visible'=>-1, 'enabled'=>1, 'position'=>90, 'notnull'=>-1,), - 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'visible'=>-1, 'enabled'=>1, 'position'=>91, 'notnull'=>-1,), - 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'visible'=>-1, 'enabled'=>1, 'position'=>92, 'notnull'=>-1,), - 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'visible'=>-2, 'enabled'=>1, 'position'=>500, 'notnull'=>1,), - 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'visible'=>-2, 'enabled'=>1, 'position'=>501, 'notnull'=>1,), - 'fk_user_creat' => array('type'=>'integer', 'label'=>'UserAuthor', 'visible'=>-2, 'enabled'=>1, 'position'=>510, 'notnull'=>1,), - 'fk_user_modif' => array('type'=>'integer', 'label'=>'UserModif', 'visible'=>-2, 'enabled'=>1, 'position'=>511, 'notnull'=>-1,), - 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'visible'=>-2, 'enabled'=>1, 'position'=>1000, 'notnull'=>-1,), - 'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'notnull'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Active', '9'=>'Cancel')), + public $fields=array( + 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), + 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>20, 'notnull'=>1, 'visible'=>1, 'noteditable'=>'0', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'validate'=>'1', 'comment'=>"Reference of object"), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'showoncombobox'=>'2', 'validate'=>'1',), + 'fk_asset_model' => array('type'=>'integer:AssetModel:asset/class/assetmodel.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'AssetModel', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1, 'index'=>1, 'validate'=>'1',), + 'qty' => array('type'=>'real', 'label'=>'Qty', 'enabled'=>'1', 'position'=>50, 'notnull'=>1, 'visible'=>0, 'default'=>'1', 'isameasure'=>'1', 'css'=>'maxwidth75imp', 'validate'=>'1',), + 'acquisition_type' => array('type'=>'smallint', 'label'=>'AssetAcquisitionType', 'enabled'=>'1', 'position'=>60, 'notnull'=>1, 'visible'=>1, 'arrayofkeyval'=>array('0'=>'AssetAcquisitionTypeNew', '1'=>'AssetAcquisitionTypeOccasion'), 'validate'=>'1',), + 'asset_type' => array('type'=>'smallint', 'label'=>'AssetType', 'enabled'=>'1', 'position'=>70, 'notnull'=>1, 'visible'=>1, 'arrayofkeyval'=>array('0'=>'AssetTypeIntangible', '1'=>'AssetTypeTangible', '2'=>'AssetTypeInProgress', '3'=>'AssetTypeFinancial'), 'validate'=>'1',), + 'not_depreciated' => array('type'=>'boolean', 'label'=>'AssetNotDepreciated', 'enabled'=>'1', 'position'=>80, 'notnull'=>0, 'default'=>'0', 'visible'=>1, 'validate'=>'1',), + 'date_acquisition' => array('type'=>'date', 'label'=>'AssetDateAcquisition', 'enabled'=>'1', 'position'=>90, 'notnull'=>1, 'visible'=>1,), + 'date_start' => array('type'=>'date', 'label'=>'AssetDateStart', 'enabled'=>'1', 'position'=>100, 'notnull'=>0, 'visible'=>-1,), + 'acquisition_value_ht' => array('type'=>'price', 'label'=>'AssetAcquisitionValueHT', 'enabled'=>'1', 'position'=>110, 'notnull'=>1, 'visible'=>1, 'isameasure'=>'1', 'validate'=>'1',), + 'recovered_vat' => array('type'=>'price', 'label'=>'AssetRecoveredVAT', 'enabled'=>'1', 'position'=>120, 'notnull'=>0, 'visible'=>1, 'isameasure'=>'1', 'validate'=>'1',), + 'reversal_date' => array('type'=>'date', 'label'=>'AssetReversalDate', 'enabled'=>'1', 'position'=>130, 'notnull'=>0, 'visible'=>1,), + 'reversal_amount_ht' => array('type'=>'price', 'label'=>'AssetReversalAmountHT', 'enabled'=>'1', 'position'=>140, 'notnull'=>0, 'visible'=>1, 'isameasure'=>'1', 'validate'=>'1',), + 'disposal_date' => array('type'=>'date', 'label'=>'AssetDisposalDate', 'enabled'=>'1', 'position'=>200, 'notnull'=>0, 'visible'=>-2,), + 'disposal_amount_ht' => array('type'=>'price', 'label'=>'AssetDisposalAmount', 'enabled'=>'1', 'position'=>210, 'notnull'=>0, 'visible'=>-2, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1',), + 'fk_disposal_type' => array('type'=>'sellist:c_asset_disposal_type:label:rowid::active=1', 'label'=>'AssetDisposalType', 'enabled'=>'1', 'position'=>220, 'notnull'=>0, 'visible'=>-2, 'index'=>1, 'validate'=>'1',), + 'disposal_depreciated' => array('type'=>'boolean', 'label'=>'AssetDisposalDepreciated', 'enabled'=>'1', 'position'=>230, 'notnull'=>0, 'default'=>'0', 'visible'=>-2, 'validate'=>'1',), + 'disposal_subject_to_vat' => array('type'=>'boolean', 'label'=>'AssetDisposalSubjectToVat', 'enabled'=>'1', 'position'=>240, 'notnull'=>0, 'default'=>'0', 'visible'=>-2, 'validate'=>'1',), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>300, 'notnull'=>0, 'visible'=>0, 'validate'=>'1',), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>301, 'notnull'=>0, 'visible'=>0, 'validate'=>'1',), + 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,), + 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,), + 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'foreignkey'=>'user.rowid',), + 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), + 'last_main_doc' => array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>'1', 'position'=>600, 'notnull'=>0, 'visible'=>0,), + 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,), + 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,), + 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'default'=>'0', 'visible'=>2, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '9'=>'Canceled'), 'validate'=>'1',), ); - - /** - * @var int ID - */ public $rowid; - - /** - * @var string Ref - */ public $ref; - - /** - * @var int Entity - */ - public $entity; - - /** - * @var string Asset label - */ public $label; - - public $amount; - - /** - * @var int Thirdparty ID - */ - public $fk_soc; - - /** - * @var string description - */ - public $description; - - /** - * @var integer|string date_creation - */ + public $fk_asset_model; + public $reversal_amount_ht; + public $acquisition_value_ht; + public $recovered_vat; + public $reversal_date; + public $date_acquisition; + public $date_start; + public $qty; + public $acquisition_type; + public $asset_type; + public $not_depreciated; + public $disposal_date; + public $disposal_amount_ht; + public $fk_disposal_type; + public $disposal_depreciated; + public $disposal_subject_to_vat; + public $supplier_invoice_id; + public $note_public; + public $note_private; public $date_creation; - - public $tms; - - /** - * @var int ID - */ public $fk_user_creat; - - /** - * @var int ID - */ public $fk_user_modif; - - /** - * @var string import key - */ + public $last_main_doc; public $import_key; - - /** - * @var int Status - */ + public $model_pdf; public $status; + // /** + // * @var string Field with ID of parent key if this object has a parent + // */ + // public $fk_element = 'fk_asset'; + // /** + // * @var array List of child tables. To test if we can delete object. + // */ + // protected $childtables = array(); + // /** + // * @var array List of child tables. To know object to delete on cascade. + // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will + // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object + // */ + // protected $childtablesoncascade = array('asset_assetdet'); + + /** + * @var AssetDepreciationOptions Used for computed fields of depreciation options class. + */ + public $asset_depreciation_options; + /** + * @var array List of depreciation lines for each mode (sort by depreciation date). + */ + public $depreciation_lines = array(); /** * Constructor @@ -167,16 +187,34 @@ class Asset extends CommonObject */ public function __construct(DoliDB $db) { - global $conf; + global $conf, $langs; $this->db = $db; - if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) { + if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) { $this->fields['rowid']['visible'] = 0; } - if (empty($conf->multicompany->enabled)) { + if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) { $this->fields['entity']['enabled'] = 0; } + + // Unset fields that are disabled + foreach ($this->fields as $key => $val) { + if (isset($val['enabled']) && empty($val['enabled'])) { + unset($this->fields[$key]); + } + } + + // Translate some data of arrayofkeyval + if (is_object($langs)) { + foreach ($this->fields as $key => $val) { + if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { + foreach ($val['arrayofkeyval'] as $key2 => $val2) { + $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2); + } + } + } + } } /** @@ -188,11 +226,27 @@ class Asset extends CommonObject */ public function create(User $user, $notrigger = false) { - return $this->createCommon($user, $notrigger); + if (!isset($this->date_start) || $this->date_start === "") $this->date_start = $this->date_acquisition; + + $this->db->begin(); + + $result = $result_create = $this->createCommon($user, $notrigger); + if ($result > 0 && $this->fk_asset_model > 0) $result = $this->setDataFromAssetModel($user, $notrigger); + if ($result > 0) { + if ($this->supplier_invoice_id > 0) $this->add_object_linked('invoice_supplier', $this->supplier_invoice_id); + } + + if ($result < 0) { + $this->db->rollback(); + } else { + $this->db->commit(); + } + + return $result > 0 ? $result_create : $result; } /** - * Clone and object into another one + * Clone an object into another one * * @param User $user User that creates * @param int $fromid Id of object to clone @@ -200,45 +254,95 @@ class Asset extends CommonObject */ public function createFromClone(User $user, $fromid) { - global $hookmanager, $langs; + global $langs, $extrafields; $error = 0; dol_syslog(__METHOD__, LOG_DEBUG); - $object = new self($this->db); - - $this->db->begin(); - - // Load source object - $object->fetchCommon($fromid); - // Reset some properties - unset($object->id); - unset($object->fk_user_creat); - unset($object->import_key); - - // Clear fields - $object->ref = "copy_of_".$object->ref; - $object->title = $langs->trans("CopyOf")." ".$object->title; - - // Create clone - $object->context['createfromclone'] = 'createfromclone'; - $result = $object->createCommon($user); - if ($result < 0) { - $error++; - $this->error = $object->error; - $this->errors = $object->errors; - } - - unset($object->context['createfromclone']); - - // End - if (!$error) { - $this->db->commit(); - return $object; - } else { - $this->db->rollback(); - return -1; - } + // $object = new self($this->db); + // + // $this->db->begin(); + // + // // Load source object + // $result = $object->fetchCommon($fromid); + // if ($result > 0 && !empty($object->table_element_line)) { + // $object->fetchLines(); + // } + // + // // get lines so they will be clone + // //foreach($this->lines as $line) + // // $line->fetch_optionals(); + // + // // Reset some properties + // unset($object->id); + // unset($object->fk_user_creat); + // unset($object->import_key); + // + // // Clear fields + // if (property_exists($object, 'ref')) { + // $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default']; + // } + // if (property_exists($object, 'label')) { + // $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default']; + // } + // if (property_exists($object, 'status')) { + // $object->status = self::STATUS_DRAFT; + // } + // if (property_exists($object, 'date_creation')) { + // $object->date_creation = dol_now(); + // } + // if (property_exists($object, 'date_modification')) { + // $object->date_modification = null; + // } + // // ... + // // Clear extrafields that are unique + // if (is_array($object->array_options) && count($object->array_options) > 0) { + // $extrafields->fetch_name_optionals_label($this->table_element); + // foreach ($object->array_options as $key => $option) { + // $shortkey = preg_replace('/options_/', '', $key); + // if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) { + // //var_dump($key); var_dump($clonedObj->array_options[$key]); exit; + // unset($object->array_options[$key]); + // } + // } + // } + // + // // Create clone + // $object->context['createfromclone'] = 'createfromclone'; + // $result = $object->createCommon($user); + // if ($result < 0) { + // $error++; + // $this->error = $object->error; + // $this->errors = $object->errors; + // } + // + // if (!$error) { + // // copy internal contacts + // if ($this->copy_linked_contact($object, 'internal') < 0) { + // $error++; + // } + // } + // + // if (!$error) { + // // copy external contacts if same company + // if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) { + // if ($this->copy_linked_contact($object, 'external') < 0) { + // $error++; + // } + // } + // } + // + // unset($object->context['createfromclone']); + // + // // End + // if (!$error) { + // $this->db->commit(); + // return $object; + // } else { + // $this->db->rollback(); + // return -1; + // } + return -1; } /** @@ -251,7 +355,21 @@ class Asset extends CommonObject public function fetch($id, $ref = null) { $result = $this->fetchCommon($id, $ref); - //if ($result > 0 && ! empty($this->table_element_line)) $this->fetchLines(); + if ($result > 0) { + if (!empty($this->table_element_line)) $this->fetchLines(); + + $res = $this->hasDepreciationLinesInBookkeeping(); + if ($res < 0) { + return -1; + } elseif ($res > 0) { + $this->fields['date_acquisition']['noteditable'] = '1'; + $this->fields['date_start']['noteditable'] = '1'; + $this->fields['acquisition_value_ht']['noteditable'] = '1'; + $this->fields['recovered_vat']['noteditable'] = '1'; + $this->fields['reversal_date']['noteditable'] = '1'; + $this->fields['reversal_amount_ht']['noteditable'] = '1'; + } + } return $result; } @@ -260,14 +378,93 @@ class Asset extends CommonObject * * @return int <0 if KO, 0 if not found, >0 if OK */ - /*public function fetchLines() + public function fetchLines() { - $this->lines=array(); + $this->lines = array(); - // Load lines with object AssetsLine + return 1; + } - return count($this->lines)?1:0; - }*/ + + /** + * Load list of objects in memory from the database. + * + * @param string $sortorder Sort Order + * @param string $sortfield Sort field + * @param int $limit limit + * @param int $offset Offset + * @param array $filter Filter array. Example array('field'=>'valueforlike', 'customurl'=>...) + * @param string $filtermode Filter mode (AND or OR) + * @return array|int int <0 if KO, array of pages if OK + */ + public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') + { + global $conf; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $records = array(); + + $sql = "SELECT "; + $sql .= $this->getFieldList('t'); + $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t"; + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) { + $sql .= " WHERE t.entity IN (".getEntity($this->table_element).")"; + } else { + $sql .= " WHERE 1 = 1"; + } + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + if ($key == 't.rowid') { + $sqlwhere[] = $key." = ".((int) $value); + } elseif (in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) { + $sqlwhere[] = $key." = '".$this->db->idate($value)."'"; + } elseif ($key == 'customsql') { + $sqlwhere[] = $value; + } elseif (strpos($value, '%') === false) { + $sqlwhere[] = $key." IN (".$this->db->sanitize($this->db->escape($value)).")"; + } else { + $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'"; + } + } + } + if (count($sqlwhere) > 0) { + $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")"; + } + + if (!empty($sortfield)) { + $sql .= $this->db->order($sortfield, $sortorder); + } + if (!empty($limit)) { + $sql .= $this->db->plimit($limit, $offset); + } + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < ($limit ? min($limit, $num) : $num)) { + $obj = $this->db->fetch_object($resql); + + $record = new self($this->db); + $record->setVarsFromFetchObj($obj); + + $records[$record->id] = $record; + + $i++; + } + $this->db->free($resql); + + return $records; + } else { + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + + return -1; + } + } /** * Update object into database @@ -278,7 +475,32 @@ class Asset extends CommonObject */ public function update(User $user, $notrigger = false) { - return $this->updateCommon($user, $notrigger); + if (!isset($this->date_start) || $this->date_start === "") $this->date_start = $this->date_acquisition; + + $this->db->begin(); + + $result = $this->updateCommon($user, $notrigger); + if ($result > 0 && $this->fk_asset_model > 0 && $this->fk_asset_model != $this->oldcopy->fk_asset_model) { + $result = $this->setDataFromAssetModel($user, $notrigger); + } + if ($result > 0 && ( + $this->date_start != $this->oldcopy->date_start || + $this->acquisition_value_ht != $this->oldcopy->acquisition_value_ht || + $this->reversal_date != $this->oldcopy->reversal_date || + $this->reversal_amount_ht != $this->oldcopy->reversal_amount_ht || + ($this->fk_asset_model > 0 && $this->fk_asset_model != $this->oldcopy->fk_asset_model) + ) + ) { + $result = $this->calculationDepreciation(); + } + + if ($result < 0) { + $this->db->rollback(); + } else { + $this->db->commit(); + } + + return $result; } /** @@ -291,21 +513,760 @@ class Asset extends CommonObject public function delete(User $user, $notrigger = false) { return $this->deleteCommon($user, $notrigger); + //return $this->deleteCommon($user, $notrigger, 1); + } + + /** + * Set asset model + * + * @param User $user User that creates + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, Id of created object if OK + */ + public function setDataFromAssetModel(User $user, $notrigger = false) + { + global $langs; + $langs->load('assets'); + + // Clean parameters + $this->id = $this->id > 0 ? $this->id : 0; + $this->fk_asset_model = $this->fk_asset_model > 0 ? $this->fk_asset_model : 0; + + // Check parameters + $error = 0; + if (empty($this->id)) { + $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')'); + $error++; + } + if (empty($this->fk_asset_model)) { + $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("AssetModel") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')'); + $error++; + } + if ($error) { + return -1; + } + + $this->db->begin(); + + // Get depreciation options + //--------------------------- + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php'; + $options_model = new AssetDepreciationOptions($this->db); + $result = $options_model->fetchDeprecationOptions(0, $this->fk_asset_model); + if ($result < 0) { + $this->error = $options_model->error; + $this->errors = $options_model->errors; + $error++; + } elseif ($result > 0) { + $options = new AssetDepreciationOptions($this->db); + $result = $options->fetchDeprecationOptions($this->id); + if ($result < 0) { + $this->error = $options->error; + $this->errors = $options->errors; + $error++; + } + + if (!$error) { + foreach ($options_model->deprecation_options as $mode_key => $fields) { + foreach ($fields as $field_key => $value) { + $options->deprecation_options[$mode_key][$field_key] = $value; + } + } + + $result = $options->updateDeprecationOptions($user, $this->id, 0, $notrigger); + if ($result < 0) { + $this->error = $options->error; + $this->errors = $options->errors; + $error++; + } + } + } + + // Get accountancy codes + //--------------------------- + if (!$error) { + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php'; + $accountancy_codes_model = new AssetAccountancyCodes($this->db); + $result = $accountancy_codes_model->fetchAccountancyCodes(0, $this->fk_asset_model); + if ($result < 0) { + $this->error = $accountancy_codes_model->error; + $this->errors = $accountancy_codes_model->errors; + $error++; + } elseif ($result > 0) { + $accountancy_codes = new AssetAccountancyCodes($this->db); + $result = $accountancy_codes->fetchAccountancyCodes($this->id); + if ($result < 0) { + $this->error = $accountancy_codes->error; + $this->errors = $accountancy_codes->errors; + $error++; + } + + if (!$error) { + foreach ($accountancy_codes_model->accountancy_codes as $mode_key => $fields) { + foreach ($fields as $field_key => $value) { + $accountancy_codes->accountancy_codes[$mode_key][$field_key] = $value; + } + } + + $result = $accountancy_codes->updateAccountancyCodes($user, $this->id, 0, $notrigger); + if ($result < 0) { + $this->error = $accountancy_codes->error; + $this->errors = $accountancy_codes->errors; + $error++; + } + } + } + } + + if ($error) { + $this->db->rollback(); + return -1; + } else { + $this->db->commit(); + return 1; + } + } + + /** + * Fetch depreciation lines for each mode in $this->depreciation_lines (sort by depreciation date) + * + * @return int <0 if KO, Id of created object if OK + */ + public function fetchDepreciationLines() + { + global $langs; + $langs->load('assets'); + $this->depreciation_lines = array(); + + // Clean parameters + $this->id = $this->id > 0 ? $this->id : 0; + + // Check parameters + $error = 0; + if (empty($this->id)) { + $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')'); + $error++; + } + if ($error) { + return -1; + } + + $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS ("; + $sql .= " SELECT DISTINCT fk_docdet"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping"; + $sql .= " WHERE doc_type = 'asset'"; + $sql .= ")"; + $sql .= "SELECT ad.rowid, ad.depreciation_mode, ad.ref, ad.depreciation_date, ad.depreciation_ht, ad.cumulative_depreciation_ht"; + $sql .= ", " . $this->db->ifsql('iab.fk_docdet IS NOT NULL', 1, 0) . " AS bookkeeping"; + $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad"; + $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid"; + $sql .= " WHERE ad.fk_asset = " . (int) $this->id; + $sql .= " ORDER BY ad.depreciation_date ASC"; + + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorFetchDepreciationLines') . ': ' . $this->db->lasterror(); + return -1; + } + + while ($obj = $this->db->fetch_object($resql)) { + if (!isset($this->depreciation_lines[$obj->depreciation_mode])) $this->depreciation_lines[$obj->depreciation_mode] = array(); + $this->depreciation_lines[$obj->depreciation_mode][] = array( + 'id' => $obj->rowid, + 'ref' => $obj->ref, + 'depreciation_date' => $this->db->jdate($obj->depreciation_date), + 'depreciation_ht' => $obj->depreciation_ht, + 'cumulative_depreciation_ht' => $obj->cumulative_depreciation_ht, + 'bookkeeping' => $obj->bookkeeping, + ); + } + + return 1; + } + + /** + * If has depreciation lines in bookkeeping + * + * @return int <0 if KO, 0 if NO, 1 if Yes + */ + public function hasDepreciationLinesInBookkeeping() + { + global $langs; + $langs->load('assets'); + + // Clean parameters + $this->id = $this->id > 0 ? $this->id : 0; + + // Check parameters + $error = 0; + if (empty($this->id)) { + $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')'); + $error++; + } + if ($error) { + return -1; + } + + $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS ("; + $sql .= " SELECT DISTINCT fk_docdet"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping"; + $sql .= " WHERE doc_type = 'asset'"; + $sql .= ")"; + $sql .= "SELECT COUNT(*) AS has_bookkeeping"; + $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad"; + $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid"; + $sql .= " WHERE ad.fk_asset = " . (int) $this->id; + $sql .= " AND iab.fk_docdet IS NOT NULL"; + + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorFetchDepreciationLines') . ': ' . $this->db->lasterror(); + return -1; + } + + if ($obj = $this->db->fetch_object($resql)) { + return $obj->has_bookkeeping > 0 ? 1 : 0; + } + + return 0; + } + + /** + * Add depreciation line for a mode + * + * @param string $mode Depreciation mode (economic, accelerated_depreciation, ...) + * @param string $ref Ref line + * @param int $depreciation_date Depreciation date + * @param double $depreciation_ht Depreciation amount HT + * @param double $cumulative_depreciation_ht Depreciation cumulative amount HT + * @param string $accountancy_code_debit Accountancy code Debit + * @param string $accountancy_code_credit Accountancy code Credit + * @return int <0 if KO, Id of created line if OK + */ + public function addDepreciationLine($mode, $ref, $depreciation_date, $depreciation_ht, $cumulative_depreciation_ht, $accountancy_code_debit, $accountancy_code_credit) + { + global $langs; + $langs->load('assets'); + + // Clean parameters + $this->id = $this->id > 0 ? $this->id : 0; + $mode = strtolower(trim($mode)); + $ref = trim($ref); + $accountancy_code_debit = trim($accountancy_code_debit); + $accountancy_code_credit = trim($accountancy_code_credit); + + // Check parameters + $error = 0; + if (empty($this->id)) { + $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')'); + $error++; + } + if ($error) { + return -1; + } + + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "asset_depreciation(fk_asset, depreciation_mode, ref, depreciation_date, depreciation_ht, cumulative_depreciation_ht, accountancy_code_debit, accountancy_code_credit)"; + $sql .= " VALUES ( "; + $sql .= " " . (int) $this->id; + $sql .= ", '" . $this->db->escape($mode) . "'"; + $sql .= ", '" . $this->db->escape($ref) . "'"; + $sql .= ", '" . $this->db->idate($depreciation_date) . "'"; + $sql .= ", " . (double) $depreciation_ht; + $sql .= ", " . (double) $cumulative_depreciation_ht; + $sql .= ", '" . $this->db->escape($accountancy_code_debit) . "'"; + $sql .= ", '" . $this->db->escape($accountancy_code_credit) . "'"; + $sql .= ")"; + + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorAddDepreciationLine') . ': ' . $this->db->lasterror(); + return -1; + } + + return 1; + } + + /** + * Calculation depreciation lines (reversal and future) for each mode + * + * @return int <0 if KO, Id of created object if OK + */ + public function calculationDepreciation() + { + global $conf, $langs; + $langs->load('assets'); + + // Clean parameters + $this->id = $this->id > 0 ? $this->id : 0; + + // Check parameters + $error = 0; + if (empty($this->id)) { + $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Asset") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')'); + $error++; + } + if ($error) { + return -1; + } + + // Get depreciation options + //--------------------------- + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php'; + $options = new AssetDepreciationOptions($this->db); + $result = $options->fetchDeprecationOptions($this->id); + if ($result < 0) { + $this->error = $options->error; + $this->errors = $options->errors; + return -1; + } + + // Get accountancy codes + //--------------------------- + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php'; + $accountancy_codes = new AssetAccountancyCodes($this->db); + $result = $accountancy_codes->fetchAccountancyCodes($this->id); + if ($result < 0) { + $this->error = $accountancy_codes->error; + $this->errors = $accountancy_codes->errors; + return -1; + } + + $this->db->begin(); + + // Delete old lines + $modes = array(); + foreach ($options->deprecation_options as $mode_key => $fields) { + $modes[$mode_key] = $this->db->escape($mode_key); + } + $sql = "DELETE FROM " . MAIN_DB_PREFIX . "asset_depreciation"; + $sql .= " WHERE fk_asset = " . (int) $this->id; + $sql .= " AND depreciation_mode NOT IN ('" . $this->db->sanitize(implode("', '", $modes)) . "')"; + + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorClearDepreciationLines') . ': ' . $this->db->lasterror(); + $error++; + } + + if (!$error) { + // Get fiscal period + require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; + $dates = getDefaultDatesForTransfer(); + $init_fiscal_period_start = $dates['date_start']; + $init_fiscal_period_end = $dates['date_end']; + if (empty($init_fiscal_period_start) || empty($init_fiscal_period_end)) { + $pastmonthyear = $dates['pastmonthyear']; + $pastmonth = $dates['pastmonth']; + $init_fiscal_period_start = dol_get_first_day($pastmonthyear, $pastmonth, false); + $init_fiscal_period_end = dol_get_last_day($pastmonthyear, $pastmonth, false); + } + + foreach ($options->deprecation_options as $mode_key => $fields) { + // Get last depreciation lines save in bookkeeping + //----------------------------------------------------- + $sql = "WITH in_accounting_bookkeeping(fk_docdet) AS ("; + $sql .= " SELECT fk_docdet"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping"; + $sql .= " WHERE doc_type = 'asset'"; + $sql .= ")"; + $sql .= "SELECT ad.depreciation_date, ad.cumulative_depreciation_ht"; + $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation AS ad"; + $sql .= " LEFT JOIN in_accounting_bookkeeping as iab ON iab.fk_docdet = ad.rowid"; + $sql .= " WHERE ad.fk_asset = " . (int) $this->id; + $sql .= " AND ad.depreciation_mode = '" . $this->db->escape($mode_key) . "'"; + $sql .= " AND iab.fk_docdet IS NOT NULL"; + $sql .= " ORDER BY ad.depreciation_date DESC"; + $sql .= " LIMIT 1"; + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorFetchMaxDepreciationDateForMode', $mode_key) . ': ' . $this->db->lasterror(); + $error++; + break; + } + $last_depreciation_date = ''; + $last_cumulative_depreciation_ht = $this->reversal_amount_ht; + if ($obj = $this->db->fetch_object($resql)) { + $last_depreciation_date = $this->db->jdate($obj->depreciation_date); + $last_cumulative_depreciation_ht = $obj->cumulative_depreciation_ht; + } + + // Set last cumulative depreciation + $sql = "UPDATE " . MAIN_DB_PREFIX . $options->deprecation_options_fields[$mode_key]['table']; + $sql .= " SET total_amount_last_depreciation_ht = " . (empty($last_cumulative_depreciation_ht) ? 0 : $last_cumulative_depreciation_ht); + $sql .= " WHERE fk_asset = " . (int) $this->id; + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorSetLastCumulativeDepreciation') . ': ' . $this->db->lasterror(); + $error++; + break; + } + + // Delete old lines + $sql = "DELETE " . MAIN_DB_PREFIX . "asset_depreciation FROM " . MAIN_DB_PREFIX . "asset_depreciation"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab ON ab.doc_type = 'asset' AND ab.fk_docdet = " . MAIN_DB_PREFIX . "asset_depreciation.rowid"; + $sql .= " WHERE " . MAIN_DB_PREFIX . "asset_depreciation.fk_asset = " . (int) $this->id; + $sql .= " AND " . MAIN_DB_PREFIX . "asset_depreciation.depreciation_mode = '" . $this->db->escape($mode_key) . "'"; + $sql .= " AND ab.fk_docdet IS NULL"; + if ($last_depreciation_date !== "") $sql .= " AND " . MAIN_DB_PREFIX . "asset_depreciation.ref != ''"; + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorClearDepreciationLines') . ': ' . $this->db->lasterror(); + $error++; + break; + } + + // Get depreciation period + $depreciation_date_start = $this->date_start > $this->date_acquisition ? $this->date_start : $this->date_acquisition; + $depreciation_date_end = dol_time_plus_duree($depreciation_date_start, $fields['duration'], $fields['duration_type'] == 1 ? 'm' : ($fields['duration_type'] == 2 ? 'd' : 'y')); + $depreciation_amount = $fields['amount_base_depreciation_ht']; + if ($fields['duration_type'] == 2) { // Daily + $fiscal_period_start = $depreciation_date_start; + $fiscal_period_end = $depreciation_date_start; + } elseif ($fields['duration_type'] == 1) { // Monthly + $date_temp = dol_getdate($depreciation_date_start); + $fiscal_period_start = dol_get_first_day($date_temp['year'], $date_temp['mon'], false); + $fiscal_period_end = dol_get_last_day($date_temp['year'], $date_temp['mon'], false); + } else { // Annually + $fiscal_period_start = $init_fiscal_period_start; + $fiscal_period_end = $init_fiscal_period_end; + } + $cumulative_depreciation_ht = $last_cumulative_depreciation_ht; + $depreciation_period_amount = $depreciation_amount - $this->reversal_amount_ht; + $start_date = $depreciation_date_start; + $disposal_date = isset($this->disposal_date) && $this->disposal_date !== "" ? $this->disposal_date : ""; + $finish_date = $disposal_date !== "" ? $disposal_date : $depreciation_date_end; + $accountancy_code_depreciation_debit_key = $accountancy_codes->accountancy_codes_fields[$mode_key]['depreciation_debit']; + $accountancy_code_depreciation_debit = $accountancy_codes->accountancy_codes[$mode_key][$accountancy_code_depreciation_debit_key]; + $accountancy_code_depreciation_credit_key = $accountancy_codes->accountancy_codes_fields[$mode_key]['depreciation_credit']; + $accountancy_code_credit = $accountancy_codes->accountancy_codes[$mode_key][$accountancy_code_depreciation_credit_key]; + + // Reversal depreciation line + //----------------------------------------------------- + if ($last_depreciation_date === "" && ($depreciation_date_start < $fiscal_period_start || is_numeric($this->reversal_date))) { + if (is_numeric($this->reversal_date)) { + if ($this->reversal_date < $fiscal_period_start) { + $this->errors[] = $langs->trans('AssetErrorReversalDateNotGreaterThanCurrentBeginFiscalDateForMode', $mode_key); + $error++; + break; + } + + if (empty($this->reversal_amount_ht)) { + $this->errors[] = $langs->trans('AssetErrorReversalAmountNotProvidedForMode', $mode_key); + $error++; + break; + } + + $start_date = $this->reversal_date; + $result = $this->addDepreciationLine($mode_key, '', $start_date, $this->reversal_amount_ht, $this->reversal_amount_ht, $accountancy_code_depreciation_debit, $accountancy_code_credit); + if ($result < 0) { + $error++; + break; + } + } else { + $this->errors[] = $langs->trans('AssetErrorReversalDateNotProvidedForMode', $mode_key); + $error++; + break; + } + } + + // futures depreciation lines + //----------------------------------------------------- + $nb_days_in_year = !empty($conf->global->ASSET_DEPRECIATION_DURATION_PER_YEAR) ? $conf->global->ASSET_DEPRECIATION_DURATION_PER_YEAR : 365; + $nb_days_in_month = !empty($conf->global->ASSET_DEPRECIATION_DURATION_PER_MONTH) ? $conf->global->ASSET_DEPRECIATION_DURATION_PER_MONTH : 30; + $period_amount = (double) price2num($depreciation_period_amount / $fields['duration'], 'MT'); + $first_period_found = false; + $first_period_date = isset($begin_period) && $begin_period > $fiscal_period_start ? $begin_period : $fiscal_period_start; + + $ref_date_format = "%Y" . ($fields['duration_type'] == 1 || $fields['duration_type'] == 2 ? '-%m' : '') . ($fields['duration_type'] == 2 ? '-%d' : ''); + + // Loop security + $idx_loop = 0; + $max_loop = $fields['duration'] + 2; + do { + // Loop security + $idx_loop++; + if ($idx_loop > $max_loop) break; + + if ($last_depreciation_date < $fiscal_period_end && ($first_period_date <= $start_date || $first_period_found)) { + // Disposal not depreciated + if ($fiscal_period_start <= $disposal_date && $disposal_date <= $fiscal_period_end && empty($this->disposal_depreciated)) { + break; + } + + $first_period_found = true; + + $period_begin = dol_print_date($fiscal_period_start, $ref_date_format); + $period_end = dol_print_date($fiscal_period_end, $ref_date_format); + $ref = $period_begin . ($period_begin != $period_end ? ' - ' . $period_end : ''); + if ($fiscal_period_start <= $disposal_date && $disposal_date <= $fiscal_period_end) { + $ref .= ' - ' . $langs->transnoentitiesnoconv('AssetDisposal'); + } + + $begin_date = $fiscal_period_start < $start_date && $start_date <= $fiscal_period_end ? $start_date : $fiscal_period_start; + $end_date = $fiscal_period_start < $finish_date && $finish_date <= $fiscal_period_end ? $finish_date : $fiscal_period_end; + if ($fields['duration_type'] == 2) { // Daily + $depreciation_ht = $period_amount; + } elseif ($fields['duration_type'] == 1) { // Monthly + $nb_days = min($nb_days_in_month, num_between_day($begin_date, $end_date, 1)); + if ($nb_days >= 28) { + $date_temp = dol_getdate($begin_date); + if ($date_temp['mon'] == 2) { + $nb_days = 30; + } + } + $depreciation_ht = (double) price2num($period_amount * $nb_days / $nb_days_in_month, 'MT'); + } else { // Annually + $nb_days = min($nb_days_in_year, num_between_day($begin_date, $end_date, 1)); + $depreciation_ht = (double) price2num($period_amount * $nb_days / $nb_days_in_year, 'MT'); + } + + if ($fiscal_period_start <= $depreciation_date_end && $depreciation_date_end <= $fiscal_period_end) { // last period + $depreciation_ht = (double) price2num($depreciation_amount - $cumulative_depreciation_ht, 'MT'); + $cumulative_depreciation_ht = $depreciation_amount; + } else { + $cumulative_depreciation_ht += $depreciation_ht; + } + + $result = $this->addDepreciationLine($mode_key, $ref, $fiscal_period_end, $depreciation_ht, $cumulative_depreciation_ht, $accountancy_code_depreciation_debit, $accountancy_code_credit); + if ($result < 0) { + $error++; + break; + } + } + + // Next fiscal period (+1 day/month/year) + $fiscal_period_start = dol_time_plus_duree($fiscal_period_end, 1, 'd'); + if ($fields['duration_type'] == 2) { // Daily + $fiscal_period_end = $fiscal_period_start; + } elseif ($fields['duration_type'] == 1) { // Monthly + $fiscal_period_end = dol_time_plus_duree(dol_time_plus_duree($fiscal_period_start, 1, 'm'), -1, 'd'); + } else { // Annually + $fiscal_period_end = dol_time_plus_duree(dol_time_plus_duree($fiscal_period_start, 1, 'y'), -1, 'd'); + } + $last_period_date = $disposal_date !== "" && $disposal_date < $depreciation_date_end ? $disposal_date : $depreciation_date_end; + } while ($fiscal_period_start < $last_period_date); + + if ($error) { + break; + } + } + } + + if ($error) { + $this->db->rollback(); + return -1; + } else { + $this->db->commit(); + return 1; + } + } + + /** + * Set last cumulative depreciation for each mode + * + * @param int $asset_depreciation_id Asset depreciation line ID + * @return int <0 if KO, >0 if OK + */ + public function setLastCumulativeDepreciation($asset_depreciation_id) + { + global $langs; + $langs->load('assets'); + + // Clean parameters + $asset_depreciation_id = $asset_depreciation_id > 0 ? $asset_depreciation_id : 0; + + // Check parameters + $error = 0; + if (empty($asset_depreciation_id)) { + $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("AssetDepreciation") . ' (' . $langs->transnoentitiesnoconv("TechnicalID") . ')'); + $error++; + } + if ($error) { + return -1; + } + + $this->db->begin(); + + require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php'; + $options = new AssetDepreciationOptions($this->db); + + // Get last depreciation lines save in bookkeeping + //----------------------------------------------------- + $sql = "SELECT fk_asset, depreciation_mode, cumulative_depreciation_ht"; + $sql .= " FROM " . MAIN_DB_PREFIX . "asset_depreciation"; + $sql .= " WHERE rowid = " . (int) $asset_depreciation_id; + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorFetchCumulativeDepreciation') . ': ' . $this->db->lasterror(); + $error++; + } else { + if ($obj = $this->db->fetch_object($resql)) { + $mode_key = $obj->depreciation_mode; + if (!empty($options->deprecation_options_fields[$mode_key])) { + $sql = "UPDATE " . MAIN_DB_PREFIX . $options->deprecation_options_fields[$mode_key]['table']; + $sql .= " SET total_amount_last_depreciation_ht = " . $obj->cumulative_depreciation_ht; + $sql .= " WHERE fk_asset = " . (int) $obj->fk_asset; + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorSetLastCumulativeDepreciation') . ': ' . $this->db->lasterror(); + $error++; + } + } + } + } + + if ($error) { + $this->db->rollback(); + return -1; + } else { + $this->db->commit(); + return 1; + } + } + + /** + * Set dispose status + * + * @param User $user Object user that dispose + * @param int $disposal_invoice_id Disposal invoice ID + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, 0=Nothing done, >0 if OK + */ + public function dispose($user, $disposal_invoice_id, $notrigger = 0) + { + global $conf, $langs; + + // Protection + if ($this->status != self::STATUS_DRAFT || $this->status == self::STATUS_DISPOSED) { + return 0; + } + + $this->db->begin(); + + $required_fields = array('disposal_date', 'disposal_date', 'fk_disposal_type'); + foreach ($required_fields as $field) { + $this->fields[$field]['notnull'] = 1; + } + $result = $this->update($user, 1); + foreach ($required_fields as $field) { + $this->fields[$field]['notnull'] = 0; + } + if ($result > 0) { + if ($disposal_invoice_id > 0) $this->add_object_linked('facture', $disposal_invoice_id); + $result = $this->setStatusCommon($user, self::STATUS_DISPOSED, $notrigger, 'ASSET_DISPOSED'); + } + if ($result > 0) $result = $this->calculationDepreciation(); + + if ($result < 0) { + $this->db->rollback(); + } else { + $this->db->commit(); + } + + // Define output language + if ($result > 0 && empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + if (method_exists($this, 'generateDocument')) { + global $hidedetails, $hidedesc, $hideref; + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); + } + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) { + $newlang = $this->thirdparty->default_lang; + } + if (!empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model = $this->model_pdf; + $ret = $this->fetch($this->id); // Reload to get new records + + $this->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + + return $result; + } + + /** + * Set back to validated status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, 0=Nothing done, >0 if OK + */ + public function reopen($user, $notrigger = 0) + { + global $conf, $langs; + + // Protection + if ($this->status != self::STATUS_DISPOSED || $this->status == self::STATUS_DRAFT) { + return 0; + } + + + $this->db->begin(); + + $this->disposal_date = null; + $this->disposal_amount_ht = null; + $this->fk_disposal_type = null; + $this->disposal_depreciated = null; + $this->disposal_subject_to_vat = null; + $result = $this->update($user, 1); + if ($result > 0) { + $this->deleteObjectLinked(null, 'facture'); + $result = $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'ASSET_REOPEN'); + } + if ($result > 0) $result = $this->calculationDepreciation(); + + if ($result < 0) { + $this->db->rollback(); + } else { + $this->db->commit(); + } + + // Define output language + if ($result > 0 && empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + if (method_exists($this, 'generateDocument')) { + global $hidedetails, $hidedesc, $hideref; + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); + } + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) { + $newlang = $this->thirdparty->default_lang; + } + if (!empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model = $this->model_pdf; + $ret = $this->fetch($this->id); // Reload to get new records + + $this->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + + return $result; } /** * Return a link to the object card (with optionaly the picto) * - * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) - * @param string $option On what the link point to ('nolink', ...) - * @param int $notooltip 1=Disable tooltip - * @param string $morecss Add more css on link - * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking - * @return string String with URL + * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) + * @param string $option On what the link point to ('nolink', ...) + * @param int $maxlen Max length of name + * @param int $notooltip 1=Disable tooltip + * @param string $morecss Add more css on link + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string String with URL */ - public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) + public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) { - global $db, $conf, $langs; + global $db, $conf, $langs, $hookmanager; global $dolibarr_main_authentication, $dolibarr_main_demo; global $menumanager; @@ -338,7 +1299,7 @@ class Asset extends CommonObject $linkclose = ''; if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { - $label = $langs->trans("ShowAssets"); + $label = $langs->trans("ShowAsset"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; @@ -347,28 +1308,87 @@ class Asset extends CommonObject $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } - $linkstart = ''; - $linkend = ''; + if ($option == 'nolink') { + $linkend = ''; + } else { + $linkend = ''; + } $result .= $linkstart; - if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + + if (empty($this->showphoto_on_popup)) { + if ($withpicto) { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } + } else { + if ($withpicto) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + list($class, $module) = explode('@', $this->picto); + $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref); + $filearray = dol_dir_list($upload_dir, "files"); + $filename = $filearray[0]['name']; + if (!empty($filename)) { + $pospoint = strpos($filearray[0]['name'], '.'); + + $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint); + if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) { + $result .= '
    No photo
    '; + } else { + $result .= '
    No photo
    '; + } + + $result .= '
    '; + } else { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } + } } + if ($withpicto != 2) { - $result .= $this->ref; + $name = $this->ref; + if ($option == 'label') $name = $this->label; + elseif ($option == 'with_label') $name .= ' - ' . $this->label; + $result .= dol_escape_htmltag($maxlen ? dol_trunc($name, $maxlen) : $name); } + $result .= $linkend; //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } /** - * Retourne le libelle du status d'un user (actif, inactif) + * Return the label of the status * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @return string Label of status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function getLabelStatus($mode = 0) + { + return $this->LibStatut($this->status, $mode); + } + + /** + * Return the label of the status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status */ public function getLibStatut($mode = 0) { @@ -379,43 +1399,43 @@ class Asset extends CommonObject /** * Return the status * - * @param int $status Id status - * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto - * @return string Label of status + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status */ - public static function LibStatut($status, $mode = 0) + public function LibStatut($status, $mode = 0) { // phpcs:enable - global $langs; - - $langs->load("contracts"); - $labelStatus = array(); - $labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Disabled'); - $labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled'); - $labelStatusShort = array(); - $labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Disabled'); - $labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled'); - - $statusType = 'status0'; - if ($status == self::STATUS_VALIDATED) { - $statusType = 'status4'; + if (empty($this->labelStatus) || empty($this->labelStatusShort)) { + global $langs; + //$langs->load("asset@asset"); + $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('AssetInProgress'); + $this->labelStatus[self::STATUS_DISPOSED] = $langs->transnoentitiesnoconv('AssetDisposed'); + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('AssetInProgress'); + $this->labelStatusShort[self::STATUS_DISPOSED] = $langs->transnoentitiesnoconv('AssetDisposed'); } - return dolGetStatus($labelStatus[$status], $labelStatusShort[$status], '', $statusType, $mode); + $statusType = 'status4'; + if ($status == self::STATUS_DISPOSED) { + $statusType = 'status6'; + } + + return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); } /** - * Load info into asset object + * Load the info information in the object * - * @param int $id Id of order + * @param int $id Id of object * @return void */ public function info($id) { - $sql = 'SELECT rowid, date_creation as datec, tms as datem,'; - $sql .= ' fk_user_creat, fk_user_modif'; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; - $sql .= ' WHERE t.rowid = '.((int) $id); + $sql = "SELECT rowid, date_creation as datec, tms as datem,"; + $sql .= " fk_user_creat, fk_user_modif"; + $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t"; + $sql .= " WHERE t.rowid = ".((int) $id); + $result = $this->db->query($sql); if ($result) { if ($this->db->num_rows($result)) { @@ -458,25 +1478,116 @@ class Asset extends CommonObject */ public function initAsSpecimen() { + // Set here init that are not commonf fields + // $this->property1 = ... + // $this->property2 = ... + $this->initAsSpecimenCommon(); } + /** + * Create an array of lines + * + * @return array|int array of lines if OK, <0 if KO + */ + public function getLinesArray() + { + $this->lines = array(); + + return $this->lines; + } /** - * Action executed by scheduler - * CAN BE A CRON TASK + * Returns the reference to the following non used object depending on the active numbering module. * - * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) + * @return string Object free reference */ - public function doScheduledJob() + public function getNextNumRef() { - global $conf, $langs; + global $langs, $conf; + $langs->load("asset@asset"); - $this->output = ''; - $this->error = ''; + if (empty($conf->global->ASSET_ASSET_ADDON)) { + $conf->global->ASSET_ASSET_ADDON = 'mod_asset_standard'; + } - dol_syslog(__METHOD__, LOG_DEBUG); + if (!empty($conf->global->ASSET_ASSET_ADDON)) { + $mybool = false; - return 0; + $file = $conf->global->ASSET_ASSET_ADDON.".php"; + $classname = $conf->global->ASSET_ASSET_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/asset/"); + + // Load file with numbering class (if found) + $mybool |= @include_once $dir.$file; + } + + if ($mybool === false) { + dol_print_error('', "Failed to include file ".$file); + return ''; + } + + if (class_exists($classname)) { + $obj = new $classname(); + $numref = $obj->getNextValue($this); + + if ($numref != '' && $numref != '-1') { + return $numref; + } else { + $this->error = $obj->error; + //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); + return ""; + } + } else { + print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname; + return ""; + } + } else { + print $langs->trans("ErrorNumberingModuleNotSetup", $this->element); + return ""; + } } + + /** + * Create a document onto disk according to template module. + * + * @param string $modele Force template to use ('' to not force) + * @param Translate $outputlangs objet lang a utiliser pour traduction + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @param null|array $moreparams Array to provide more information + * @return int 0 if KO, 1 if OK + */ + // public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) + // { + // global $conf, $langs; + // + // $result = 0; + // $includedocgeneration = 1; + // + // $langs->load("asset@asset"); + // + // if (!dol_strlen($modele)) { + // $modele = 'standard_asset'; + // + // if (!empty($this->model_pdf)) { + // $modele = $this->model_pdf; + // } elseif (!empty($conf->global->ASSET_ADDON_PDF)) { + // $modele = $conf->global->ASSET_ADDON_PDF; + // } + // } + // + // $modelpath = "core/modules/asset/doc/"; + // + // if ($includedocgeneration && !empty($modele)) { + // $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + // } + // + // return $result; + // } } diff --git a/htdocs/asset/class/asset_type.class.php b/htdocs/asset/class/asset_type.class.php deleted file mode 100644 index be8643e3f20..00000000000 --- a/htdocs/asset/class/asset_type.class.php +++ /dev/null @@ -1,445 +0,0 @@ - - * - * 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 . - */ - -/** - * \file htdocs/asset/class/asset_type.class.php - * \ingroup asset - * \brief File of class to manage asset types - */ - -require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; - - -/** - * Class to manage asset type - */ -class AssetType extends CommonObject -{ - /** - * @var string Name of table without prefix where object is stored - */ - public $table_element = 'asset_type'; - - /** - * @var string ID to identify managed object - */ - public $element = 'asset_type'; - - /** - * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png - */ - public $picto = 'asset'; - - /** - * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe - * @var int - */ - public $ismultientitymanaged = 1; - - /** - * @var string Asset type label - */ - public $label; - - /** @var string Accountancy code asset */ - public $accountancy_code_asset; - - /** @var string Accountancy code depreciation asset */ - public $accountancy_code_depreciation_asset; - - /** @var string Accountancy code depreciation expense */ - public $accountancy_code_depreciation_expense; - - /** @var string Public note */ - public $note; - - /** @var array Array of asset */ - public $asset = array(); - - public $fields = array( - 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), - 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>15, 'index'=>1), - 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>20), - 'label' =>array('type'=>'varchar(50)', 'label'=>'Label', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>25, 'showoncombobox'=>1), - 'accountancy_code_asset' =>array('type'=>'varchar(32)', 'label'=>'Accountancy code asset', 'enabled'=>1, 'visible'=>-1, 'position'=>30), - 'accountancy_code_depreciation_asset' =>array('type'=>'varchar(32)', 'label'=>'Accountancy code depreciation asset', 'enabled'=>1, 'visible'=>-1, 'position'=>35), - 'accountancy_code_depreciation_expense' =>array('type'=>'varchar(32)', 'label'=>'Accountancy code depreciation expense', 'enabled'=>1, 'visible'=>-1, 'position'=>40), - 'note' =>array('type'=>'mediumtext', 'label'=>'Note', 'enabled'=>1, 'visible'=>-1, 'position'=>45), - ); - - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - public function __construct($db) - { - $this->db = $db; - } - - - /** - * Fonction qui permet de creer le type d'immobilisation - * - * @param User $user User making creation - * @param int $notrigger 1=do not execute triggers, 0 otherwise - * @return int >0 if OK, < 0 if KO - */ - public function create($user, $notrigger = 0) - { - global $conf; - - $error = 0; - - $this->label = trim($this->label); - $this->accountancy_code_asset = trim($this->accountancy_code_asset); - $this->accountancy_code_depreciation_asset = trim($this->accountancy_code_depreciation_asset); - $this->accountancy_code_depreciation_expense = trim($this->accountancy_code_depreciation_expense); - - $this->db->begin(); - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."asset_type ("; - $sql .= "label"; - $sql .= ", accountancy_code_asset"; - $sql .= ", accountancy_code_depreciation_asset"; - $sql .= ", accountancy_code_depreciation_expense"; - $sql .= ", note"; - $sql .= ", entity"; - $sql .= ") VALUES ("; - $sql .= "'".$this->db->escape($this->label)."'"; - $sql .= ", '".$this->db->escape($this->accountancy_code_asset)."'"; - $sql .= ", '".$this->db->escape($this->accountancy_code_depreciation_asset)."'"; - $sql .= ", '".$this->db->escape($this->accountancy_code_depreciation_expense)."'"; - $sql .= ", '".$this->db->escape($this->note)."'"; - $sql .= ", ".((int) $conf->entity); - $sql .= ")"; - - dol_syslog("Asset_type::create", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."asset_type"); - - $result = $this->update($user, 1); - if ($result < 0) { - $this->db->rollback(); - return -3; - } - - if (!$notrigger) { - // Call trigger - $result = $this->call_trigger('ASSET_TYPE_CREATE', $user); - if ($result < 0) { - $error++; - } - // End call triggers - } - - if (!$error) { - $this->db->commit(); - return $this->id; - } else { - dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR); - $this->db->rollback(); - return -2; - } - } else { - $this->error = $this->db->lasterror(); - $this->db->rollback(); - return -1; - } - } - - /** - * Met a jour en base donnees du type - * - * @param User $user Object user making change - * @param int $notrigger 1=do not execute triggers, 0 otherwise - * @return int >0 if OK, < 0 if KO - */ - public function update($user, $notrigger = 0) - { - global $conf, $hookmanager; - - $error = 0; - - $this->label = trim($this->label); - - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."asset_type "; - $sql .= "SET "; - $sql .= "label = '".$this->db->escape($this->label)."',"; - $sql .= "accountancy_code_asset = '".$this->db->escape($this->accountancy_code_asset)."',"; - $sql .= "accountancy_code_depreciation_asset = '".$this->db->escape($this->accountancy_code_depreciation_asset)."',"; - $sql .= "accountancy_code_depreciation_expense = '".$this->db->escape($this->accountancy_code_depreciation_expense)."',"; - $sql .= "note = '".$this->db->escape($this->note)."'"; - $sql .= " WHERE rowid = ".((int) $this->id); - - $result = $this->db->query($sql); - if ($result) { - $action = 'update'; - - // Actions on extra fields - if (!$error) { - $result = $this->insertExtraFields(); - if ($result < 0) { - $error++; - } - } - - if (!$error && !$notrigger) { - // Call trigger - $result = $this->call_trigger('ASSET_TYPE_MODIFY', $user); - if ($result < 0) { - $error++; - } - // End call triggers - } - - if (!$error) { - $this->db->commit(); - return 1; - } else { - $this->db->rollback(); - dol_syslog(get_class($this)."::update ".$this->error, LOG_ERR); - return -$error; - } - } else { - $this->error = $this->db->lasterror(); - $this->db->rollback(); - return -1; - } - } - - /** - * Fonction qui permet de supprimer le status de l'adherent - * - * @return int >0 if OK, 0 if not found, < 0 if KO - */ - public function delete() - { - global $user; - - $error = 0; - - $sql = "DELETE FROM ".MAIN_DB_PREFIX."asset_type"; - $sql .= " WHERE rowid = ".((int) $this->id); - - $resql = $this->db->query($sql); - if ($resql) { - // Call trigger - $result = $this->call_trigger('ASSET_TYPE_DELETE', $user); - if ($result < 0) { - $error++; $this->db->rollback(); return -2; - } - // End call triggers - - $this->db->commit(); - return 1; - } else { - $this->db->rollback(); - $this->error = $this->db->lasterror(); - return -1; - } - } - - /** - * Fonction qui permet de recuperer le status de l'immobilisation - * - * @param int $rowid Id of member type to load - * @return int <0 if KO, >0 if OK - */ - public function fetch($rowid) - { - $sql = "SELECT d.rowid, d.label as label, d.accountancy_code_asset, d.accountancy_code_depreciation_asset, d.accountancy_code_depreciation_expense, d.note"; - $sql .= " FROM ".MAIN_DB_PREFIX."asset_type as d"; - $sql .= " WHERE d.rowid = ".(int) $rowid; - - dol_syslog("Asset_type::fetch", LOG_DEBUG); - - $resql = $this->db->query($sql); - if ($resql) { - if ($this->db->num_rows($resql)) { - $obj = $this->db->fetch_object($resql); - - $this->id = $obj->rowid; - $this->ref = $obj->rowid; - $this->label = $obj->label; - $this->accountancy_code_asset = $obj->accountancy_code_asset; - $this->accountancy_code_depreciation_asset = $obj->accountancy_code_depreciation_asset; - $this->accountancy_code_depreciation_expense = $obj->accountancy_code_depreciation_expense; - $this->note = $obj->note; - } - - return 1; - } else { - $this->error = $this->db->lasterror(); - return -1; - } - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Return list of asset's type - * - * @return array List of types of members - */ - public function liste_array() - { - // phpcs:enable - global $conf, $langs; - - $assettypes = array(); - - $sql = "SELECT rowid, label as label"; - $sql .= " FROM ".MAIN_DB_PREFIX."asset_type"; - $sql .= " WHERE entity IN (".getEntity('asset_type').")"; - - $resql = $this->db->query($sql); - if ($resql) { - $nump = $this->db->num_rows($resql); - - if ($nump) { - $i = 0; - while ($i < $nump) { - $obj = $this->db->fetch_object($resql); - - $assettypes[$obj->rowid] = $langs->trans($obj->label); - $i++; - } - } - } else { - print $this->db->error(); - } - return $assettypes; - } - - /** - * Return array of Asset objects for asset type this->id (or all if this->id not defined) - * - * @param string $excludefilter Filter string to exclude. This parameter must not be provided by input of users - * @param int $mode 0=Return array of asset instance - * 1=Return array of asset instance without extra data - * 2=Return array of asset id only - * @return mixed Array of asset or -1 on error - */ - public function listAssetForAssetType($excludefilter = '', $mode = 0) - { - global $conf, $user; - - $ret = array(); - - $sql = "SELECT a.rowid"; - $sql .= " FROM ".MAIN_DB_PREFIX."asset as a"; - $sql .= " WHERE a.entity IN (".getEntity('asset').")"; - $sql .= " AND a.fk_asset_type = ".((int) $this->id); - if (!empty($excludefilter)) { - $sql .= ' AND ('.$excludefilter.')'; - } - - dol_syslog(get_class($this)."::listAssetsForGroup", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) { - while ($obj = $this->db->fetch_object($resql)) { - if (!array_key_exists($obj->rowid, $ret)) { - if ($mode < 2) { - $assetstatic = new Asset($this->db); - $assetstatic->fetch($obj->rowid); - $ret[$obj->rowid] = $assetstatic; - } else { - $ret[$obj->rowid] = $obj->rowid; - } - } - } - - $this->db->free($resql); - - $this->asset = $ret; - - return $ret; - } else { - $this->error = $this->db->lasterror(); - return -1; - } - } - - /** - * Return clicable name (with picto eventually) - * - * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto - * @param int $maxlen length max label - * @param int $notooltip 1=Disable tooltip - * @return string String with URL - */ - public function getNomUrl($withpicto = 0, $maxlen = 0, $notooltip = 0) - { - global $langs; - - $result = ''; - $label = $langs->trans("ShowTypeCard", $this->label); - - $linkstart = ''; - $linkend = ''; - - $result .= $linkstart; - if ($withpicto) { - $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); - } - if ($withpicto != 2) { - $result .= ($maxlen ?dol_trunc($this->label, $maxlen) : $this->label); - } - $result .= $linkend; - - return $result; - } - - /** - * Initialise an instance with random values. - * Used to build previews or test instances. - * id must be 0 if object instance is a specimen. - * - * @return void - */ - public function initAsSpecimen() - { - global $conf, $user, $langs; - - // Initialize parameters - $this->id = 0; - $this->ref = 'ATSPEC'; - $this->specimen = 1; - - $this->label = 'ASSET TYPE SPECIMEN'; - $this->note = 'This is a note'; - - // Assets of this asset type is just me - $this->asset = array( - $user->id => $user - ); - } - - /** - * getLibStatut - * - * @return string Return status of a type of asset - */ - public function getLibStatut() - { - return ''; - } -} diff --git a/htdocs/asset/class/assetaccountancycodes.class.php b/htdocs/asset/class/assetaccountancycodes.class.php new file mode 100644 index 00000000000..720dd1e745d --- /dev/null +++ b/htdocs/asset/class/assetaccountancycodes.class.php @@ -0,0 +1,279 @@ + + * + * 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 . + */ + +/** + * \file asset/class/assetaccountancycodes.class.php + * \ingroup asset + * \brief This file is a class file for AssetAccountancyCodes + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; + +/** + * Class for AssetAccountancyCodes + */ +class AssetAccountancyCodes extends CommonObject +{ + /** + * @var array Array with all accountancy codes info by mode. + * Note : 'economic' mode is mandatory and is the primary accountancy codes + * 'depreciation_asset' and 'depreciation_expense' is mandatory and is used for write depreciation in bookkeeping + */ + public $accountancy_codes_fields = array( + 'economic' => array( + 'label' => 'AssetAccountancyCodeDepreciationEconomic', + 'table' => 'asset_accountancy_codes_economic', + 'depreciation_debit' => 'depreciation_asset', + 'depreciation_credit' => 'depreciation_expense', + 'fields' => array( + 'asset' => array('label' => 'AssetAccountancyCodeAsset'), + 'depreciation_asset' => array('label' => 'AssetAccountancyCodeDepreciationAsset'), + 'depreciation_expense' => array('label' => 'AssetAccountancyCodeDepreciationExpense'), + 'value_asset_sold' => array('label' => 'AssetAccountancyCodeValueAssetSold'), + 'receivable_on_assignment' => array('label' => 'AssetAccountancyCodeReceivableOnAssignment'), + 'proceeds_from_sales' => array('label' => 'AssetAccountancyCodeProceedsFromSales'), + 'vat_collected' => array('label' => 'AssetAccountancyCodeVatCollected'), + 'vat_deductible' => array('label' => 'AssetAccountancyCodeVatDeductible'), + ), + ), + 'accelerated_depreciation' => array( + 'label' => 'AssetAccountancyCodeDepreciationAcceleratedDepreciation', + 'table' => 'asset_accountancy_codes_fiscal', + 'depreciation_debit' => 'accelerated_depreciation', + 'depreciation_credit' => 'endowment_accelerated_depreciation', + 'fields' => array( + 'accelerated_depreciation' => array('label' => 'AssetAccountancyCodeAcceleratedDepreciation'), + 'endowment_accelerated_depreciation' => array('label' => 'AssetAccountancyCodeEndowmentAcceleratedDepreciation'), + 'provision_accelerated_depreciation' => array('label' => 'AssetAccountancyCodeProvisionAcceleratedDepreciation'), + ), + ), + ); + + /** + * @var array Array with all accountancy codes by mode. + */ + public $accountancy_codes = array(); + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } + + /** + * Fill accountancy_codes property of object (using for data sent by forms) + * + * @return array Array of values + */ + public function setAccountancyCodesFromPost() + { + $this->accountancy_codes = array(); + foreach ($this->accountancy_codes_fields as $mode_key => $mode_info) { + $this->accountancy_codes[$mode_key] = array(); + foreach ($mode_info['fields'] as $field_key => $field_info) { + $accountancy_code = GETPOST($mode_key . '_' . $field_key, 'aZ09'); + if (empty($accountancy_code) || $accountancy_code == '-1') $accountancy_code = ''; + $this->accountancy_codes[$mode_key][$field_key] = $accountancy_code; + } + } + } + + /** + * Load accountancy codes of a asset or a asset model + * + * @param int $asset_id Asset ID to set + * @param int $asset_model_id Asset model ID to set + * @return int <0 if KO, >0 if OK + */ + public function fetchAccountancyCodes($asset_id = 0, $asset_model_id = 0) + { + global $langs, $hookmanager; + dol_syslog(__METHOD__ . " asset_id=$asset_id, asset_model_id=$asset_model_id"); + + $error = 0; + $this->errors = array(); + $this->accountancy_codes = array(); + + // Clean parameters + $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 + if (!empty($reshook)) { + return $reshook; + } + + // Check parameters + if (empty($asset_id) && empty($asset_model_id)) { + $this->errors[] = $langs->trans('AssetErrorAssetOrAssetModelIDNotProvide'); + $error++; + } + if ($error) { + dol_syslog(__METHOD__ . " Error check parameters: " . $this->errorsToString(), LOG_ERR); + return -1; + } + + $accountancy_codes = array(); + foreach ($this->accountancy_codes_fields as $mode_key => $mode_info) { + $sql = "SELECT " . implode(',', array_keys($mode_info['fields'])); + $sql .= " FROM " . MAIN_DB_PREFIX . $mode_info['table']; + $sql .= " WHERE " . ($asset_id > 0 ? " fk_asset = " . (int) $asset_id : " fk_asset_model = " . (int) $asset_model_id); + + $resql = $this->db->query($sql); + if ($resql) { + if ($obj = $this->db->fetch_object($resql)) { + $accountancy_codes[$mode_key] = array(); + foreach ($mode_info['fields'] as $field_key => $field_info) { + $accountancy_codes[$mode_key][$field_key] = $obj->$field_key; + } + } + } else { + $this->errors[] = $langs->trans('AssetErrorFetchAccountancyCodesForMode', $mode_key) . ': ' . $this->db->lasterror(); + $error++; + } + } + + if ($error) { + dol_syslog(__METHOD__ . " Error fetch accountancy codes: " . $this->errorsToString(), LOG_ERR); + return -1; + } else { + $this->accountancy_codes = $accountancy_codes; + return 1; + } + } + + /** + * Update accountancy codes of a asset or a asset model + * + * @param User $user User making update + * @param int $asset_id Asset ID to set + * @param int $asset_model_id Asset model ID to set + * @param int $notrigger 1=disable trigger UPDATE (when called by create) + * @return int <0 if KO, >0 if OK + */ + public function updateAccountancyCodes($user, $asset_id = 0, $asset_model_id = 0, $notrigger = 0) + { + global $langs, $hookmanager; + dol_syslog(__METHOD__ . " user_id={$user->id}, asset_id=$asset_id, asset_model_id=$asset_model_id, notrigger=$notrigger"); + + $error = 0; + $this->errors = array(); + + // Clean parameters + $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 + if (!empty($reshook)) { + return $reshook; + } + + // Check parameters + if (empty($asset_id) && empty($asset_model_id)) { + $this->errors[] = $langs->trans('AssetErrorAssetOrAssetModelIDNotProvide'); + $error++; + } + if ($error) { + dol_syslog(__METHOD__ . " Error check parameters: " . $this->errorsToString(), LOG_ERR); + return -1; + } + + $this->db->begin(); + $now = dol_now(); + + foreach ($this->accountancy_codes_fields as $mode_key => $mode_info) { + // Delete old accountancy codes + $sql = "DELETE FROM " . MAIN_DB_PREFIX . $mode_info['table']; + $sql .= " WHERE " . ($asset_id > 0 ? " fk_asset = " . (int) $asset_id : " fk_asset_model = " . (int) $asset_model_id); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorDeleteAccountancyCodesForMode', $mode_key) . ': ' . $this->db->lasterror(); + $error++; + } + + if (!$error && !empty($this->accountancy_codes[$mode_key])) { + // Insert accountancy codes + $sql = "INSERT INTO " . MAIN_DB_PREFIX . $mode_info['table'] . "("; + $sql .= $asset_id > 0 ? "fk_asset," : "fk_asset_model,"; + $sql .= implode(',', array_keys($mode_info['fields'])); + $sql .= ", tms, fk_user_modif"; + $sql .= ") VALUES("; + $sql .= $asset_id > 0 ? $asset_id : $asset_model_id; + foreach ($mode_info['fields'] as $field_key => $field_info) { + $sql .= ', ' . (empty($this->accountancy_codes[$mode_key][$field_key]) ? 'NULL' : "'" . $this->db->escape($this->accountancy_codes[$mode_key][$field_key]) . "'"); + } + $sql .= ", '" . $this->db->idate($now) . "'"; + $sql .= ", " . $user->id; + $sql .= ")"; + + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorInsertAccountancyCodesForMode', $mode_key) . ': ' . $this->db->lasterror(); + $error++; + } + } + } + + if (!$error && $asset_id > 0) { + // Calculation of depreciation lines (reversal and future) + require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php'; + $asset = new Asset($this->db); + $result = $asset->fetch($asset_id); + if ($result > 0) $result = $asset->calculationDepreciation(); + if ($result < 0) { + $this->errors[] = $langs->trans('AssetErrorCalculationDepreciationLines'); + $this->errors[] = $asset->errorsToString(); + $error++; + } + } + + if (!$error && !$notrigger) { + // Call trigger + $result = $this->call_trigger('ASSET_ACCOUNTANCY_CODES_MODIFY', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + + if (!$error) { + $this->db->commit(); + return 1; + } else { + $this->db->rollback(); + return -1; + } + } +} diff --git a/htdocs/asset/class/assetdepreciationoptions.class.php b/htdocs/asset/class/assetdepreciationoptions.class.php new file mode 100644 index 00000000000..ce2ddd73c08 --- /dev/null +++ b/htdocs/asset/class/assetdepreciationoptions.class.php @@ -0,0 +1,546 @@ + + * + * 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 . + */ + +/** + * \file asset/class/assetdepreciationoptions.class.php + * \ingroup asset + * \brief This file is a class file for AssetDepreciationOptions + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; + +/** + * Class for AssetDepreciationOptions + */ +class AssetDepreciationOptions extends CommonObject +{ + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = ''; + + /** + * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:Sortfield]]]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', '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)" + * 'label' the translation key. + * 'picto' is code of a picto to show before value in forms + * 'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM) + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 or 2 if field can be used for measure. Field type must be summable like integer or double(24,8). Use 1 in most cases, or 2 if you don't want to see the column total into list (for example for percentage) + * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200' + * 'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click. + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arrayofkeyval' to set a list of values if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar' + * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * 'validate' is 1 if need to validate with $this->validateField() + * 'copytoclipboard' is 1 or 2 to allow to add a picto to copy value into clipboard (1=picto after label, 2=picto after value) + * 'enabled_field' if the mode block or a field is enabled if another field equal a value (="mode_key:field_key:value") + * 'only_on_asset' is 1 if only a field on a asset + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + /** + * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields = array(); + + /** + * @var array Array with all deprecation options info by mode. + * Note : economic mode is mandatory and is the primary options + */ + public $deprecation_options_fields = array( + 'economic' => array( + 'label' => 'AssetDepreciationOptionEconomic', + 'table' => 'asset_depreciation_options_economic', + 'fields' => array( + 'depreciation_type' => array('type'=>'smallint', 'label'=>'AssetDepreciationOptionDepreciationType', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'arrayofkeyval'=>array('0'=>'AssetDepreciationOptionDepreciationTypeLinear', '1'=>'AssetDepreciationOptionDepreciationTypeDegressive', '2'=>'AssetDepreciationOptionDepreciationTypeExceptional'), 'validate'=>'1',), + 'degressive_coefficient' => array('type'=>'double(24,8)', 'label'=>'AssetDepreciationOptionDegressiveRate', 'enabled'=>'1', 'position'=>20, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1','enabled_field' => 'economic:depreciation_type:1'), + 'duration' => array('type'=>'integer', 'label'=>'AssetDepreciationOptionDuration', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1',), + 'duration_type' => array('type'=>'smallint', 'label'=>'AssetDepreciationOptionDurationType', 'enabled'=>'1', 'position'=>40, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'arrayofkeyval'=>array('0'=>'AssetDepreciationOptionDurationTypeAnnual', '1'=>'AssetDepreciationOptionDurationTypeMonthly'/*, '2'=>'AssetDepreciationOptionDurationTypeDaily'*/), 'validate'=>'1',), + 'rate' => array('type'=>'double(24,8)', 'label'=>'AssetDepreciationOptionRate', 'enabled'=>'1', 'position'=>50, 'visible'=>3, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1', 'computed' => '$object->asset_depreciation_options->getRate("economic")',), + 'accelerated_depreciation_option' => array('type'=>'boolean', 'label'=>'AssetDepreciationOptionAcceleratedDepreciation', 'enabled'=>'1', 'position'=>60, 'column_break' => true, 'notnull'=>0, 'default'=>'0', 'visible'=>1, 'validate'=>'1',), + 'amount_base_depreciation_ht' => array('type'=>'price', 'label'=>'AssetDepreciationOptionAmountBaseDepreciationHT', 'enabled'=>'isset($object)&&get_class($object)=="Asset"', 'only_on_asset'=>1, 'position'=>90, 'notnull'=>0, 'required'=>1, 'visible'=>1, 'default'=>'$object->reversal_amount_ht > 0 ? $object->reversal_amount_ht : $object->acquisition_value_ht', 'isameasure'=>'1', 'validate'=>'1',), + 'amount_base_deductible_ht' => array('type'=>'price', 'label'=>'AssetDepreciationOptionAmountBaseDeductibleHT', 'enabled'=>'isset($object)&&get_class($object)=="Asset"', 'only_on_asset'=>1, 'position'=>100, 'notnull'=>0, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1',), + 'total_amount_last_depreciation_ht' => array('type'=>'price', 'label'=>'AssetDepreciationOptionTotalAmountLastDepreciationHT', 'enabled'=>'isset($object)&&get_class($object)=="Asset"', 'only_on_asset'=>1, 'position'=>110, 'noteditable'=> 1, 'notnull'=>0, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1',), + ), + ), + 'accelerated_depreciation' => array( + 'label' => 'AssetDepreciationOptionAcceleratedDepreciation', + 'table' => 'asset_depreciation_options_fiscal', + 'enabled_field' => 'economic:accelerated_depreciation_option:1', + 'fields' => array( + 'depreciation_type' => array('type'=>'smallint', 'label'=>'AssetDepreciationOptionDepreciationType', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'arrayofkeyval'=>array('0'=>'AssetDepreciationOptionDepreciationTypeLinear', '1'=>'AssetDepreciationOptionDepreciationTypeDegressive', '2'=>'AssetDepreciationOptionDepreciationTypeExceptional'), 'validate'=>'1',), + 'degressive_coefficient' => array('type'=>'double(24,8)', 'label'=>'AssetDepreciationOptionDegressiveRate', 'enabled'=>'1', 'position'=>20, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1','enabled_field' => 'accelerated_depreciation:depreciation_type:1'), + 'duration' => array('type'=>'integer', 'label'=>'AssetDepreciationOptionDuration', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1',), + 'duration_type' => array('type'=>'smallint', 'label'=>'AssetDepreciationOptionDurationType', 'enabled'=>'1', 'position'=>40, 'notnull'=>1, 'visible'=>1, 'default'=>'0', 'arrayofkeyval'=>array('0'=>'AssetDepreciationOptionDurationTypeAnnual', '1'=>'AssetDepreciationOptionDurationTypeMonthly'/*, '2'=>'AssetDepreciationOptionDurationTypeDaily'*/), 'validate'=>'1',), + 'rate' => array('type'=>'double(24,8)', 'label'=>'AssetDepreciationOptionRate', 'enabled'=>'1', 'position'=>50, 'visible'=>3, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1', 'computed' => '$object->asset_depreciation_options->getRate("accelerated_depreciation")',), + 'amount_base_depreciation_ht' => array('type'=>'price', 'label'=>'AssetDepreciationOptionAmountBaseDepreciationHT', 'enabled'=>'isset($object)&&get_class($object)=="Asset"', 'only_on_asset'=>1, 'position'=>80, 'column_break' => true, 'notnull'=>0, 'required'=>1, 'visible'=>1, 'default'=>'$object->reversal_amount_ht > 0 ? $object->reversal_amount_ht : $object->acquisition_value_ht', 'isameasure'=>'1', 'validate'=>'1',), + 'amount_base_deductible_ht' => array('type'=>'price', 'label'=>'AssetDepreciationOptionAmountBaseDeductibleHT', 'enabled'=>'isset($object)&&get_class($object)=="Asset"', 'only_on_asset'=>1, 'position'=>90, 'notnull'=>0, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1',), + 'total_amount_last_depreciation_ht' => array('type'=>'price', 'label'=>'AssetDepreciationOptionTotalAmountLastDepreciationHT', 'enabled'=>'isset($object)&&get_class($object)=="Asset"', 'only_on_asset'=>1, 'position'=>100, 'noteditable'=> 1, 'notnull'=>0, 'visible'=>1, 'default'=>'0', 'isameasure'=>'1', 'validate'=>'1',), + ), + ), + ); + public $fk_asset; + public $fk_asset_model; + public $tms; + public $fk_user_modif; + + /** + * @var array Array with all deprecation options by mode. + */ + public $deprecation_options = array(); + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + global $langs; + $this->db = $db; + + // Translate some data of arrayofkeyval + if (is_object($langs)) { + foreach ($this->deprecation_options_fields as $mode_key => $mode_info) { + if (!empty($mode_info['fields']) && is_array($mode_info['fields'])) { + foreach ($mode_info['fields'] as $field_key => $field_info) { + if (!empty($field_info['arrayofkeyval']) && is_array($field_info['arrayofkeyval'])) { + foreach ($field_info['arrayofkeyval'] as $key => $val) { + $this->deprecation_options_fields[$mode_key]['fields'][$field_key]['arrayofkeyval'][$key] = $langs->trans($val); + } + } + } + } + } + } + } + + /** + * Set object infos for a mode + * + * @param string $mode Depreciation mode (economic, accelerated_depreciation, ...) + * @param int $class_type Type (0:asset, 1:asset model) + * @param bool $all_field Get all fields + * @return int <0 if KO, >0 if OK + */ + public function setInfosForMode($mode, $class_type = 0, $all_field = false) + { + // Clean parameters + $mode = strtolower(trim($mode)); + + if (!empty($this->deprecation_options_fields[$mode])) { + $this->table_element = $this->deprecation_options_fields[$mode]['table']; + $this->fields = $this->deprecation_options_fields[$mode]['fields']; + foreach ($this->fields as $field_key => $field_info) { + if ((!empty($field_info['computed']) && !$all_field) || (!empty($field_info['only_on_asset']) && !empty($class_type))) { + unset($this->fields[$field_key]); + continue; + } + + // Unset required option (notnull) if field disabled + if (!empty($mode_info['enabled_field'])) { + $info = explode(':', $mode_info['enabled_field']); + if ($this->deprecation_options[$info[0]][$info[1]] != $info[2] && isset($this->fields[$field_key]['notnull'])) { + unset($this->fields[$field_key]['notnull']); + } + } + // Set value of the field in the object (for createCommon and setDeprecationOptionsFromPost functions) + $this->{$field_key} = $this->deprecation_options[$mode][$field_key]; + } + + $this->fields['rowid'] = array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"); + if (empty($class_type)) { + $this->fields['fk_asset'] = array('type' => 'integer:Asset:asset/class/asset.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label' => 'Asset', 'enabled' => '1', 'position' => 0, 'notnull' => 0, 'visible' => 0, 'index' => 1, 'validate' => '1',); + } else { + $this->fields['fk_asset_model'] = array('type' => 'integer:AssetModel:asset/class/assetmodel.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label' => 'AssetModel', 'enabled' => '1', 'position' => 0, 'notnull' => 0, 'visible' => 0, 'index' => 1, 'validate' => '1',); + } + $this->fields['tms'] = array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => '1', 'position' => 501, 'notnull' => 0, 'visible' => 0,); + $this->fields['fk_user_modif'] = array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => '1', 'position' => 511, 'notnull' => -1, 'visible' => 0,); + } + + return 1; + } + + /** + * Fill deprecation_options property of object (using for data sent by forms) + * + * @param int $class_type Type (0:asset, 1:asset model) + * @return int <0 if KO, >0 if OK + */ + public function setDeprecationOptionsFromPost($class_type = 0) + { + global $conf, $langs; + + $error = 0; + + $deprecation_options = array(); + foreach ($this->deprecation_options_fields as $mode_key => $mode_info) { + $this->setInfosForMode($mode_key, $class_type); + + foreach ($mode_info['fields'] as $field_key => $field_info) { + if (!empty($field_info['computed'])) { + continue; + } + + $html_name = $mode_key . '_' . $field_key; + if ($field_info['type'] == 'duration') { + if (GETPOST($html_name . 'hour') == '' && GETPOST($html_name . 'min') == '') { + continue; // The field was not submited to be saved + } + } else { + if (!GETPOSTISSET($html_name)) { + continue; // The field was not submited to be saved + } + } + // Ignore special fields + if (in_array($field_key, array('rowid', 'entity', 'import_key'))) { + continue; + } + if (in_array($field_key, array('date_creation', 'tms', 'fk_user_creat', 'fk_user_modif'))) { + if (!in_array(abs($field_info['visible']), array(1, 3))) { + continue; // Only 1 and 3 that are case to create + } + } + + // Set value to insert + if (in_array($field_info['type'], array('text', 'html'))) { + $value = GETPOST($html_name, 'restricthtml'); + } elseif ($field_info['type'] == 'date') { + $value = dol_mktime(12, 0, 0, GETPOST($html_name . 'month', 'int'), GETPOST($html_name . 'day', 'int'), GETPOST($html_name . 'year', 'int')); // for date without hour, we use gmt + } elseif ($field_info['type'] == 'datetime') { + $value = dol_mktime(GETPOST($html_name . 'hour', 'int'), GETPOST($html_name . 'min', 'int'), GETPOST($html_name . 'sec', 'int'), GETPOST($html_name . 'month', 'int'), GETPOST($html_name . 'day', 'int'), GETPOST($html_name . 'year', 'int'), 'tzuserrel'); + } elseif ($field_info['type'] == 'duration') { + $value = 60 * 60 * GETPOST($html_name . 'hour', 'int') + 60 * GETPOST($html_name . 'min', 'int'); + } elseif (preg_match('/^(integer|price|real|double)/', $field_info['type'])) { + $value = price2num(GETPOST($html_name, 'alphanohtml')); // To fix decimal separator according to lang setup + } elseif ($field_info['type'] == 'boolean') { + $value = ((GETPOST($html_name) == '1' || GETPOST($html_name) == 'on') ? 1 : 0); + } elseif ($field_info['type'] == 'reference') { + // todo to check + $tmparraykey = array(); //array_keys($object->param_list); + $value = $tmparraykey[GETPOST($html_name)] . ',' . GETPOST($html_name . '2'); + } else { + if ($field_key == 'lang') { + $value = GETPOST($html_name, 'aZ09') ? GETPOST($html_name, 'aZ09') : ""; + } else { + $value = GETPOST($html_name, 'alphanohtml'); + } + } + if (preg_match('/^integer:/i', $field_info['type']) && $value == '-1') { + $value = ''; // This is an implicit foreign key field + } + if (!empty($field_info['foreignkey']) && $value == '-1') { + $value = ''; // This is an explicit foreign key field + } + + //var_dump($field_key.' '.$value.' '.$field_info['type']); + $field_value = $value; + if ($field_info['notnull'] > 0 && $field_value == '' && !is_null($field_info['default']) && $field_info['default'] == '(PROV)') { + $field_value = '(PROV)'; + } elseif ((!empty($field_info['required']) || $field_info['notnull'] > 0) && $field_value == '' && !empty($field_info['default'])) { + $field_value = dol_eval($field_info['default'], 1); + } + if ($field_info['notnull'] > 0 && $field_value == '' && is_null($field_info['default'])) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv($field_info['label'])), null, 'errors'); + } + $deprecation_options[$mode_key][$field_key] = $field_value; + + // Validation of fields values + if ($conf->global->MAIN_FEATURE_LEVEL >= 2 || !empty($conf->global->MAIN_ACTIVATE_VALIDATION_RESULT)) { + if (!$error && !empty($field_info['validate']) && is_callable(array($this, 'validateField'))) { + if (!$this->validateField($mode_info['fields'], $field_key, $value)) { + $error++; + } + } + } + } + } + // Unset not enabled modes + foreach ($this->deprecation_options_fields as $mode_key => $mode_info) { + if (!empty($mode_info['enabled_field'])) { + $info = explode(':', $mode_info['enabled_field']); + if ($deprecation_options[$info[0]][$info[1]] != $info[2]) { + unset($deprecation_options[$info[0]][$info[1]]); + } + } + } + $this->deprecation_options = $deprecation_options; + + if ($error) { + return -1; + } else { + return 1; + } + } + + /** + * Load deprecation options of a asset or a asset model + * + * @param int $asset_id Asset ID to set + * @param int $asset_model_id Asset model ID to set + * @return int <0 if KO, >0 if OK + */ + public function fetchDeprecationOptions($asset_id = 0, $asset_model_id = 0) + { + global $langs, $hookmanager; + dol_syslog(__METHOD__ . " asset_id=$asset_id, asset_model_id=$asset_model_id"); + + $error = 0; + $this->errors = array(); + $this->deprecation_options = array(); + + // Clean parameters + $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 + if (!empty($reshook)) { + return $reshook; + } + + // Check parameters + if (empty($asset_id) && empty($asset_model_id)) { + $this->errors[] = $langs->trans('AssetErrorAssetOrAssetModelIDNotProvide'); + $error++; + } + if ($error) { + dol_syslog(__METHOD__ . " Error check parameters: " . $this->errorsToString(), LOG_ERR); + return -1; + } + + $class_type = $asset_id > 0 ? 0 : 1; + $deprecation_options = array(); + foreach ($this->deprecation_options_fields as $mode_key => $mode_info) { + $this->setInfosForMode($mode_key, $class_type); + + $result = $this->fetchCommon(0, '', " AND " . ($asset_id > 0 ? " fk_asset = " . (int) $asset_id : " fk_asset_model = " . (int) $asset_model_id)); + if ($result < 0) { + $this->errors = array_merge(array($langs->trans('AssetErrorFetchDepreciationOptionsForMode', $mode_key) . ':'), $this->errors); + $error++; + } elseif ($result > 0) { + foreach ($this->fields as $field_key => $field_info) { + if (in_array($field_key, array('rowid', 'fk_asset', 'fk_asset_model', 'tms', 'fk_user_modif'))) continue; + $deprecation_options[$mode_key][$field_key] = $this->{$field_key}; + } + } + } + // Unset not enabled modes + foreach ($this->deprecation_options_fields as $mode_key => $mode_info) { + if (!empty($mode_info['enabled_field'])) { + $info = explode(':', $mode_info['enabled_field']); + if ($deprecation_options[$info[0]][$info[1]] != $info[2]) { + unset($deprecation_options[$info[0]][$info[1]]); + } + } + } + + if ($error) { + dol_syslog(__METHOD__ . " Error fetch accountancy codes: " . $this->errorsToString(), LOG_ERR); + return -1; + } else { + $this->deprecation_options = $deprecation_options; + return 1; + } + } + + /** + * get general depreciation info for a mode (used in depreciation card) + * + * @param string $mode Depreciation mode (economic, accelerated_depreciation, ...) + * @return array|int <0 if KO otherwise array with general depreciation info + */ + public function getGeneralDepreciationInfoForMode($mode) + { + global $hookmanager; + dol_syslog(__METHOD__ . " mode=$mode"); + + $this->errors = array(); + + // 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 + if ($reshook < 0) { + return $reshook; + } elseif ($reshook > 0) { + return $hookmanager->resArray; + } + + $duration_type_list = $this->deprecation_options_fields[$mode]['fields']['duration_type']['arrayofkeyval']; + + return array( + 'base_depreciation_ht' => $this->deprecation_options[$mode]['amount_base_depreciation_ht'], + 'duration' => $this->deprecation_options[$mode]['duration'], + 'duration_type' => $duration_type_list[$this->deprecation_options[$mode]['duration_type']], + 'rate' => $this->getRate($mode), + ); + } + + /** + * Update deprecation options of a asset or a asset model + * + * @param User $user User making update + * @param int $asset_id Asset ID to set + * @param int $asset_model_id Asset model ID to set + * @param int $notrigger 1=disable trigger UPDATE (when called by create) + * @return int <0 if KO, >0 if OK + */ + public function updateDeprecationOptions($user, $asset_id = 0, $asset_model_id = 0, $notrigger = 0) + { + global $langs, $hookmanager; + dol_syslog(__METHOD__ . " user_id={$user->id}, asset_id=$asset_id, asset_model_id=$asset_model_id, notrigger=$notrigger"); + + $error = 0; + $this->errors = array(); + + // Clean parameters + $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 + if (!empty($reshook)) { + return $reshook; + } + + // Check parameters + if (empty($asset_id) && empty($asset_model_id)) { + $this->errors[] = $langs->trans('AssetErrorAssetOrAssetModelIDNotProvide'); + $error++; + } + if ($error) { + dol_syslog(__METHOD__ . " Error check parameters: " . $this->errorsToString(), LOG_ERR); + return -1; + } + + $this->db->begin(); + + if ($asset_id > 0) { + $this->fk_asset = $asset_id; + $class_type = 0; + } else { + $this->fk_asset_model = $asset_model_id; + $class_type = 1; + } + $this->tms = dol_now(); + $this->fk_user_modif = $user->id; + + foreach ($this->deprecation_options_fields as $mode_key => $mode_info) { + // Delete old accountancy codes + $sql = "DELETE FROM " . MAIN_DB_PREFIX . $mode_info['table']; + $sql .= " WHERE " . ($asset_id > 0 ? " fk_asset = " . (int) $asset_id : " fk_asset_model = " . (int) $asset_model_id); + $resql = $this->db->query($sql); + if (!$resql) { + $this->errors[] = $langs->trans('AssetErrorDeleteDepreciationOptionsForMode', $mode_key) . ': ' . $this->db->lasterror(); + $error++; + } + + if (!$error && !empty($this->deprecation_options[$mode_key])) { + if (!empty($mode_info['enabled_field'])) { + $info = explode(':', $mode_info['enabled_field']); + if ($this->deprecation_options[$info[0]][$info[1]] != $info[2]) { + continue; + } + } + + $this->setInfosForMode($mode_key, $class_type); + + $result = $this->createCommon($user, 1); + if ($result < 0) { + $this->errors = array_merge(array($langs->trans('AssetErrorInsertDepreciationOptionsForMode', $mode_key) . ':'), $this->errors); + $error++; + } + } + } + + if (!$error && $this->fk_asset > 0) { + // Calculation of depreciation lines (reversal and future) + require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php'; + $asset = new Asset($this->db); + $result = $asset->fetch($this->fk_asset); + if ($result > 0) $result = $asset->calculationDepreciation(); + if ($result < 0) { + $this->errors[] = $langs->trans('AssetErrorCalculationDepreciationLines'); + $this->errors[] = $asset->errorsToString(); + $error++; + } + } + + if (!$error && !$notrigger) { + // Call trigger + $result = $this->call_trigger('ASSET_DEPRECIATION_OPTIONS_MODIFY', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + + if ($error) { + $this->db->rollback(); + return -1; + } else { + $this->db->commit(); + return 1; + } + } + + /** + * Get rate + * + * @param string $mode Depreciation mode (economic, accelerated_depreciation, ...) + * @return string Rate of the provided mode option + */ + public function getRate($mode) + { + $duration = $this->deprecation_options[$mode]["duration"] > 0 ? $this->deprecation_options[$mode]["duration"] : 0; + $duration_type = $this->deprecation_options[$mode]["duration_type"] > 0 ? $this->deprecation_options[$mode]["duration_type"] : 0; + + return price(price2num($duration > 0 ? (100 * ($duration_type == 1 ? 12 : 1) / $duration) : 0, 2)); + } +} diff --git a/htdocs/asset/class/assetmodel.class.php b/htdocs/asset/class/assetmodel.class.php new file mode 100644 index 00000000000..077f33936e8 --- /dev/null +++ b/htdocs/asset/class/assetmodel.class.php @@ -0,0 +1,822 @@ + + * Copyright (C) 2021 Open-Dsi + * + * 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 . + */ + +/** + * \file class/assetmodel.class.php + * \ingroup asset + * \brief This file is a CRUD class file for AssetModel (Create/Read/Update/Delete) + */ + +// Put here all includes required by your class file +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + +/** + * Class for AssetModel + */ +class AssetModel extends CommonObject +{ + /** + * @var string ID of module. + */ + public $module = 'asset'; + + /** + * @var string ID to identify managed object. + */ + public $element = 'assetmodel'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'asset_model'; + + /** + * @var int Does this object support multicompany module ? + * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table + */ + public $ismultientitymanaged = 1; + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 1; + + /** + * @var string String with name of icon for assetmodel. Must be the part after the 'object_' into object_assetmodel.png + */ + public $picto = 'asset'; + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_CANCELED = 9; + + + /** + * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:Sortfield]]]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', '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)" + * 'label' the translation key. + * 'picto' is code of a picto to show before value in forms + * 'enabled' is a condition when the field must be managed (Example: 1 or '$conf->global->MY_SETUP_PARAM) + * 'position' is the sort order of field. + * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). + * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) + * 'noteditable' says if field is not editable (1 or 0) + * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. + * 'index' if we want an index in database. + * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). + * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. + * 'isameasure' must be set to 1 or 2 if field can be used for measure. Field type must be summable like integer or double(24,8). Use 1 in most cases, or 2 if you don't want to see the column total into list (for example for percentage) + * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200' + * 'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click. + * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record + * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. + * 'arrayofkeyval' to set a list of values if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel"). Note that type can be 'integer' or 'varchar' + * 'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1. + * 'comment' is not used. You can store here any text of your choice. It is not used by application. + * 'validate' is 1 if need to validate with $this->validateField() + * 'copytoclipboard' is 1 or 2 to allow to add a picto to copy value into clipboard (1=picto after label, 2=picto after value) + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + /** + * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields=array( + 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), + 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>20, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'validate'=>'1'), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'showoncombobox'=>'2', 'validate'=>'1',), + 'asset_type' => array('type'=>'smallint', 'label'=>'AssetType', 'enabled'=>'1', 'position'=>40, 'notnull'=>1, 'visible'=>1, 'arrayofkeyval'=>array('0'=>'AssetTypeIntangible', '1'=>'AssetTypeTangible', '2'=>'AssetTypeInProgress', '3'=>'AssetTypeFinancial'), 'validate'=>'1',), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>300, 'notnull'=>0, 'visible'=>0, 'validate'=>'1',), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>301, 'notnull'=>0, 'visible'=>0, 'validate'=>'1',), + 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,), + 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,), + 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'foreignkey'=>'user.rowid',), + 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), + 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,), + 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'default'=>'0', 'visible'=>2, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Enabled', '9'=>'Disabled'), 'validate'=>'1',), + ); + public $rowid; + public $ref; + public $label; + public $asset_type; + public $note_public; + public $note_private; + public $date_creation; + public $tms; + public $fk_user_creat; + public $fk_user_modif; + public $last_main_doc; + public $import_key; + public $model_pdf; + public $status; + public $asset_depreciation_options; + + // /** + // * @var string Field with ID of parent key if this object has a parent + // */ + // public $fk_element = 'fk_assetmodel'; + // /** + // * @var array List of child tables. To test if we can delete object. + // */ + // protected $childtables = array(); + // /** + // * @var array List of child tables. To know object to delete on cascade. + // * If name matches '@ClassNAme:FilePathClass;ParentFkFieldName' it will + // * call method deleteByParentField(parentId, ParentFkFieldName) to fetch and delete child object + // */ + // protected $childtablesoncascade = array('asset_assetmodeldet'); + + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + global $conf, $langs; + + $this->db = $db; + + if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) { + $this->fields['rowid']['visible'] = 0; + } + if (empty($conf->multicompany->enabled) && isset($this->fields['entity'])) { + $this->fields['entity']['enabled'] = 0; + } + + // Unset fields that are disabled + foreach ($this->fields as $key => $val) { + if (isset($val['enabled']) && empty($val['enabled'])) { + unset($this->fields[$key]); + } + } + + // Translate some data of arrayofkeyval + if (is_object($langs)) { + foreach ($this->fields as $key => $val) { + if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { + foreach ($val['arrayofkeyval'] as $key2 => $val2) { + $this->fields[$key]['arrayofkeyval'][$key2] = $langs->trans($val2); + } + } + } + } + } + + /** + * Create object into database + * + * @param User $user User that creates + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, Id of created object if OK + */ + public function create(User $user, $notrigger = false) + { + $resultcreate = $this->createCommon($user, $notrigger); + + return $resultcreate; + } + + /** + * Clone an object into another one + * + * @param User $user User that creates + * @param int $fromid Id of object to clone + * @return mixed New object created, <0 if KO + */ + public function createFromClone(User $user, $fromid) + { + global $langs, $extrafields; + $error = 0; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $object = new self($this->db); + + $this->db->begin(); + + // Load source object + $result = $object->fetchCommon($fromid); + if ($result > 0 && !empty($object->table_element_line)) { + $object->fetchLines(); + } + + // get lines so they will be clone + //foreach($this->lines as $line) + // $line->fetch_optionals(); + + // Reset some properties + unset($object->id); + unset($object->fk_user_creat); + unset($object->import_key); + + // Clear fields + if (property_exists($object, 'ref')) { + $object->ref = empty($this->fields['ref']['default']) ? "Copy_Of_".$object->ref : $this->fields['ref']['default']; + } + if (property_exists($object, 'label')) { + $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default']; + } + if (property_exists($object, 'status')) { + $object->status = self::STATUS_DRAFT; + } + if (property_exists($object, 'date_creation')) { + $object->date_creation = dol_now(); + } + if (property_exists($object, 'date_modification')) { + $object->date_modification = null; + } + // ... + // Clear extrafields that are unique + if (is_array($object->array_options) && count($object->array_options) > 0) { + $extrafields->fetch_name_optionals_label($this->table_element); + foreach ($object->array_options as $key => $option) { + $shortkey = preg_replace('/options_/', '', $key); + if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) { + //var_dump($key); var_dump($clonedObj->array_options[$key]); exit; + unset($object->array_options[$key]); + } + } + } + + // Create clone + $object->context['createfromclone'] = 'createfromclone'; + $result = $object->createCommon($user); + if ($result < 0) { + $error++; + $this->error = $object->error; + $this->errors = $object->errors; + } + + if (!$error) { + // copy internal contacts + if ($this->copy_linked_contact($object, 'internal') < 0) { + $error++; + } + } + + if (!$error) { + // copy external contacts if same company + if (property_exists($this, 'fk_soc') && $this->fk_soc == $object->socid) { + if ($this->copy_linked_contact($object, 'external') < 0) { + $error++; + } + } + } + + unset($object->context['createfromclone']); + + // End + if (!$error) { + $this->db->commit(); + return $object; + } else { + $this->db->rollback(); + return -1; + } + } + + /** + * Load object in memory from the database + * + * @param int $id Id object + * @param string $ref Ref + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetch($id, $ref = null) + { + $result = $this->fetchCommon($id, $ref); + if ($result > 0 && !empty($this->table_element_line)) { + $this->fetchLines(); + } + return $result; + } + + /** + * Load object lines in memory from the database + * + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetchLines() + { + $this->lines = array(); + + return 1; + } + + + /** + * Load list of objects in memory from the database. + * + * @param string $sortorder Sort Order + * @param string $sortfield Sort field + * @param int $limit limit + * @param int $offset Offset + * @param array $filter Filter array. Example array('field'=>'valueforlike', 'customurl'=>...) + * @param string $filtermode Filter mode (AND or OR) + * @return array|int int <0 if KO, array of pages if OK + */ + public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') + { + global $conf; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $records = array(); + + $sql = "SELECT "; + $sql .= $this->getFieldList('t'); + $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t"; + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) { + $sql .= " WHERE t.entity IN (".getEntity($this->table_element).")"; + } else { + $sql .= " WHERE 1 = 1"; + } + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + if ($key == 't.rowid') { + $sqlwhere[] = $key." = ".((int) $value); + } elseif (in_array($this->fields[$key]['type'], array('date', 'datetime', 'timestamp'))) { + $sqlwhere[] = $key." = '".$this->db->idate($value)."'"; + } elseif ($key == 'customsql') { + $sqlwhere[] = $value; + } elseif (strpos($value, '%') === false) { + $sqlwhere[] = $key." IN (".$this->db->sanitize($this->db->escape($value)).")"; + } else { + $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'"; + } + } + } + if (count($sqlwhere) > 0) { + $sql .= " AND (".implode(" ".$filtermode." ", $sqlwhere).")"; + } + + if (!empty($sortfield)) { + $sql .= $this->db->order($sortfield, $sortorder); + } + if (!empty($limit)) { + $sql .= $this->db->plimit($limit, $offset); + } + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < ($limit ? min($limit, $num) : $num)) { + $obj = $this->db->fetch_object($resql); + + $record = new self($this->db); + $record->setVarsFromFetchObj($obj); + + $records[$record->id] = $record; + + $i++; + } + $this->db->free($resql); + + return $records; + } else { + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.join(',', $this->errors), LOG_ERR); + + return -1; + } + } + + /** + * Update object into database + * + * @param User $user User that modifies + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, >0 if OK + */ + public function update(User $user, $notrigger = false) + { + return $this->updateCommon($user, $notrigger); + } + + /** + * Delete object in database + * + * @param User $user User that deletes + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int <0 if KO, >0 if OK + */ + public function delete(User $user, $notrigger = false) + { + return $this->deleteCommon($user, $notrigger); + //return $this->deleteCommon($user, $notrigger, 1); + } + + + /** + * Validate object + * + * @param User $user User making status change + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * @return int <=0 if OK, 0=Nothing done, >0 if KO + */ + public function validate($user, $notrigger = 0) + { + global $conf, $langs; + + $error = 0; + + // Protection + if ($this->status == self::STATUS_VALIDATED) { + dol_syslog(get_class($this) . "::validate action abandonned: already validated", LOG_WARNING); + return 0; + } + + $now = dol_now(); + + $this->db->begin(); + + // Validate + $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element; + $sql .= " SET status = " . self::STATUS_VALIDATED; + if (!empty($this->fields['date_validation'])) { + $sql .= ", date_validation = '" . $this->db->idate($now) . "'"; + } + if (!empty($this->fields['fk_user_valid'])) { + $sql .= ", fk_user_valid = " . ((int) $user->id); + } + $sql .= " WHERE rowid = " . ((int) $this->id); + + dol_syslog(get_class($this) . "::validate()", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + dol_print_error($this->db); + $this->error = $this->db->lasterror(); + $error++; + } + + if (!$error && !$notrigger) { + // Call trigger + $result = $this->call_trigger('ASSETMODEL_VALIDATE', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + + // Set new ref and current status + if (!$error) { + $this->status = self::STATUS_VALIDATED; + } + + if (!$error) { + $this->db->commit(); + return 1; + } else { + $this->db->rollback(); + return -1; + } + } + + + /** + * Set draft status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, >0 if OK + */ + public function setDraft($user, $notrigger = 0) + { + // Protection + if ($this->status <= self::STATUS_DRAFT) { + return 0; + } + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'ASSETMODEL_UNVALIDATE'); + } + + /** + * Set cancel status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, 0=Nothing done, >0 if OK + */ + public function cancel($user, $notrigger = 0) + { + // Protection + if ($this->status != self::STATUS_VALIDATED) { + return 0; + } + + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'ASSETMODEL_CANCEL'); + } + + /** + * Set back to validated status + * + * @param User $user Object user that modify + * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers + * @return int <0 if KO, 0=Nothing done, >0 if OK + */ + public function reopen($user, $notrigger = 0) + { + // Protection + if ($this->status != self::STATUS_CANCELED) { + return 0; + } + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'ASSETMODEL_REOPEN'); + } + + /** + * Return a link to the object card (with optionaly the picto) + * + * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) + * @param string $option On what the link point to ('nolink', ...) + * @param int $notooltip 1=Disable tooltip + * @param string $morecss Add more css on link + * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking + * @return string String with URL + */ + public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) + { + global $conf, $langs, $hookmanager; + + if (!empty($conf->dol_no_mouse_hover)) { + $notooltip = 1; // Force disable tooltips + } + + $result = ''; + + $label = img_picto('', $this->picto).' '.$langs->trans("AssetModel").''; + if (isset($this->status)) { + $label .= ' '.$this->getLibStatut(5); + } + $label .= '
    '; + $label .= ''.$langs->trans('Ref').': '.$this->ref; + + $url = dol_buildpath('/asset/model/card.php', 1).'?id='.$this->id; + + if ($option != 'nolink') { + // Add param to save lastsearch_values or not + $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); + if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) { + $add_save_lastsearch_values = 1; + } + if ($add_save_lastsearch_values) { + $url .= '&save_lastsearch_values=1'; + } + } + + $linkclose = ''; + if (empty($notooltip)) { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + $label = $langs->trans("ShowAssetModel"); + $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } else { + $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + } + + if ($option == 'nolink') { + $linkstart = ''; + if ($option == 'nolink') { + $linkend = ''; + } else { + $linkend = ''; + } + + $result .= $linkstart; + + if (empty($this->showphoto_on_popup)) { + if ($withpicto) { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } + } else { + if ($withpicto) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + list($class, $module) = explode('@', $this->picto); + $upload_dir = $conf->$module->multidir_output[$conf->entity]."/$class/".dol_sanitizeFileName($this->ref); + $filearray = dol_dir_list($upload_dir, "files"); + $filename = $filearray[0]['name']; + if (!empty($filename)) { + $pospoint = strpos($filearray[0]['name'], '.'); + + $pathtophoto = $class.'/'.$this->ref.'/thumbs/'.substr($filename, 0, $pospoint).'_mini'.substr($filename, $pospoint); + if (empty($conf->global->{strtoupper($module.'_'.$class).'_FORMATLISTPHOTOSASUSERS'})) { + $result .= '
    No photo
    '; + } else { + $result .= '
    No photo
    '; + } + + $result .= '
    '; + } else { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } + } + } + + if ($withpicto != 2) { + $result .= $this->ref; + } + + $result .= $linkend; + //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + + global $action, $hookmanager; + $hookmanager->initHooks(array('assetmodeldao')); + $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } + + return $result; + } + + /** + * Return the label of the status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function getLabelStatus($mode = 0) + { + return $this->LibStatut($this->status, $mode); + } + + /** + * Return the label of the status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function getLibStatut($mode = 0) + { + return $this->LibStatut($this->status, $mode); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return the status + * + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function LibStatut($status, $mode = 0) + { + // phpcs:enable + if (empty($this->labelStatus) || empty($this->labelStatusShort)) { + global $langs; + //$langs->load("asset@asset"); + $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled'); + $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled'); + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled'); + } + + $statusType = 'status'.$status; + //if ($status == self::STATUS_VALIDATED) $statusType = 'status1'; + if ($status == self::STATUS_CANCELED) { + $statusType = 'status6'; + } + + return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); + } + + /** + * Load the info information in the object + * + * @param int $id Id of object + * @return void + */ + public function info($id) + { + $sql = "SELECT rowid, date_creation as datec, tms as datem,"; + $sql .= " fk_user_creat, fk_user_modif"; + $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t"; + $sql .= " WHERE t.rowid = ".((int) $id); + + $result = $this->db->query($sql); + if ($result) { + if ($this->db->num_rows($result)) { + $obj = $this->db->fetch_object($result); + $this->id = $obj->rowid; + if ($obj->fk_user_author) { + $cuser = new User($this->db); + $cuser->fetch($obj->fk_user_author); + $this->user_creation = $cuser; + } + + if ($obj->fk_user_valid) { + $vuser = new User($this->db); + $vuser->fetch($obj->fk_user_valid); + $this->user_validation = $vuser; + } + + if ($obj->fk_user_cloture) { + $cluser = new User($this->db); + $cluser->fetch($obj->fk_user_cloture); + $this->user_cloture = $cluser; + } + + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_modification = $this->db->jdate($obj->datem); + $this->date_validation = $this->db->jdate($obj->datev); + } + + $this->db->free($result); + } else { + dol_print_error($this->db); + } + } + + /** + * Initialise object with example values + * Id must be 0 if object instance is a specimen + * + * @return void + */ + public function initAsSpecimen() + { + // Set here init that are not commonf fields + // $this->property1 = ... + // $this->property2 = ... + + $this->initAsSpecimenCommon(); + } + + /** + * Create an array of lines + * + * @return array|int array of lines if OK, <0 if KO + */ + public function getLinesArray() + { + $this->lines = array(); + + return $this->lines; + } + + /** + * Action executed by scheduler + * CAN BE A CRON TASK. In such a case, parameters come from the schedule job setup field 'Parameters' + * Use public function doScheduledJob($param1, $param2, ...) to get parameters + * + * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) + */ + public function doScheduledJob() + { + global $conf, $langs; + + //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log'; + + $error = 0; + $this->output = ''; + $this->error = ''; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $now = dol_now(); + + $this->db->begin(); + + // ... + + $this->db->commit(); + + return $error; + } +} diff --git a/htdocs/asset/depreciation.php b/htdocs/asset/depreciation.php new file mode 100644 index 00000000000..8f3547d81fb --- /dev/null +++ b/htdocs/asset/depreciation.php @@ -0,0 +1,199 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * 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 . + */ + +/** + * \file htdocs/asset/depreciation.php + * \ingroup asset + * \brief Card with depreciation on Asset + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new Asset($db); +$assetdepreciationoptions = new AssetDepreciationOptions($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('assetdepreciation', '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->asset->multidir_output[$object->entity] . "/" . $object->id; +} + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!empty($object->not_depreciated)) accessforbidden(); + +$object->asset_depreciation_options = &$assetdepreciationoptions; +$result = $assetdepreciationoptions->fetchDeprecationOptions($object->id); +if ($result < 0) { + setEventMessages($assetdepreciationoptions->error, $assetdepreciationoptions->errors, 'errors'); +} +$result = $object->fetchDepreciationLines(); +if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); +} + + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', array(), $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)) { +} + + +/* + * View + */ + +$form = new Form($db); + +$help_url = ''; +llxHeader('', $langs->trans('Asset'), $help_url); + +if ($id > 0 || !empty($ref)) { + $head = assetPrepareHead($object); + print dol_get_fiche_head($head, 'depreciation', $langs->trans("Asset"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + print '
    '; + print '
    '; + + print dol_get_fiche_end(); + + $parameters = array(); + $reshook = $hookmanager->executeHooks('listAssetDeprecation', $parameters, $object, $action); + print $hookmanager->resPrint; + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } elseif (empty($reshook)) { + $bookkeeping_icon = ''; + $future_icon = ''; + $now = dol_now(); + + foreach ($assetdepreciationoptions->deprecation_options_fields as $mode_key => $fields) { + $lines = $object->depreciation_lines[$mode_key]; + if (!empty($lines)) { + $mode_info = $assetdepreciationoptions->deprecation_options_fields[$mode_key]; + $depreciation_info = $assetdepreciationoptions->getGeneralDepreciationInfoForMode($mode_key); + + print load_fiche_titre($langs->trans($mode_info['label']), '', ''); + + // Depreciation general info + //--------------------------------- + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + print ''; + print ''; + print '
    ' . $langs->trans('AssetBaseDepreciationHT') . '' . price($depreciation_info['base_depreciation_ht']) . '
    ' . $langs->trans('AssetDepreciationBeginDate') . '' . dol_print_date($object->date_start > $object->date_acquisition ? $object->date_start : $object->date_acquisition, 'day') . '
    '; + + // We close div and reopen for second column + print '
    '; + print '
    '; + + print '
    '; + print ''; + print ''; + print ''; + print '
    ' . $langs->trans('AssetDepreciationDuration') . '' . $depreciation_info['duration'] . ' ( ' . $depreciation_info['duration_type'] . ' )
    ' . $langs->trans('AssetDepreciationRate') . '' . $depreciation_info['rate'] . '
    '; + print '
    '; + print '
    '; + print '
    '; + + // Depreciation lines + //--------------------------------- + print '
    '; + print '
    '; + print ''; + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + if (empty($lines)) { + print ''; + } else { + foreach ($lines as $line) { + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print "\n"; + } + } + + print '
    ' . $langs->trans("Ref") . '' . $langs->trans("AssetDepreciationDate") . '' . $langs->trans("AssetDepreciationHT") . '' . $langs->trans("AssetCumulativeDepreciationHT") . '' . $langs->trans("AssetResidualHT") . '
    ' . $langs->trans("None") . '
    ' . ($line['bookkeeping'] ? $bookkeeping_icon : ($line['depreciation_date'] > $now ? $future_icon : '')) . '' . (empty($line['ref']) ? $langs->trans('AssetDepreciationReversal') : $line['ref']) . '' . dol_print_date($line['depreciation_date'], 'day') . ''; + print price($line['depreciation_ht']); + print ''; + print price($line['cumulative_depreciation_ht']); + print ''; + print price(price2num($depreciation_info['base_depreciation_ht'] - $line['cumulative_depreciation_ht'], 'MT')); + print '
    '; + print '
    '; + } + } + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/depreciation_options.php b/htdocs/asset/depreciation_options.php new file mode 100644 index 00000000000..ba5719705dc --- /dev/null +++ b/htdocs/asset/depreciation_options.php @@ -0,0 +1,190 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * 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 . + */ + +/** + * \file htdocs/asset/depreciation_options.php + * \ingroup asset + * \brief Card with depreciation options on Asset + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/asset.class.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new Asset($db); +$assetdepreciationoptions = new AssetDepreciationOptions($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('assetdepreciationoptions', '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->asset->multidir_output[$object->entity] . "/" . $object->id; +} + +$permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!empty($object->not_depreciated)) accessforbidden(); + +$object->asset_depreciation_options = &$assetdepreciationoptions; +$result = $assetdepreciationoptions->fetchDeprecationOptions($object->id); +if ($result < 0) { + setEventMessages($assetdepreciationoptions->error, $assetdepreciationoptions->errors, 'errors'); +} + + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', array(), $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)) { + $backurlforlist = DOL_URL_ROOT.'/asset/list.php'; + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = DOL_URL_ROOT.'/asset/depreciation_options.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__'); + } + } + } + + if ($cancel) { + /*var_dump($cancel);var_dump($backtopage);var_dump($backtopageforcancel);exit;*/ + if (!empty($backtopageforcancel)) { + header("Location: ".$backtopageforcancel); + exit; + } elseif (!empty($backtopage)) { + header("Location: ".$backtopage); + exit; + } + $action = ''; + } + + if ($action == "update") { + $result = $assetdepreciationoptions->setDeprecationOptionsFromPost(); + if ($result > 0) $result = $assetdepreciationoptions->updateDeprecationOptions($user, $object->id); + if ($result < 0) { + setEventMessages($assetdepreciationoptions->error, $assetdepreciationoptions->errors, 'errors'); + $action = 'edit'; + } else { + setEventMessage($langs->trans('RecordSaved')); + header("Location: " . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit; + } + } +} + + +/* + * View + */ + +$form = new Form($db); + +$help_url = ''; +llxHeader('', $langs->trans('Asset'), $help_url); + +if ($id > 0 || !empty($ref)) { + $head = assetPrepareHead($object); + print dol_get_fiche_head($head, 'depreciation_options', $langs->trans("Asset"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + print '
    '; + print '
    '; + + if ($action == 'edit') { + print ''; + print ''; + print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } + + print dol_get_fiche_head(array(), ''); + + include DOL_DOCUMENT_ROOT . '/asset/tpl/depreciation_options_edit.tpl.php'; + + print dol_get_fiche_end(); + + print $form->buttonsSaveCancel(); + + print ''; + } else { + include DOL_DOCUMENT_ROOT . '/asset/tpl/depreciation_options_view.tpl.php'; + } + + print dol_get_fiche_end(); + + if ($action != 'edit') { + print '
    ' . "\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + + if (empty($reshook)) { + if ($object->status == $object::STATUS_DRAFT/* && !empty($object->enabled_modes)*/) { + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&token=' . newToken(), '', $permissiontoadd); + } + } + print '
    ' . "\n"; + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/disposal.php b/htdocs/asset/disposal.php new file mode 100644 index 00000000000..7fddb92b05f --- /dev/null +++ b/htdocs/asset/disposal.php @@ -0,0 +1,120 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * 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 . + */ + +/** + * \file htdocs/asset/disposal.php + * \ingroup asset + * \brief Card with disposal info on Asset + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/asset/class/asset.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new Asset($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('assetdisposal', '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->asset->multidir_output[$object->entity]."/".$object->id; +} + +$permissionnote = $user->rights->asset->write; // Used by the include of actions_setnotes.inc.php +$permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!isset($object->disposal_date) || $object->disposal_date === "") accessforbidden(); + + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', array(), $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)) { +} + + +/* + * View + */ + +$form = new Form($db); + +$help_url = ''; +llxHeader('', $langs->trans('Asset'), $help_url); + +if ($id > 0 || !empty($ref)) { + $object->fetch_thirdparty(); + + $head = assetPrepareHead($object); + + print dol_get_fiche_head($head, 'disposal', $langs->trans("Asset"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + print '
    '; + print ''."\n"; + + // Common attributes + $show_fields = array('disposal_date', 'disposal_amount_ht', 'fk_disposal_type', 'disposal_depreciated', 'disposal_subject_to_vat'); + foreach ($object->fields as $field_key => $field_info) { + $object->fields[$field_key]['visible'] = in_array($field_key, $show_fields) ? 1 : 0; + } + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; + + print '
    '; + print '
    '; + + print dol_get_fiche_end(); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/document.php b/htdocs/asset/document.php index 9d46e9ae0b6..96b222b26c1 100644 --- a/htdocs/asset/document.php +++ b/htdocs/asset/document.php @@ -31,19 +31,18 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; // Load translation files required by the page -$langs->loadLangs(array('assets', 'companies', 'other')); +$langs->loadLangs(array('assets', 'companies', 'other', 'mails')); -$id = (GETPOST('id', 'int') ?GETPOST('id', 'int') : GETPOST('facid', 'int')); // For backward compatibility -$ref = GETPOST('ref', 'alpha'); -$socid = GETPOST('socid', 'int'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); // Get parameters $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; -$sortfield = GETPOST('sortfield', 'aZ09comma'); -$sortorder = GETPOST('sortorder', 'aZ09comma'); +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); if (empty($page) || $page == -1) { $page = 0; @@ -58,18 +57,28 @@ if (!$sortfield) { $sortfield = "name"; } +// Initialize technical objects $object = new Asset($db); -if ($object->fetch($id)) { - $upload_dir = $conf->asset->dir_output."/".dol_sanitizeFileName($object->ref); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('assetdocument', '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->asset->multidir_output[$object->entity ? $object->entity : $conf->entity]."/".get_exdir(0, 0, 0, 1, $object); } -$permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php +$permissiontoadd = $user->rights->asset->asset->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result=restrictedArea($user, 'asset', $id, ''); +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); /* @@ -83,60 +92,67 @@ include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; * View */ -$title = $langs->trans('Assets')." - ".$langs->trans('Documents'); - -$help_url = ''; - -llxHeader('', $title, $help_url); - $form = new Form($db); +$title = $langs->trans("Asset").' - '.$langs->trans("Files"); +$help_url = ''; +llxHeader('', $title, $help_url); + +if ($object->id) { + /* + * Show tabs + */ + $head = assetPrepareHead($object); + + print dol_get_fiche_head($head, 'document', $langs->trans("Asset"), -1, $object->picto); -if ($id > 0 || !empty($ref)) { - if ($object->fetch($id, $ref) > 0) { - $upload_dir = $conf->asset->multidir_output[$object->entity].'/'.dol_sanitizeFileName($object->ref); - - $head = asset_prepare_head($object); - print dol_get_fiche_head($head, 'documents', $langs->trans('Asset'), -1, 'accounting'); - - // Build file list - $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ?SORT_DESC:SORT_ASC), 1); - $totalsize = 0; - foreach ($filearray as $key => $file) { - $totalsize += $file['size']; - } - - // Asset content - - $linkback = ''.$langs->trans("BackToList").''; - - $morehtmlref = ''; - dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0); - - print '
    '; - print '
    '; - - print ''; - - print ''; - print ''; - print "
    '.$langs->trans("NbOfAttachedFiles").''.count($filearray).'
    '.$langs->trans("TotalSizeOfAttachedFiles").''.dol_print_size($totalsize, 1, 1).'
    \n"; - - print "
    \n"; - - print dol_get_fiche_end(); - - $modulepart = 'asset'; - $permissiontoadd = $user->rights->asset->write; - $permtoedit = $user->rights->asset->write; - $param = '&id='.$object->id; - include DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php'; - } else { - dol_print_error($db); + // Build file list + $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', $sortfield, (strtolower($sortorder) == 'desc' ? SORT_DESC : SORT_ASC), 1); + $totalsize = 0; + foreach ($filearray as $key => $file) { + $totalsize += $file['size']; } + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + + print '
    '; + print ''; + + // Number of files + print ''; + + // Total size + print ''; + + print '
    ' . $langs->trans("NbOfAttachedFiles") . '' . count($filearray) . '
    ' . $langs->trans("TotalSizeOfAttachedFiles") . '' . $totalsize . ' ' . $langs->trans("bytes") . '
    '; + + print '
    '; + + print dol_get_fiche_end(); + + $modulepart = 'asset'; + $permissiontoadd = $user->rights->asset->write; + // $permissiontoadd = 1; + $permtoedit = $user->rights->asset->write; + // $permtoedit = 1; + $param = '&id=' . $object->id; + + //$relativepathwithnofile='asset/' . dol_sanitizeFileName($object->id).'/'; + $relativepathwithnofile = dol_sanitizeFileName($object->ref) . '/'; + + include DOL_DOCUMENT_ROOT . '/core/tpl/document_actions_post_headers.tpl.php'; } else { - print $langs->trans("ErrorUnknown"); + accessforbidden('', 0, 1); } // End of page diff --git a/htdocs/asset/info.php b/htdocs/asset/info.php deleted file mode 100644 index 7a8f4c20ce2..00000000000 --- a/htdocs/asset/info.php +++ /dev/null @@ -1,93 +0,0 @@ - - * - * 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 . - */ - -/** - * \file htdocs/asset/info.php - * \ingroup asset - * \brief Page to show an asset information - */ - -require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/asset.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/asset/class/asset.class.php'; - -// Load translation files required by the page -$langs->loadLangs(array("asset")); - -$id = GETPOSTINT('id'); -$ref = GETPOST('ref', 'alpha'); -$action = GETPOST('action', 'aZ09'); - -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'asset', $id); - -$object = new Asset($db); -$object->fetch($id); - - -/* - * Actions - */ - -// None - - -/* - * View - */ - -$form = new Form($db); - -$title = $langs->trans('Asset')." - ".$langs->trans('Info'); - -$help_url = ""; - -llxHeader('', $title, $help_url); - -$object->info($id); - -$head = asset_prepare_head($object); - -print dol_get_fiche_head($head, 'info', $langs->trans("Asset"), -1, 'generic'); - -$linkback = ''.$langs->trans("BackToList").''; - -$morehtmlref = '
    '; -$morehtmlref .= '
    '; - -dol_banner_tab($object, 'rowid', $linkback, 1, 'rowid', 'ref', $morehtmlref); - -print '
    '; -print '
    '; - -print '
    '; - -print '
    '; -dol_print_object_info($object); -print '
    '; - -print '
    '; - -print dol_get_fiche_end(); - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/asset/list.php b/htdocs/asset/list.php index 1abdabd333e..c475e22fc83 100644 --- a/htdocs/asset/list.php +++ b/htdocs/asset/list.php @@ -31,26 +31,26 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/asset/class/asset.class.php'; // Load translation files required by the page -$langs->loadLangs(array("assets")); +$langs->loadLangs(array("assets", "other")); -$action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... -$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) -$show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ? -$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation -$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button -$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list -$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'assetlist'; // To manage different context of search -$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page -$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') +$action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... +$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) +$show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ? +$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation +$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button +$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'assetlist'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page +$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') $id = GETPOST('id', 'int'); // Load variable for pagination -$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; +$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 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { +if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { $page = 0; } // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action $offset = $limit * $page; @@ -71,33 +71,24 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen // Default sort order (if not yet defined by previous GETPOST) if (!$sortfield) { + reset($object->fields); // Reset is required to avoid key() to return null. $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition. } if (!$sortorder) { $sortorder = "ASC"; } -// Security check -$socid = 0; -if ($user->socid) { - $socid = $user->socid; -} -if ($user->socid > 0) { - // Protection if external user - //$socid = $user->socid; - accessforbidden(); -} -// Security check -$result = restrictedArea($user, 'asset', $id); - - // Initialize array of search criterias -$search_all = GETPOST("search_all", 'alpha'); +$search_all = GETPOST('search_all', 'alphanohtml'); $search = array(); foreach ($object->fields as $key => $val) { if (GETPOST('search_'.$key, 'alpha') !== '') { $search[$key] = GETPOST('search_'.$key, 'alpha'); } + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int')); + $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int')); + } } // List of fields to search into when doing a "search in all" @@ -108,27 +99,24 @@ foreach ($object->fields as $key => $val) { } } -// Definition of fields for list +// Definition of array of fields for columns $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $arrayfields['t.'.$key] = array('label'=>$val['label'], 'checked'=>(($val['visible'] < 0) ? 0 : 1), 'enabled'=>($val['enabled'] && ($val['visible'] != 3)), 'position'=>$val['position']); + $visible = (int) dol_eval($val['visible'], 1); + $arrayfields['t.'.$key] = array( + 'label'=>$val['label'], + 'checked'=>(($visible < 0) ? 0 : 1), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'position'=>$val['position'], + 'help'=> isset($val['help']) ? $val['help'] : '' + ); } } // Extra fields -if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label']) > 0) { - foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - if (!empty($extrafields->attributes[$object->table_element]['list'][$key])) { - $arrayfields["ef.".$key] = array( - 'label'=>$extrafields->attributes[$object->table_element]['label'][$key], - 'checked'=>(($extrafields->attributes[$object->table_element]['list'][$key] < 0) ? 0 : 1), - 'position'=>$extrafields->attributes[$object->table_element]['pos'][$key], - 'enabled'=>(abs($extrafields->attributes[$object->table_element]['list'][$key]) != 3 && $extrafields->attributes[$object->table_element]['perms'][$key]) - ); - } - } -} +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'); @@ -136,13 +124,28 @@ $permissiontoread = $user->rights->asset->read; $permissiontoadd = $user->rights->asset->write; $permissiontodelete = $user->rights->asset->delete; +// Security check +if (empty($conf->asset->enabled)) { + accessforbidden('Module not enabled'); +} + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$socid = 0; if ($user->socid > 0) $socid = $user->socid; +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + + /* * Actions */ if (GETPOST('cancel', 'alpha')) { - $action = 'list'; $massaction = ''; + $action = 'list'; + $massaction = ''; } if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; @@ -162,8 +165,12 @@ if (empty($reshook)) { 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 foreach ($object->fields as $key => $val) { $search[$key] = ''; + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = ''; + $search[$key.'_dtend'] = ''; + } } - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') @@ -188,21 +195,20 @@ $form = new Form($db); $now = dol_now(); -//$help_url="EN:Module_Asset|FR:Module_Asset_FR|ES:Módulo_Asset"; $help_url = ''; $title = $langs->trans('ListOf', $langs->transnoentitiesnoconv("Assets")); +$morejs = array(); +$morecss = array(); // 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 @@ -211,27 +217,45 @@ $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $obje $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); $sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; -if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { +if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; } +// Add table from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; if ($object->ismultientitymanaged == 1) { $sql .= " WHERE t.entity IN (".getEntity($object->element).")"; } else { $sql .= " WHERE 1 = 1"; } foreach ($search as $key => $val) { - if ($key == 'status' && $search[$key] == -1) { - continue; - } - $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); - if (strpos($object->fields[$key]['type'], 'integer:') === 0) { - if ($search[$key] == '-1') { - $search[$key] = ''; + if (array_key_exists($key, $object->fields)) { + if ($key == 'status' && $search[$key] == -1) { + continue; + } + $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); + if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) { + if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) { + $search[$key] = ''; + } + $mode_search = 2; + } + if ($search[$key] != '') { + $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); + } + } else { + if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') { + $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key); + if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) { + if (preg_match('/_dtstart$/', $key)) { + $sql .= " AND t.".$columnName." >= '".$db->idate($search[$key])."'"; + } + if (preg_match('/_dtend$/', $key)) { + $sql .= " AND t." . $columnName . " <= '" . $db->idate($search[$key]) . "'"; + } + } } - $mode_search = 2; - } - if ($search[$key] != '') { - $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); } } if ($search_all) { @@ -246,51 +270,69 @@ $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $objec $sql .= $hookmanager->resPrint; /* If a group by is required -$sql.= " GROUP BY " -foreach($object->fields as $key => $val) -{ +$sql .= " GROUP BY "; +foreach($object->fields as $key => $val) { $sql .= "t.".$key.", "; } // 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.', ' : ''); +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.', ' : ''); + } } // Add where from hooks -$parameters=array(); -$reshook=$hookmanager->executeHooks('printFieldListGroupBy',$parameters); // Note that $action and $object may have been modified by hook -$sql.=$hookmanager->resPrint; -$sql=preg_replace('/,\s*$/','', $sql); +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; +$sql = preg_replace('/,\s*$/', '', $sql); */ -$sql .= $db->order($sortfield, $sortorder); +// Add HAVING from hooks +/* +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= !empty($hookmanager->resPrint) ? (" HAVING 1=1 " . $hookmanager->resPrint) : ""; +*/ // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + /* This old and fast method to get and count full list returns all record so use a high amount of memory. $resql = $db->query($sql); $nbtotalofrecords = $db->num_rows($resql); + */ + /* The slow method does not consume memory on mysql (not tested on pgsql) */ + /*$resql = $db->query($sql, 0, 'auto', 1); + while ($db->fetch_object($resql)) { + $nbtotalofrecords++; + }*/ + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^SELECT[a-z0-9\._\s\(\),]+FROM/i', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $resql = $db->query($sqlforcount); + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 $page = 0; $offset = 0; } + $db->free($resql); } -// if total of record found is smaller than limit, no need to do paging and to restart another select with limits set. -if (is_numeric($nbtotalofrecords) && ($limit > $nbtotalofrecords || empty($limit))) { - $num = $nbtotalofrecords; -} else { - if ($limit) { - $sql .= $db->plimit($limit + 1, $offset); - } - $resql = $db->query($sql); - if (!$resql) { - dol_print_error($db); - exit; - } - - $num = $db->num_rows($resql); +// Complete request and execute it with limit +$sql .= $db->order($sortfield, $sortorder); +if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); } +$resql = $db->query($sql); +if (!$resql) { + dol_print_error($db); + exit; +} + +$num = $db->num_rows($resql); + + // Direct jump if only one record found if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) { $obj = $db->fetch_object($resql); @@ -303,7 +345,7 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $ // Output page // -------------------------------------------------------------------- -llxHeader('', $title, $help_url); +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); $arrayofselected = is_array($toselect) ? $toselect : array(); @@ -317,9 +359,11 @@ if ($limit > 0 && $limit != $conf->liste_limit) { foreach ($search as $key => $val) { if (is_array($search[$key]) && count($search[$key])) { foreach ($search[$key] as $skey) { - $param .= '&search_'.$key.'[]='.urlencode($skey); + if ($skey != '') { + $param .= '&search_'.$key.'[]='.urlencode($skey); + } } - } else { + } elseif ($search[$key] != '') { $param .= '&search_'.$key.'='.urlencode($search[$key]); } } @@ -328,11 +372,17 @@ if ($optioncss != '') { } // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; +// Add $param from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook +$param .= $hookmanager->resPrint; // List of mass actions available $arrayofmassactions = array( - //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), + //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"), + //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"), //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), + //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), ); if ($permissiontodelete) { $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); @@ -351,24 +401,25 @@ print ''; print ''; print ''; +print ''; print ''; -$newcardbutton = dolGetButtonTitle($langs->trans('NewAsset'), '', 'fa fa-plus-circle', dol_buildpath('/asset/card.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); +$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/asset/card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); -print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, $object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); // Add code for pre mass action (confirmation or email presend form) -$topicmail = "SendAssetsRef"; +$topicmail = "SendAssetRef"; $modelmail = "asset"; $objecttmp = new Asset($db); $trackid = 'asset'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; -if ($sall) { +if ($search_all) { foreach ($fieldstosearchall as $key => $val) { $fieldstosearchall[$key] = $langs->trans($val); } - print '
    '.$langs->trans("FilterOnInto", $sall).join(', ', $fieldstosearchall).'
    '; + print '
    '.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
    '; } $moreforfilter = ''; @@ -395,31 +446,42 @@ $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfi $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table -print ''."\n"; +print '
    '."\n"; // Fields title search // -------------------------------------------------------------------- print ''; foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if ($key == 'status') { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } if (!empty($arrayfields['t.'.$key]['checked'])) { print ''; } @@ -443,14 +505,14 @@ print ''."\n"; // -------------------------------------------------------------------- print ''; foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if ($key == 'status') { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif (in_array($val['type'], array('timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; - } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID') { + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } if (!empty($arrayfields['t.'.$key]['checked'])) { @@ -464,13 +526,13 @@ $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$ $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column -print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', 'align="center"', $sortfield, $sortorder, 'maxwidthsearch ')."\n"; +print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; print ''."\n"; // Detect if we need a fetch on each output line $needToFetchEachLine = 0; -if (is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) { +if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) { foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) { if (preg_match('/\$object/', $val)) { $needToFetchEachLine++; // There is at least one compute field that use $object @@ -483,6 +545,7 @@ if (is_array($extrafields->attributes[$object->table_element]['computed']) && co // -------------------------------------------------------------------- $i = 0; $totalarray = array(); +$totalarray['nbfield'] = 0; while ($i < ($limit ? min($num, $limit) : $num)) { $obj = $db->fetch_object($resql); if (empty($obj)) { @@ -495,7 +558,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { // Show here line of result print ''; foreach ($object->fields as $key => $val) { - $cssforfield = (empty($val['css']) ? '' : $val['css']); + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { $cssforfield .= ($cssforfield ? ' ' : '').'center'; } elseif ($key == 'status') { @@ -508,14 +571,17 @@ while ($i < ($limit ? min($num, $limit) : $num)) { $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; } - if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'status') { + if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) { $cssforfield .= ($cssforfield ? ' ' : '').'right'; } + //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; if (!empty($arrayfields['t.'.$key]['checked'])) { print ''; if ($key == 'status') { print $object->getLibStatut(5); + } elseif ($key == 'rowid') { + print $object->showOutputField($val, $key, $object->id, ''); } else { print $object->showOutputField($val, $key, $object->$key, ''); } @@ -545,7 +611,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { print $hookmanager->resPrint; // Action column print ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo "\n"; +} +if (count($linkedObjectBlock) > 1) { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo "\n"; +} + +echo "\n"; diff --git a/htdocs/asset/type.php b/htdocs/asset/type.php deleted file mode 100644 index cd802c1c4fd..00000000000 --- a/htdocs/asset/type.php +++ /dev/null @@ -1,608 +0,0 @@ - - * - * 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 . - */ - -/** - * \file htdocs/asset/type.php - * \ingroup asset - * \brief Asset's type setup - */ - -require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/asset.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/asset/class/asset.class.php'; -require_once DOL_DOCUMENT_ROOT.'/asset/class/asset_type.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; -if (!empty($conf->accounting->enabled)) { - require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; -} -if (!empty($conf->accounting->enabled)) { - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; -} -if (!empty($conf->accounting->enabled)) { - require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; -} - -// Load translation files required by the page -$langs->load("assets"); - -$rowid = GETPOST('rowid', 'int'); -$action = GETPOST('action', 'aZ09'); -$cancel = GETPOST('cancel', 'alpha'); -$backtopage = GETPOST('backtopage', 'alpha'); - -$type = GETPOST('type', 'alpha'); - -$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 (!$sortorder) { - $sortorder = "DESC"; -} -if (!$sortfield) { - $sortfield = "a.label"; -} - -$label = GETPOST("label", "alpha"); -$accountancy_code_asset = GETPOST('accountancy_code_asset', 'string'); -$accountancy_code_depreciation_asset = GETPOST('accountancy_code_depreciation_asset', 'string'); -$accountancy_code_depreciation_expense = GETPOST('accountancy_code_depreciation_expense', 'string'); -$comment = GETPOST('comment', 'string'); - -// Security check -$result = restrictedArea($user, 'asset', $rowid, 'asset_type'); - -$object = new AssetType($db); - -$extrafields = new ExtraFields($db); - -// fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label($object->table_element); - -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 - $type = ""; - $sall = ""; -} - - -// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context -$hookmanager->initHooks(array('assettypecard', 'globalcard')); - -$permissiontoadd = $user->rights->asset->setup_advance; - - -/* - * Actions - */ - -if ($cancel) { - $action = ''; - - if (!empty($backtopage)) { - header("Location: ".$backtopage); - exit; - } -} - -if ($action == 'add' && $user->rights->asset->write) { - $object->label = trim($label); - $object->accountancy_code_asset = trim($accountancy_code_asset); - $object->accountancy_code_depreciation_asset = trim($accountancy_code_depreciation_asset); - $object->accountancy_code_depreciation_expense = trim($accountancy_code_depreciation_expense); - $object->note = trim($comment); - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost(null, $object); - if ($ret < 0) { - $error++; - } - - if (empty($object->label)) { - $error++; - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors'); - } else { - $sql = "SELECT label FROM ".MAIN_DB_PREFIX."asset_type WHERE label='".$db->escape($object->label)."'"; - $result = $db->query($sql); - if ($result) { - $num = $db->num_rows($result); - } - if ($num) { - $error++; - $langs->load("errors"); - setEventMessages($langs->trans("ErrorLabelAlreadyExists", $login), null, 'errors'); - } - } - - if (!$error) { - $id = $object->create($user); - if ($id > 0) { - header("Location: ".$_SERVER["PHP_SELF"]); - exit; - } else { - setEventMessages($object->error, $object->errors, 'errors'); - $action = 'create'; - } - } else { - $action = 'create'; - } -} - -if ($action == 'update' && $user->rights->asset->write) { - $object->fetch($rowid); - - $object->oldcopy = clone $object; - - $object->label = trim($label); - $object->accountancy_code_asset = trim($accountancy_code_asset); - $object->accountancy_code_depreciation_asset = trim($accountancy_code_depreciation_asset); - $object->accountancy_code_depreciation_expense = trim($accountancy_code_depreciation_expense); - $object->note = trim($comment); - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost(null, $object, '@GETPOSTISSET'); - if ($ret < 0) { - $error++; - } - - $ret = $object->update($user); - - if ($ret >= 0 && !count($object->errors)) { - setEventMessages($langs->trans("AssetTypeModified"), null, 'mesgs'); - } else { - setEventMessages($object->error, $object->errors, 'errors'); - } - - header("Location: ".$_SERVER["PHP_SELF"]."?rowid=".$object->id); - exit; -} - -if ($action == 'confirm_delete' && $user->rights->asset->write) { - $object->fetch($rowid); - $res = $object->delete(); - - if ($res > 0) { - setEventMessages($langs->trans("AssetsTypeDeleted"), null, 'mesgs'); - header("Location: ".$_SERVER["PHP_SELF"]); - exit; - } else { - setEventMessages($langs->trans("AssetsTypeCanNotBeDeleted"), null, 'errors'); - $action = ''; - } -} - - -/* - * View - */ - -$form = new Form($db); - -$help_url = ''; - -llxHeader('', $langs->trans("AssetsTypeSetup"), $help_url); - - -// List of asset type -if (!$rowid && $action != 'create' && $action != 'edit') { - //print dol_get_fiche_head(''); - - $sql = "SELECT d.rowid, d.label as label, d.accountancy_code_asset, d.accountancy_code_depreciation_asset, d.accountancy_code_depreciation_expense, d.note"; - $sql .= " FROM ".MAIN_DB_PREFIX."asset_type as d"; - $sql .= " WHERE d.entity IN (".getEntity('asset_type').")"; - - $result = $db->query($sql); - if ($result) { - $num = $db->num_rows($result); - $nbtotalofrecords = $num; - - $i = 0; - - $param = ''; - - print '
    '; - if ($optioncss != '') { - print ''; - } - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - $newcardbutton = dolGetButtonTitle($langs->trans('NewAssetType'), '', 'fa fa-plus-circle', dol_buildpath('/asset/type.php', 1).'?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); - - print_barre_liste($langs->trans("AssetsTypes"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, $object->picto, 0, $newcardbutton, '', $limit); - - $moreforfilter = ''; - - print '
    '; - print '
    '; if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { - print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $search[$key], $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); - } elseif (strpos($val['type'], 'integer:') === 0) { - print $object->showInputField($val, $key, $search[$key], '', '', 'search_', 'maxwidth150', 1); - } elseif (!preg_match('/^(date|timestamp)/', $val['type'])) { - print ''; + print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); + } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) { + print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', 'maxwidth125', 1); + } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + print '
    '; + print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
    '; + print '
    '; + print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
    '; + } elseif ($key == 'lang') { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; + $formadmin = new FormAdmin($db); + print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2); + } else { + print ''; } print '
    '; - if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined $selected = 0; if (in_array($object->id, $arrayofselected)) { $selected = 1; @@ -605,7 +671,7 @@ if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $n $genallowed = $permissiontoread; $delallowed = $permissiontoadd; - print $formfile->showdocuments('massfilesarea_asset', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, ''); + print $formfile->showdocuments('massfilesarea_asset', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); } // End of page diff --git a/htdocs/asset/model/accountancy_codes.php b/htdocs/asset/model/accountancy_codes.php new file mode 100644 index 00000000000..7582b61177e --- /dev/null +++ b/htdocs/asset/model/accountancy_codes.php @@ -0,0 +1,191 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * 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 . + */ + +/** + * \file htdocs/asset/model/accountancy_code.php + * \ingroup asset + * \brief Card with accountancy code on Asset Model + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetmodel.class.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetaccountancycodes.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new AssetModel($db); +$assetaccountancycodes = new AssetAccountancyCodes($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('assetmodelaccountancycodes', '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->asset->multidir_output[$object->entity] . "/" . $object->id; +} + +$permissiontoread = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->read) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->model_advance->read))); +$permissiontoadd = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->write) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->model_advance->write))); // Used by the include of actions_addupdatedelete.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, 'asset', $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + +$result = $assetaccountancycodes->fetchAccountancyCodes(0, $object->id); +if ($result < 0) { + setEventMessages($assetaccountancycodes->error, $assetaccountancycodes->errors, 'errors'); +} + + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', array(), $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)) { + $backurlforlist = DOL_URL_ROOT.'/asset/list.php'; + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = DOL_URL_ROOT.'/asset/model/accountancy_codes.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__'); + } + } + } + + if ($cancel) { + /*var_dump($cancel);var_dump($backtopage);var_dump($backtopageforcancel);exit;*/ + if (!empty($backtopageforcancel)) { + header("Location: ".$backtopageforcancel); + exit; + } elseif (!empty($backtopage)) { + header("Location: ".$backtopage); + exit; + } + $action = ''; + } + + if ($action == "update") { + $assetaccountancycodes->setAccountancyCodesFromPost(); + + $result = $assetaccountancycodes->updateAccountancyCodes($user, 0, $object->id); + if ($result < 0) { + setEventMessages($assetaccountancycodes->error, $assetaccountancycodes->errors, 'errors'); + $action = 'edit'; + } else { + setEventMessage($langs->trans('RecordSaved')); + header("Location: " . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit; + } + } +} + + +/* + * View + */ + +$form = new Form($db); + +$help_url = ''; +llxHeader('', $langs->trans('AssetModel'), $help_url); + +if ($id > 0 || !empty($ref)) { + $head = assetModelPrepareHead($object); + print dol_get_fiche_head($head, 'accountancy_codes', $langs->trans("AssetModel"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + print '
    '; + print '
    '; + + if ($action == 'edit') { + print '
    '; + print ''; + print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } + + print dol_get_fiche_head(array(), ''); + + include DOL_DOCUMENT_ROOT . '/asset/tpl/accountancy_codes_edit.tpl.php'; + + print dol_get_fiche_end(); + + print $form->buttonsSaveCancel(); + + print '
    '; + } else { + include DOL_DOCUMENT_ROOT . '/asset/tpl/accountancy_codes_view.tpl.php'; + } + + print dol_get_fiche_end(); + + if ($action != 'edit') { + print '
    ' . "\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + + if (empty($reshook)) { + if ($object->status == $object::STATUS_DRAFT/* && !empty($object->enabled_modes)*/) { + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&token=' . newToken(), '', $permissiontoadd); + } + } + print '
    ' . "\n"; + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/model/agenda.php b/htdocs/asset/model/agenda.php new file mode 100644 index 00000000000..a915f540ce9 --- /dev/null +++ b/htdocs/asset/model/agenda.php @@ -0,0 +1,217 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * 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 . + */ + +/** + * \file htdocs/asset/model/agenda.php + * \ingroup asset + * \brief Tab of events on Asset Model + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetmodel.class.php'; +require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "other")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$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' : (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT)); +} +$search_agenda_label = GETPOST('search_agenda_label'); + +$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +if (empty($page) || $page == -1) { + $page = 0; +} // If $page is not defined, or '' or -1 +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (!$sortfield) { + $sortfield = 'a.datep,a.id'; +} +if (!$sortorder) { + $sortorder = 'DESC,DESC'; +} + +// Initialize technical objects +$object = new AssetModel($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('assetmodelagenda', '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->asset->multidir_output[$object->entity] . "/model/" . $object->id; +} + +$permissiontoread = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->read) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->model_advance->read))); +$permissiontoadd = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->write) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->model_advance->write))); // Used by the include of actions_addupdatedelete.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +if ($user->socid > 0) $socid = $user->socid; +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, 'asset', $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + + +/* + * 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'; + llxHeader('', $title, $help_url); + + if (!empty($conf->notification->enabled)) { + $langs->load("mails"); + } + $head = assetModelPrepareHead($object); + + + print dol_get_fiche_head($head, 'agenda', $langs->trans("AssetModel"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + print '
    '; + + $object->info($object->id); + dol_print_object_info($object, 1); + + print '
    '; + + print dol_get_fiche_end(); + + + // Actions buttons + + $objthirdparty = $object; + $objcon = new stdClass(); + + $out = '&origin=' . urlencode($object->element . '@' . $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.='trans("AddAnAction"),'filenew'); + //$out.=""; + } + + + print '
    '; + + // if (!empty($conf->agenda->enabled)) { + // if (!empty($user->rights->agenda->myactions->create) || !empty($user->rights->agenda->allactions->create)) { + // print '' . $langs->trans("AddAction") . ''; + // } else { + // print '' . $langs->trans("AddAction") . ''; + // } + // } + + print '
    '; + + // if (!empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) { + // $param = '&id=' . $object->id . '&socid=' . $socid; + // if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { + // $param .= '&contextpage=' . urlencode($contextpage); + // } + // if ($limit > 0 && $limit != $conf->liste_limit) { + // $param .= '&limit=' . urlencode($limit); + // } + // + // + // print load_fiche_titre($langs->trans("ActionsOnAssetModel"), '', ''); + // + // // List of all actions + // $filters = array(); + // $filters['search_agenda_label'] = $search_agenda_label; + // + // // TODO Replace this with same code than into list.php + // show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder, $object->module); + // } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/model/card.php b/htdocs/asset/model/card.php new file mode 100644 index 00000000000..f4cf1074dd2 --- /dev/null +++ b/htdocs/asset/model/card.php @@ -0,0 +1,330 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * 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 . + */ + +/** + * \file htdocs/asset/model/card.php + * \ingroup asset + * \brief Page to create/edit/view asset Model + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetmodel.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT . '/core/class/html.formfile.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "other")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm', 'alpha'); +$cancel = GETPOST('cancel', 'aZ09'); +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'assetmodelcard'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); + +// Initialize technical objects +$object = new AssetModel($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('assetmodelcard', 'globalcard')); // Note that conf->hooks_modules contains array + +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); + +// Initialize array of search criterias +$search_all = GETPOST("search_all", 'alpha'); +$search = array(); +foreach ($object->fields as $key => $val) { + if (GETPOST('search_' . $key, 'alpha')) { + $search[$key] = GETPOST('search_' . $key, 'alpha'); + } +} + +if (empty($action) && empty($id) && empty($ref)) { + $action = 'view'; +} + +// Load object +include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once. + +$permissiontoread = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->read) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->model_advance->read))); +$permissiontoadd = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->write) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->model_advance->write))); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php +$permissiontodelete = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->delete) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->model_advance->delete))) || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); +$permissionnote = $permissiontoadd; // Used by the include of actions_setnotes.inc.php +$permissiondellink = $permissiontoadd; // Used by the include of actions_dellink.inc.php +$upload_dir = $conf->asset->multidir_output[isset($object->entity) ? $object->entity : 1]; + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +if ($user->socid > 0) $socid = $user->socid; +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, 'asset', $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + + +/* + * Actions + */ + +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + $error = 0; + + $backurlforlist = DOL_URL_ROOT . '/asset/model/list.php'; + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = DOL_URL_ROOT . '/asset/model/card.php?id=' . ((!empty($id) && $id > 0) ? $id : '__ID__'); + } + } + } + + $triggermodname = 'ASSETMODEL_MODIFY'; // Name of trigger action code to execute when we modify record + + if (($action == 'edit' && !($permissiontoadd && $object->status == $object::STATUS_DRAFT)) || + ($action == 'confirm_setdraft' && !($permissiontoadd && $object->status != $object::STATUS_DRAFT)) || + ($action == 'confirm_validate' && !($permissiontoadd && $object->status != $object::STATUS_VALIDATED)) || + ($action == 'confirm_close' && !($permissiontoadd && $object->status != $object::STATUS_CANCELED)) + ) { + $action = ""; + } + + // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen + include DOL_DOCUMENT_ROOT . '/core/actions_addupdatedelete.inc.php'; +} + + +/* + * View + * + * Put here all code to build page + */ + +$form = new Form($db); +$formfile = new FormFile($db); + +$title = $langs->trans("AssetModel") . ' - ' . $langs->trans("Card"); +$help_url = ''; +llxHeader('', $title, $help_url); + +// Part to create +if ($action == 'create') { + print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("AssetModel")), '', 'object_' . $object->picto); + + print '
    '; + print ''; + print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } + + print dol_get_fiche_head(array(), ''); + + // Set some default values + //if (! GETPOSTISSET('fieldname')) $_POST['fieldname'] = 'myvalue'; + + print '' . "\n"; + + // Common attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_add.tpl.php'; + + // Other attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_add.tpl.php'; + + print '
    ' . "\n"; + + print dol_get_fiche_end(); + + print $form->buttonsSaveCancel("Create"); + + print '
    '; + + //dol_set_focus('input[name="ref"]'); +} + +// Part to edit record +if (($id || $ref) && $action == 'edit') { + print load_fiche_titre($langs->trans("AssetModel"), '', 'object_' . $object->picto); + + print '
    '; + print ''; + print ''; + print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } + + print dol_get_fiche_head(); + + print '' . "\n"; + + // Common attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_edit.tpl.php'; + + // Other attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_edit.tpl.php'; + + print '
    '; + + print dol_get_fiche_end(); + + print $form->buttonsSaveCancel(); + + print '
    '; +} + +// Part to show record +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { + $res = $object->fetch_optionals(); + + $head = assetModelPrepareHead($object); + print dol_get_fiche_head($head, 'card', $langs->trans("AssetModel"), -1, $object->picto); + + $formconfirm = ''; + + // Confirmation to delete + if ($action == 'delete') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteAssetModel'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); + } elseif ($action == 'clone') { + // Clone confirmation + // Create an array for form + $formquestion = array(); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); + } + + // Call Hook formConfirm + $parameters = array('formConfirm' => $formconfirm); + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + $formconfirm .= $hookmanager->resPrint; + } elseif ($reshook > 0) { + $formconfirm = $hookmanager->resPrint; + } + + // Print form confirm + print $formconfirm; + + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + + // Common attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_view.tpl.php'; + + // Other attributes. Fields from hook formObjectOptions and Extrafields. + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + + print '
    '; + print '
    '; + print '
    '; + + print '
    '; + + print dol_get_fiche_end(); + + + // Buttons for actions + if ($action != 'editline') { + print '
    ' . "\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + + if (empty($reshook)) { + if ($object->status == $object::STATUS_DRAFT) { + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&token=' . newToken(), '', $permissiontoadd); + } + + // Back to draft + if ($object->status != $object::STATUS_DRAFT) { + print dolGetButtonAction($langs->trans('SetToDraft'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=confirm_setdraft&confirm=yes&token=' . newToken(), '', $permissiontoadd); + } + + if ($object->status != $object::STATUS_VALIDATED) { + print dolGetButtonAction($langs->trans('Enable'), '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=confirm_validate&confirm=yes&token=' . newToken(), '', $permissiontoadd); + } + + if ($object->status != $object::STATUS_CANCELED) { + print dolGetButtonAction($langs->trans('Disable'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=confirm_close&confirm=yes&token='.newToken(), '', $permissiontoadd); + } + + // Clone + print dolGetButtonAction($langs->trans('ToClone'), '', 'default', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&socid=' . $object->socid . '&action=clone&token=' . newToken(), '', $permissiontoadd); + + // Delete (need delete permission, or if draft, just need create/modify permission) + print dolGetButtonAction($langs->trans('Delete'), '', 'delete', $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=delete&token=' . newToken(), '', $permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)); + } + print '
    ' . "\n"; + } + + print '
    '; + print ''; // ancre + + print '
    '; + + // $MAXEVENT = 10; + // + // $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT . '/asset/model/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, $object->element.'@'.$object->module, 0, 1, '', $MAXEVENT, '', $morehtmlright); + + print '
    '; +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/model/depreciation_options.php b/htdocs/asset/model/depreciation_options.php new file mode 100644 index 00000000000..c34bd38dc46 --- /dev/null +++ b/htdocs/asset/model/depreciation_options.php @@ -0,0 +1,191 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * 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 . + */ + +/** + * \file htdocs/asset/model/depreciation_options.php + * \ingroup asset + * \brief Card with depreciation options on Asset Model + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetmodel.class.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetdepreciationoptions.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new AssetModel($db); +$assetdepreciationoptions = new AssetDepreciationOptions($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('assetmodeldeprectationoptions', '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->asset->multidir_output[$object->entity] . "/" . $object->id; +} + +$permissiontoread = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->read) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->model_advance->read))); +$permissiontoadd = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->write) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->model_advance->write))); // Used by the include of actions_addupdatedelete.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, 'asset', $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + +$object->asset_depreciation_options = &$assetdepreciationoptions; +$result = $assetdepreciationoptions->fetchDeprecationOptions(0, $object->id); +if ($result < 0) { + setEventMessages($assetdepreciationoptions->error, $assetdepreciationoptions->errors, 'errors'); +} + + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', array(), $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)) { + $backurlforlist = DOL_URL_ROOT.'/asset/list.php'; + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = DOL_URL_ROOT.'/asset/model/depreciation_options.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__'); + } + } + } + + if ($cancel) { + /*var_dump($cancel);var_dump($backtopage);var_dump($backtopageforcancel);exit;*/ + if (!empty($backtopageforcancel)) { + header("Location: ".$backtopageforcancel); + exit; + } elseif (!empty($backtopage)) { + header("Location: ".$backtopage); + exit; + } + $action = ''; + } + + if ($action == "update") { + $result = $assetdepreciationoptions->setDeprecationOptionsFromPost(1); + if ($result > 0) $result = $assetdepreciationoptions->updateDeprecationOptions($user, 0, $object->id); + if ($result < 0) { + setEventMessages($assetdepreciationoptions->error, $assetdepreciationoptions->errors, 'errors'); + $action = 'edit'; + } else { + setEventMessage($langs->trans('RecordSaved')); + header("Location: " . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit; + } + } +} + + +/* + * View + */ + +$form = new Form($db); + +$help_url = ''; +llxHeader('', $langs->trans('AssetModel'), $help_url); + +if ($id > 0 || !empty($ref)) { + $head = assetModelPrepareHead($object); + print dol_get_fiche_head($head, 'depreciation_options', $langs->trans("AssetModel"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
    '; + print '
    '; + print '
    '; + + if ($action == 'edit') { + print '
    '; + print ''; + print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } + + print dol_get_fiche_head(array(), ''); + + include DOL_DOCUMENT_ROOT . '/asset/tpl/depreciation_options_edit.tpl.php'; + + print dol_get_fiche_end(); + + print $form->buttonsSaveCancel(); + + print '
    '; + } else { + include DOL_DOCUMENT_ROOT . '/asset/tpl/depreciation_options_view.tpl.php'; + } + + print dol_get_fiche_end(); + + if ($action != 'edit') { + print '
    ' . "\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + + if (empty($reshook)) { + if ($object->status == $object::STATUS_DRAFT/* && !empty($object->enabled_modes)*/) { + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&token=' . newToken(), '', $permissiontoadd); + } + } + print '
    ' . "\n"; + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/model/list.php b/htdocs/asset/model/list.php new file mode 100644 index 00000000000..a55d5f49f9a --- /dev/null +++ b/htdocs/asset/model/list.php @@ -0,0 +1,685 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * 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 . + */ + +/** + * \file htdocs/asset/model/list.php + * \ingroup asset + * \brief List page for asset model + */ + +// Load Dolibarr environment +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/asset/class/assetmodel.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "other")); + +$action = GETPOST('action', 'aZ09') ?GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... +$massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choice into lists) +$show_files = GETPOST('show_files', 'int'); // Show files area generated by bulk actions ? +$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation +$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button +$toselect = GETPOST('toselect', 'array'); // Array of ids of elements selected into a list +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'assetmodellist'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page +$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') + +$id = GETPOST('id', 'int'); + +// Load variable for pagination +$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; +$sortfield = GETPOST('sortfield', 'aZ09comma'); +$sortorder = GETPOST('sortorder', 'aZ09comma'); +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha') || (empty($toselect) && $massaction === '0')) { + $page = 0; +} // If $page is not defined, or '' or -1 or if we click on clear filters or if we select empty mass action +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +// Initialize technical objects +$object = new AssetModel($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('assetmodellist')); // Note that conf->hooks_modules contains array + +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); +//$extrafields->fetch_name_optionals_label($object->table_element_line); + +$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); + +// Default sort order (if not yet defined by previous GETPOST) +if (!$sortfield) { + reset($object->fields); // Reset is required to avoid key() to return null. + $sortfield = "t.".key($object->fields); // Set here default search field. By default 1st field in definition. +} +if (!$sortorder) { + $sortorder = "ASC"; +} + +// Initialize array of search criterias +$search_all = GETPOST('search_all', 'alphanohtml'); +$search = array(); +foreach ($object->fields as $key => $val) { + if ($key == 'fk_pays' && !GETPOSTISSET('search_'.$key)) { + $search[$key] = $mysoc->country_id; + } elseif (GETPOST('search_'.$key, 'alpha') !== '') { + $search[$key] = GETPOST('search_'.$key, 'alpha'); + } + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = dol_mktime(0, 0, 0, GETPOST('search_'.$key.'_dtstartmonth', 'int'), GETPOST('search_'.$key.'_dtstartday', 'int'), GETPOST('search_'.$key.'_dtstartyear', 'int')); + $search[$key.'_dtend'] = dol_mktime(23, 59, 59, GETPOST('search_'.$key.'_dtendmonth', 'int'), GETPOST('search_'.$key.'_dtendday', 'int'), GETPOST('search_'.$key.'_dtendyear', 'int')); + } +} + +// List of fields to search into when doing a "search in all" +$fieldstosearchall = array(); +foreach ($object->fields as $key => $val) { + if (!empty($val['searchall'])) { + $fieldstosearchall['t.'.$key] = $val['label']; + } +} + +// Definition of array of fields for columns +$arrayfields = array(); +foreach ($object->fields as $key => $val) { + // If $val['visible']==0, then we never show the field + if (!empty($val['visible'])) { + $visible = (int) dol_eval($val['visible'], 1); + $arrayfields['t.'.$key] = array( + 'label'=>$val['label'], + 'checked'=>(($visible < 0) ? 0 : 1), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'position'=>$val['position'], + 'help'=> isset($val['help']) ? $val['help'] : '' + ); + } +} +// Extra fields +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'); + +$permissiontoread = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->read) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->model_advance->read))); +$permissiontoadd = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->write) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->model_advance->write))); +$permissiontodelete = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->delete) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->model_advance->delete))); + +// Security check +if (empty($conf->asset->enabled)) { + accessforbidden('Module not enabled'); +} + +// Security check (enable the most restrictive one) +if ($user->socid > 0) { + accessforbidden(); +} +$socid = 0; +if ($user->socid > 0) { + $socid = $user->socid; +} +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, 'asset', $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + +/* + * Actions + */ + +if (GETPOST('cancel', 'alpha')) { + $action = 'list'; + $massaction = ''; +} +if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { + $massaction = ''; +} + +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + // Selection of new fields + include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; + + // 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 + foreach ($object->fields as $key => $val) { + $search[$key] = ''; + if ($key == 'fk_pays') $search[$key] = $mysoc->country_id; + if (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + $search[$key.'_dtstart'] = ''; + $search[$key.'_dtend'] = ''; + } + } + $toselect = array(); + $search_array_options = array(); + } + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') + || GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) { + $massaction = ''; // Protection to avoid mass action if we force a new search during a mass action confirmation + } + + // Mass actions + $objectclass = 'AssetModel'; + $objectlabel = 'AssetModel'; + $uploaddir = $conf->asset->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; +} + + + +/* + * View + */ + +$form = new Form($db); + +$now = dol_now(); + +$help_url = ''; +$title = $langs->trans('ListOf', $langs->transnoentitiesnoconv("AssetModels")); +$morejs = array(); +$morecss = array(); + + +// Build and execute select +// -------------------------------------------------------------------- +$sql = 'SELECT '; +$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 : ''); + } +} +// 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 = 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'])) { + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; +} +// Add table from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; +if ($object->ismultientitymanaged == 1) { + $sql .= " WHERE t.entity IN (".getEntity($object->element).")"; +} else { + $sql .= " WHERE 1 = 1"; +} +foreach ($search as $key => $val) { + if (array_key_exists($key, $object->fields)) { + if ($key == 'status' && $search[$key] == -1) { + continue; + } + $mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0); + if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) { + if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) { + $search[$key] = ''; + } + $mode_search = 2; + } + if ($search[$key] != '') { + $sql .= natural_search($key, $search[$key], (($key == 'status') ? 2 : $mode_search)); + } + } else { + if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') { + $columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key); + if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) { + if (preg_match('/_dtstart$/', $key)) { + $sql .= " AND t.".$columnName." >= '".$db->idate($search[$key])."'"; + } + if (preg_match('/_dtend$/', $key)) { + $sql .= " AND t." . $columnName . " <= '" . $db->idate($search[$key]) . "'"; + } + } + } + } +} +if ($search_all) { + $sql .= natural_search(array_keys($fieldstosearchall), $search_all); +} +//$sql.= dolSqlDateFilter("t.field", $search_xxxday, $search_xxxmonth, $search_xxxyear); +// Add where from extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; +// Add where from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; + +/* If a group by is required +$sql .= " GROUP BY "; +foreach($object->fields as $key => $val) { + $sql .= "t.".$key.", "; +} +// 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.', ' : ''); + } +} +// Add where from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= $hookmanager->resPrint; +$sql = preg_replace('/,\s*$/', '', $sql); +*/ + +// Add HAVING from hooks +/* +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook +$sql .= !empty($hookmanager->resPrint) ? (" HAVING 1=1 " . $hookmanager->resPrint) : ""; +*/ + +// Count total nb of records +$nbtotalofrecords = ''; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { + /* This old and fast method to get and count full list returns all record so use a high amount of memory. + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); + */ + /* The fast and low memory method to get and count full list converts the sql into a sql count */ + $sqlforcount = preg_replace('/^SELECT[a-z0-9\._\s\(\),]+FROM/i', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + + $resql = $db->query($sqlforcount); + if ($resql) { + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } else { + dol_print_error($db); + } + + if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 + $page = 0; + $offset = 0; + } + $db->free($resql); +} + +// Complete request and execute it with limit +$sql .= $db->order($sortfield, $sortorder); +if ($limit) { + $sql .= $db->plimit($limit + 1, $offset); +} + +$resql = $db->query($sql); +if (!$resql) { + dol_print_error($db); + exit; +} + +$num = $db->num_rows($resql); + + +// Direct jump if only one record found +if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) { + $obj = $db->fetch_object($resql); + $id = $obj->rowid; + header("Location: ".DOL_URL_ROOT.'/asset/model/card.php?id='.$id); + exit; +} + + +// Output page +// -------------------------------------------------------------------- + +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); + +$arrayofselected = is_array($toselect) ? $toselect : array(); + +$param = ''; +if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { + $param .= '&contextpage='.urlencode($contextpage); +} +if ($limit > 0 && $limit != $conf->liste_limit) { + $param .= '&limit='.urlencode($limit); +} +foreach ($search as $key => $val) { + if (is_array($search[$key]) && count($search[$key])) { + foreach ($search[$key] as $skey) { + if ($skey != '') { + $param .= '&search_'.$key.'[]='.urlencode($skey); + } + } + } elseif ($search[$key] != '') { + $param .= '&search_'.$key.'='.urlencode($search[$key]); + } +} +if ($optioncss != '') { + $param .= '&optioncss='.urlencode($optioncss); +} +// Add $param from extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; +// Add $param from hooks +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook +$param .= $hookmanager->resPrint; + +// List of mass actions available +$arrayofmassactions = array( + //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"), + //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"), + //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), + //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), +); +if ($permissiontodelete) { + $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); +} +if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) { + $arrayofmassactions = array(); +} +$massactionbutton = $form->selectMassAction('', $arrayofmassactions); + +print '
    '."\n"; +if ($optioncss != '') { + print ''; +} +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; + +$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/asset/model/card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); + +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_'.$object->picto, 0, $newcardbutton, '', $limit, 0, 0, 1); + +// Add code for pre mass action (confirmation or email presend form) +$topicmail = "SendAssetModelRef"; +$modelmail = "assetmodel"; +$objecttmp = new AssetModel($db); +$trackid = 'assetmodel'.$object->id; +include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; + +if ($search_all) { + foreach ($fieldstosearchall as $key => $val) { + $fieldstosearchall[$key] = $langs->trans($val); + } + print '
    '.$langs->trans("FilterOnInto", $search_all).join(', ', $fieldstosearchall).'
    '; +} + +$moreforfilter = ''; +/*$moreforfilter.='
    '; +$moreforfilter.= $langs->trans('MyFilter') . ': '; +$moreforfilter.= '
    ';*/ + +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook +if (empty($reshook)) { + $moreforfilter .= $hookmanager->resPrint; +} else { + $moreforfilter = $hookmanager->resPrint; +} + +if (!empty($moreforfilter)) { + print '
    '; + print $moreforfilter; + print '
    '; +} + +$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; +$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields +$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); + +print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table +print ''."\n"; + + +// Fields title search +// -------------------------------------------------------------------- +print ''; +foreach ($object->fields as $key => $val) { + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); + if ($key == 'status') { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } elseif (in_array($val['type'], array('timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { + $cssforfield .= ($cssforfield ? ' ' : '').'right'; + } + if (!empty($arrayfields['t.'.$key]['checked'])) { + print ''; + } +} +// Extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; + +// Fields from hook +$parameters = array('arrayfields'=>$arrayfields); +$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +// Action column +print ''; +print ''."\n"; + + +// Fields title label +// -------------------------------------------------------------------- +print ''; +foreach ($object->fields as $key => $val) { + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); + if ($key == 'status') { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } elseif (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } elseif (in_array($val['type'], array('timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + } elseif (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $val['label'] != 'TechnicalID' && empty($val['arrayofkeyval'])) { + $cssforfield .= ($cssforfield ? ' ' : '').'right'; + } + if (!empty($arrayfields['t.'.$key]['checked'])) { + print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($cssforfield ? 'class="'.$cssforfield.'"' : ''), $sortfield, $sortorder, ($cssforfield ? $cssforfield.' ' : ''))."\n"; + } +} +// Extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; +// Hook fields +$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); +$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +// Action column +print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; +print ''."\n"; + + +// Detect if we need a fetch on each output line +$needToFetchEachLine = 0; +if (isset($extrafields->attributes[$object->table_element]['computed']) && is_array($extrafields->attributes[$object->table_element]['computed']) && count($extrafields->attributes[$object->table_element]['computed']) > 0) { + foreach ($extrafields->attributes[$object->table_element]['computed'] as $key => $val) { + if (preg_match('/\$object/', $val)) { + $needToFetchEachLine++; // There is at least one compute field that use $object + } + } +} + + +// Loop on record +// -------------------------------------------------------------------- +$i = 0; +$totalarray = array(); +$totalarray['nbfield'] = 0; +while ($i < ($limit ? min($num, $limit) : $num)) { + $obj = $db->fetch_object($resql); + if (empty($obj)) { + break; // Should not happen + } + + // Store properties in $object + $object->setVarsFromFetchObj($obj); + + // Show here line of result + print ''; + foreach ($object->fields as $key => $val) { + $cssforfield = (empty($val['csslist']) ? (empty($val['css']) ? '' : $val['css']) : $val['csslist']); + if (in_array($val['type'], array('date', 'datetime', 'timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } elseif ($key == 'status') { + $cssforfield .= ($cssforfield ? ' ' : '').'center'; + } + + if (in_array($val['type'], array('timestamp'))) { + $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + } elseif ($key == 'ref') { + $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + } + + if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'status')) && empty($val['arrayofkeyval'])) { + $cssforfield .= ($cssforfield ? ' ' : '').'right'; + } + //if (in_array($key, array('fk_soc', 'fk_user', 'fk_warehouse'))) $cssforfield = 'tdoverflowmax100'; + + if (!empty($arrayfields['t.'.$key]['checked'])) { + print ''; + if ($key == 'status') { + print $object->getLibStatut(5); + } elseif ($key == 'rowid') { + print $object->showOutputField($val, $key, $object->id, ''); + } else { + print $object->showOutputField($val, $key, $object->$key, ''); + } + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + if (!empty($val['isameasure']) && $val['isameasure'] == 1) { + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; + } + if (!isset($totalarray['val'])) { + $totalarray['val'] = array(); + } + if (!isset($totalarray['val']['t.'.$key])) { + $totalarray['val']['t.'.$key] = 0; + } + $totalarray['val']['t.'.$key] += $object->$key; + } + } + } + // Extra fields + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; + // Fields from hook + $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + // Action column + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + + print ''."\n"; + + $i++; +} + +// Show total line +include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; + +// If no record found +if ($num == 0) { + $colspan = 1; + foreach ($arrayfields as $key => $val) { + if (!empty($val['checked'])) { + $colspan++; + } + } + print ''; +} + + +$db->free($resql); + +$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql); +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; + +print '
    '; + if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { + print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1); + } elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) { + print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', 'maxwidth125', 1); + } elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) { + print '
    '; + print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
    '; + print '
    '; + print $form->selectDate($search[$key.'_dtend'] ? $search[$key.'_dtend'] : '', "search_".$key."_dtend", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
    '; + } elseif ($key == 'lang') { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; + $formadmin = new FormAdmin($db); + print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2); + } else { + print ''; + } + print '
    '; +$searchpicto = $form->showFilterButtons(); +print $searchpicto; +print '
    '; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($object->id, $arrayofselected)) { + $selected = 1; + } + print ''; + } + print '
    '.$langs->trans("NoRecordFound").'
    '."\n"; +print '
    '."\n"; + +print '
    '."\n"; + +if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) { + $hidegeneratedfilelistifempty = 1; + if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) { + $hidegeneratedfilelistifempty = 0; + } + + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; + $formfile = new FormFile($db); + + // Show list of available documents + $urlsource = $_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder; + $urlsource .= str_replace('&', '&', $param); + + $filedir = $diroutputmassaction; + $genallowed = $permissiontoread; + $delallowed = $permissiontoadd; + + print $formfile->showdocuments('massfilesarea_asset', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/model/note.php b/htdocs/asset/model/note.php new file mode 100644 index 00000000000..8c88feba449 --- /dev/null +++ b/htdocs/asset/model/note.php @@ -0,0 +1,120 @@ + + * Copyright (C) 2018 Alexandre Spangaro + * + * 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 . + */ + +/** + * \file htdocs/asset/model/note.php + * \ingroup asset + * \brief Card with notes on Asset Model + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT . '/core/lib/asset.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/asset/class/assetmodel.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("assets", "companies")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +// Initialize technical objects +$object = new AssetModel($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->asset->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('assetmodelnote', '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->asset->multidir_output[$object->entity] . "/" . $object->id; +} + +$permissiontoread = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->read) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->model_advance->read))); +$permissiontoadd = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $user->rights->asset->write) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->asset->model_advance->write))); // Used by the include of actions_addupdatedelete.inc.php +$permissionnote = $permissiontoadd; // Used by the include of actions_setnotes.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +if ($user->socid > 0) $socid = $user->socid; +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, 'asset', $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + + +/* + * Actions + */ + +$reshook = $hookmanager->executeHooks('doActions', array(), $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} +if (empty($reshook)) { + include DOL_DOCUMENT_ROOT . '/core/actions_setnotes.inc.php'; // Must be include, not include_once +} + + +/* + * View + */ + +$form = new Form($db); + +$help_url = ''; +llxHeader('', $langs->trans('AssetModel'), $help_url); + +if ($id > 0 || !empty($ref)) { + $object->fetch_thirdparty(); + + $head = assetModelPrepareHead($object); + + print dol_get_fiche_head($head, 'note', $langs->trans("AssetModel"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
    '; + print '
    '; + + + $cssclass = "titlefield"; + include DOL_DOCUMENT_ROOT . '/core/tpl/notes.tpl.php'; + + print '
    '; + + print dol_get_fiche_end(); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/asset/note.php b/htdocs/asset/note.php index ebd340e393d..8de86d49bb7 100644 --- a/htdocs/asset/note.php +++ b/htdocs/asset/note.php @@ -27,7 +27,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/asset.lib.php'; require_once DOL_DOCUMENT_ROOT.'/asset/class/asset.class.php'; // Load translation files required by the page -$langs->loadLangs(array("asset", "companies")); +$langs->loadLangs(array("assets", "companies")); // Get parameters $id = GETPOST('id', 'int'); @@ -40,30 +40,24 @@ $backtopage = GETPOST('backtopage', 'alpha'); $object = new Asset($db); $extrafields = new ExtraFields($db); $diroutputmassaction = $conf->asset->dir_output.'/temp/massgeneration/'.$user->id; -$hookmanager->initHooks(array('assetnote')); // Note that conf->hooks_modules contains array - +$hookmanager->initHooks(array('assetnote', 'globalcard')); // Note that conf->hooks_modules contains array // Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); -// Security check - Protection if external user -//if ($user->socid > 0) accessforbidden(); -//if ($user->socid > 0) $socid = $user->socid; -//$result = restrictedArea($user, 'asset', $id); - // 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->asset->multidir_output[$object->entity]."/".$object->id; } -// Security check -if (!empty($user->socid)) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'asset', $id); +$permissionnote = $user->rights->asset->write; // Used by the include of actions_setnotes.inc.php +$permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php -$permissionnote = 1; -//$permissionnote=$user->rights->asset->creer; // Used by the include of actions_setnotes.inc.php +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->asset->enabled)) accessforbidden(); /* @@ -78,67 +72,28 @@ if (empty($reshook)) { include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once } + /* * View */ $form = new Form($db); -//$help_url='EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes'; $help_url = ''; -llxHeader('', $langs->trans('Assets'), $help_url); +llxHeader('', $langs->trans('Asset'), $help_url); if ($id > 0 || !empty($ref)) { $object->fetch_thirdparty(); - $head = asset_prepare_head($object); + $head = assetPrepareHead($object); - print dol_get_fiche_head($head, 'note', $langs->trans("Asset"), -1, 'generic'); + print dol_get_fiche_head($head, 'note', $langs->trans("Asset"), -1, $object->picto); // Object card // ------------------------------------------------------------ - $linkback = ''.$langs->trans("BackToList").''; + $linkback = '' . $langs->trans("BackToList") . ''; $morehtmlref = '
    '; - /* - // 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.='
    '.$langs->trans('ThirdParty') . ' : ' . $object->thirdparty->getNomUrl(1); - // Project - if (! empty($conf->projet->enabled)) - { - $langs->load("projects"); - $morehtmlref.='
    '.$langs->trans('Project') . ' '; - if ($user->rights->asset->creer) - { - if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - $morehtmlref.=' : '; - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref.='
    '; - $morehtmlref.=''; - $morehtmlref.=''; - $morehtmlref.=$formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref.=''; - $morehtmlref.='
    '; - } else { - $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); - } - } else { - if (! empty($object->fk_project)) { - $proj = new Project($db); - $proj->fetch($object->fk_project); - $morehtmlref.=''; - $morehtmlref.=$proj->ref; - $morehtmlref.=''; - } else { - $morehtmlref.=''; - } - } - }*/ $morehtmlref .= '
    '; @@ -150,7 +105,7 @@ if ($id > 0 || !empty($ref)) { $cssclass = "titlefield"; - include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; + include DOL_DOCUMENT_ROOT . '/core/tpl/notes.tpl.php'; print ''; diff --git a/htdocs/asset/tpl/accountancy_codes_edit.tpl.php b/htdocs/asset/tpl/accountancy_codes_edit.tpl.php new file mode 100644 index 00000000000..bbd2b3d797c --- /dev/null +++ b/htdocs/asset/tpl/accountancy_codes_edit.tpl.php @@ -0,0 +1,81 @@ + + * + * 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 . + * + * Show extrafields. It also show fields from hook formAssetAccountancyCode. Need to have following variables defined: + * $object (asset, assetmodel, ...) + * $assetaccountancycodes + * $action + * $conf + * $langs + * + * $parameters + */ + +// Protection to avoid direct call of template +if (empty($object) || !is_object($object)) { + print "Error, template page can't be called as URL"; + exit; +} + +if (!is_object($form)) { + $form = new Form($db); +} + +if (!empty($conf->accounting->enabled) && !is_object($formaccounting)) { + require_once DOL_DOCUMENT_ROOT . '/core/class/html.formaccounting.class.php'; + $formaccounting = new FormAccounting($db); +} + + +?> + +executeHooks('formAssetAccountancyCodes', $parameters, $object, $action); +print $hookmanager->resPrint; +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + foreach ($assetaccountancycodes->accountancy_codes_fields as $mode_key => $mode_info) { + //if (empty($object->enabled_modes[$mode_key])) continue; + + print load_fiche_titre($langs->trans($mode_info['label']), '', ''); + print '
    '; + print '
    '; + print ''; + foreach ($mode_info['fields'] as $field_key => $field_info) { + $html_name = $mode_key . '_' . $field_key; + print ''; + } + print '
    ' . $langs->trans($field_info['label']) . ''; + $accountancy_code = GETPOSTISSET($html_name) ? GETPOST($html_name, 'aZ09') : (!empty($assetaccountancycodes->accountancy_codes[$mode_key][$field_key]) ? $assetaccountancycodes->accountancy_codes[$mode_key][$field_key] : ''); + if (!empty($conf->accounting->enabled)) { + print $formaccounting->select_account($accountancy_code, $html_name, 1, null, 1, 1, 'minwidth150 maxwidth300', 1); + } else { + print ''; + } + print '
    '; + print '
    '; + } +} +?> + diff --git a/htdocs/asset/tpl/accountancy_codes_view.tpl.php b/htdocs/asset/tpl/accountancy_codes_view.tpl.php new file mode 100644 index 00000000000..0d92ad8eb37 --- /dev/null +++ b/htdocs/asset/tpl/accountancy_codes_view.tpl.php @@ -0,0 +1,82 @@ + + * + * 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 . + * + * Show extrafields. It also show fields from hook formAssetAccountancyCode. Need to have following variables defined: + * $object (asset, assetmodel, ...) + * $assetaccountancycodes + * $action + * $conf + * $langs + * + * $parameters + */ + +// Protection to avoid direct call of template +if (empty($object) || !is_object($object)) { + print "Error, template page can't be called as URL"; + exit; +} + +if (!is_object($form)) { + $form = new Form($db); +} + + +?> + +executeHooks('formAssetAccountancyCodes', $parameters, $object, $action); +print $hookmanager->resPrint; +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + if (!empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingaccount.class.php'; + + foreach ($assetaccountancycodes->accountancy_codes_fields as $mode_key => $mode_info) { + //if (empty($object->enabled_modes[$mode_key])) continue; + + print load_fiche_titre($langs->trans($mode_info['label']), '', ''); + print '
    '; + print '
    '; + print ''; + foreach ($mode_info['fields'] as $field_key => $field_info) { + print ''; + } + print '
    ' . $langs->trans($field_info['label']) . ''; + if (!empty($assetaccountancycodes->accountancy_codes[$mode_key][$field_key])) { + $accountancy_code = $assetaccountancycodes->accountancy_codes[$mode_key][$field_key]; + if (!empty($conf->accounting->enabled)) { + $accountingaccount = new AccountingAccount($db); + $accountingaccount->fetch('', $accountancy_code, 1); + + print $accountingaccount->getNomUrl(0, 1, 1, '', 1); + } else { + print $accountancy_code; + } + } + print '
    '; + print '
    '; + } +} +?> + diff --git a/htdocs/asset/tpl/depreciation_options_edit.tpl.php b/htdocs/asset/tpl/depreciation_options_edit.tpl.php new file mode 100644 index 00000000000..cef22936260 --- /dev/null +++ b/htdocs/asset/tpl/depreciation_options_edit.tpl.php @@ -0,0 +1,228 @@ + + * + * 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 . + * + * Show extrafields. It also show fields from hook formAssetAccountancyCode. Need to have following variables defined: + * $object (asset, assetmodel, ...) + * $assetaccountancycodes + * $action + * $conf + * $langs + * + * $parameters + */ + +// Protection to avoid direct call of template +if (empty($object) || !is_object($object)) { + print "Error, template page can't be called as URL"; + exit; +} + +if (!is_object($form)) { + $form = new Form($db); +} + +if (!is_object($formadmin)) { + require_once DOL_DOCUMENT_ROOT . '/core/class/html.formadmin.class.php'; + $formadmin = new FormAdmin($db); +} + + +?> + +executeHooks('formAssetDeprecationOptions', $parameters, $object, $action); +print $hookmanager->resPrint; +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + $class_type = get_class($object) == 'Asset' ? 0 : 1; + foreach ($assetdepreciationoptions->deprecation_options_fields as $mode_key => $mode_info) { + if (!empty($mode_info['enabled_field'])) { + $info = explode(':', $mode_info['enabled_field']); + $enabled_field_info[] = array( + 'mode_key' => $info[0], + 'field_key' => $info[1], + 'value' => $info[2], + 'target' => 'block_' . $mode_key, + ); + } + + $assetdepreciationoptions->setInfosForMode($mode_key, $class_type, true); + $prefix_html_name = $mode_key . '_'; + + print '
    '; + print load_fiche_titre($langs->trans($mode_info['label']), '', ''); + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + $mode_info['fields'] = dol_sort_array($mode_info['fields'], 'position'); + foreach ($mode_info['fields'] as $field_key => $field_info) { + // Discard if extrafield is a hidden field on form + if (abs($field_info['visible']) != 1 && abs($field_info['visible']) != 3 && abs($field_info['visible']) != 4) { + continue; + } + if (array_key_exists('enabled', $field_info) && isset($field_info['enabled']) && !verifCond($field_info['enabled'])) { + continue; // We don't want this field + } + if (!empty($field_info['column_break'])) { + print '
    '; + + // We close div and reopen for second column + print '
    '; + print '
    '; + + print '
    '; + print ''; + } + + $html_name = $prefix_html_name . $field_key; + if (!empty($field_info['enabled_field'])) { + $info = explode(':', $field_info['enabled_field']); + $enabled_field_info[] = array( + 'mode_key' => $info[0], + 'field_key' => $info[1], + 'value' => $info[2], + 'target' => 'field_' . $html_name, + ); + } + + $more_class = ''; + if (!empty($field_info['required']) || (isset($field_info['notnull']) && $field_info['notnull'] > 0)) { + $more_class .= ' fieldrequired'; + } + if (preg_match('/^(text|html)/', $val['type'])) { + $more_class .= ' tdtop'; + } + + print ''; + if (!empty($field_info['help'])) { + print $form->textwithpicto($langs->trans($field_info['label']), $langs->trans($field_info['help'])); + } else { + print $langs->trans($field_info['label']); + } + print ''; + print ''; + print ''; + } + print '
    '; + if (!empty($field_info['picto'])) { + print img_picto('', $field_info['picto'], '', false, 0, 0, '', 'pictofixedwidth'); + } + if (in_array($field_info['type'], array('int', 'integer'))) { + $value = GETPOSTISSET($html_name) ?GETPOST($html_name, 'int') : $assetdepreciationoptions->$field_key; + } elseif ($field_info['type'] == 'double') { + $value = GETPOSTISSET($html_name) ? price2num(GETPOST($html_name, 'alphanohtml')) : $assetdepreciationoptions->$field_key; + } elseif (preg_match('/^(text|html)/', $field_info['type'])) { + $tmparray = explode(':', $field_info['type']); + if (!empty($tmparray[1])) { + $check = $tmparray[1]; + } else { + $check = 'restricthtml'; + } + $value = GETPOSTISSET($html_name) ? GETPOST($html_name, $check) : $assetdepreciationoptions->$field_key; + } elseif ($field_info['type'] == 'price') { + $value = GETPOSTISSET($html_name) ? price2num(GETPOST($html_name)) : ($assetdepreciationoptions->$field_key ? price2num($assetdepreciationoptions->$field_key) : (!empty($field_info['default']) ? dol_eval($field_info['default'], 1) : 0)); + } elseif ($field_key == 'lang') { + $value = GETPOSTISSET($html_name) ? GETPOST($html_name, 'aZ09') : $assetdepreciationoptions->lang; + } else { + $value = GETPOSTISSET($html_name) ? GETPOST($html_name, 'alpha') : $assetdepreciationoptions->$field_key; + } + if (!empty($field_info['noteditable'])) { + print $assetdepreciationoptions->showOutputField($field_info, $field_key, $value, '', '', $prefix_html_name, 0); + } else { + if ($field_key == 'lang') { + print img_picto('', 'language', 'class="pictofixedwidth"'); + print $formadmin->select_language($value, $html_name, 0, null, 1, 0, 0, 'minwidth300', 2); + } else { + print $assetdepreciationoptions->showInputField($field_info, $field_key, $value, '', '', $prefix_html_name, 0); + } + } + print '
    '; + print '
    '; + print '
    '; + print '
    '; + print '
    '; + } +} + +if (!empty($enabled_field_info)) { + $enabled_field_info = json_encode($enabled_field_info); + print << +SCRIPT; +} + +?> + diff --git a/htdocs/asset/tpl/depreciation_options_view.tpl.php b/htdocs/asset/tpl/depreciation_options_view.tpl.php new file mode 100644 index 00000000000..2660fbbaee7 --- /dev/null +++ b/htdocs/asset/tpl/depreciation_options_view.tpl.php @@ -0,0 +1,154 @@ + + * + * 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 . + * + * Show extrafields. It also show fields from hook formAssetAccountancyCode. Need to have following variables defined: + * $object (asset, assetmodel, ...) + * $assetaccountancycodes + * $action + * $conf + * $langs + * + * $parameters + */ + +// Protection to avoid direct call of template +if (empty($object) || !is_object($object)) { + print "Error, template page can't be called as URL"; + exit; +} + +if (!is_object($form)) { + $form = new Form($db); +} + + +?> + +executeHooks('formAssetDeprecationOptions', $parameters, $object, $action); +print $hookmanager->resPrint; +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + $class_type = get_class($object) == 'Asset' ? 0 : 1; + foreach ($assetdepreciationoptions->deprecation_options_fields as $mode_key => $mode_info) { + if (!empty($mode_info['enabled_field'])) { + $info = explode(':', $mode_info['enabled_field']); + if ($assetdepreciationoptions->deprecation_options[$info[0]][$info[1]] != $info[2]) { + continue; + } + } + + $assetdepreciationoptions->setInfosForMode($mode_key, $class_type, true); + + print load_fiche_titre($langs->trans($mode_info['label']), '', ''); + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + $mode_info['fields'] = dol_sort_array($mode_info['fields'], 'position'); + foreach ($mode_info['fields'] as $field_key => $field_info) { + if (!empty($field_info['enabled_field'])) { + $info = explode(':', $field_info['enabled_field']); + if ($assetdepreciationoptions->deprecation_options[$info[0]][$info[1]] != $info[2]) { + continue; + } + } + // Discard if extrafield is a hidden field on form + if (abs($field_info['visible']) != 1 && abs($field_info['visible']) != 3 && abs($field_info['visible']) != 4 && abs($field_info['visible']) != 5) { + continue; + } + if (array_key_exists('enabled', $field_info) && isset($field_info['enabled']) && !verifCond($field_info['enabled'])) { + continue; // We don't want this field + } + if (!empty($field_info['column_break'])) { + print '
    '; + + // We close div and reopen for second column + print '
    '; + print '
    '; + + print '
    '; + print ''; + } + + $key = $mode_key . '_' . $field_key; + $value = $assetdepreciationoptions->deprecation_options[$mode_key][$field_key]; + + print ''; + if (!empty($field_info['help'])) { + print $form->textwithpicto($langs->trans($field_info['label']), $langs->trans($field_info['help'])); + } else { + if (isset($field_info['copytoclipboard']) && $field_info['copytoclipboard'] == 1) { + print showValueWithClipboardCPButton($value, 0, $langs->transnoentitiesnoconv($field_info['label'])); + } else { + print $langs->trans($field_info['label']); + } + } + print ''; + print ''; + print ''; + } + print '
    '; + if (in_array($field_info['type'], array('text', 'html'))) { + print '
    '; + } + if ($field_key == 'lang') { + $langs->load("languages"); + $labellang = ($value ? $langs->trans('Language_' . $value) : ''); + print picto_from_langcode($value, 'class="paddingrightonly saturatemedium opacitylow"'); + print $labellang; + } else { + if (isset($field_info['copytoclipboard']) && $field_info['copytoclipboard'] == 2) { + $out = $assetdepreciationoptions->showOutputField($field_info, $field_key, $value, '', '', $mode_key . '_', 0); + print showValueWithClipboardCPButton($out, 0, $out); + } else { + print $assetdepreciationoptions->showOutputField($field_info, $field_key, $value, '', '', $mode_key . '_', 0); + } + } + if (in_array($field_info['type'], array('text', 'html'))) { + print '
    '; + } + print '
    '; + print '
    '; + print '
    '; + print '
    '; + } +} + +?> + diff --git a/htdocs/asset/tpl/depreciation_view.tpl.php b/htdocs/asset/tpl/depreciation_view.tpl.php new file mode 100644 index 00000000000..2660fbbaee7 --- /dev/null +++ b/htdocs/asset/tpl/depreciation_view.tpl.php @@ -0,0 +1,154 @@ + + * + * 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 . + * + * Show extrafields. It also show fields from hook formAssetAccountancyCode. Need to have following variables defined: + * $object (asset, assetmodel, ...) + * $assetaccountancycodes + * $action + * $conf + * $langs + * + * $parameters + */ + +// Protection to avoid direct call of template +if (empty($object) || !is_object($object)) { + print "Error, template page can't be called as URL"; + exit; +} + +if (!is_object($form)) { + $form = new Form($db); +} + + +?> + +executeHooks('formAssetDeprecationOptions', $parameters, $object, $action); +print $hookmanager->resPrint; +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + $class_type = get_class($object) == 'Asset' ? 0 : 1; + foreach ($assetdepreciationoptions->deprecation_options_fields as $mode_key => $mode_info) { + if (!empty($mode_info['enabled_field'])) { + $info = explode(':', $mode_info['enabled_field']); + if ($assetdepreciationoptions->deprecation_options[$info[0]][$info[1]] != $info[2]) { + continue; + } + } + + $assetdepreciationoptions->setInfosForMode($mode_key, $class_type, true); + + print load_fiche_titre($langs->trans($mode_info['label']), '', ''); + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + $mode_info['fields'] = dol_sort_array($mode_info['fields'], 'position'); + foreach ($mode_info['fields'] as $field_key => $field_info) { + if (!empty($field_info['enabled_field'])) { + $info = explode(':', $field_info['enabled_field']); + if ($assetdepreciationoptions->deprecation_options[$info[0]][$info[1]] != $info[2]) { + continue; + } + } + // Discard if extrafield is a hidden field on form + if (abs($field_info['visible']) != 1 && abs($field_info['visible']) != 3 && abs($field_info['visible']) != 4 && abs($field_info['visible']) != 5) { + continue; + } + if (array_key_exists('enabled', $field_info) && isset($field_info['enabled']) && !verifCond($field_info['enabled'])) { + continue; // We don't want this field + } + if (!empty($field_info['column_break'])) { + print '
    '; + + // We close div and reopen for second column + print '
    '; + print '
    '; + + print '
    '; + print ''; + } + + $key = $mode_key . '_' . $field_key; + $value = $assetdepreciationoptions->deprecation_options[$mode_key][$field_key]; + + print ''; + if (!empty($field_info['help'])) { + print $form->textwithpicto($langs->trans($field_info['label']), $langs->trans($field_info['help'])); + } else { + if (isset($field_info['copytoclipboard']) && $field_info['copytoclipboard'] == 1) { + print showValueWithClipboardCPButton($value, 0, $langs->transnoentitiesnoconv($field_info['label'])); + } else { + print $langs->trans($field_info['label']); + } + } + print ''; + print ''; + print ''; + } + print '
    '; + if (in_array($field_info['type'], array('text', 'html'))) { + print '
    '; + } + if ($field_key == 'lang') { + $langs->load("languages"); + $labellang = ($value ? $langs->trans('Language_' . $value) : ''); + print picto_from_langcode($value, 'class="paddingrightonly saturatemedium opacitylow"'); + print $labellang; + } else { + if (isset($field_info['copytoclipboard']) && $field_info['copytoclipboard'] == 2) { + $out = $assetdepreciationoptions->showOutputField($field_info, $field_key, $value, '', '', $mode_key . '_', 0); + print showValueWithClipboardCPButton($out, 0, $out); + } else { + print $assetdepreciationoptions->showOutputField($field_info, $field_key, $value, '', '', $mode_key . '_', 0); + } + } + if (in_array($field_info['type'], array('text', 'html'))) { + print '
    '; + } + print '
    '; + print '
    '; + print '
    '; + print '
    '; + } +} + +?> + diff --git a/htdocs/asset/tpl/linkedobjectblock.tpl.php b/htdocs/asset/tpl/linkedobjectblock.tpl.php new file mode 100644 index 00000000000..aef30995432 --- /dev/null +++ b/htdocs/asset/tpl/linkedobjectblock.tpl.php @@ -0,0 +1,81 @@ + + * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2014 Marcos García + * + * 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 . + */ + +// Protection to avoid direct call of template +if (empty($conf) || !is_object($conf)) { + print "Error, template page can't be called as URL"; + exit; +} + +print "\n"; + +global $user; +global $noMoreLinkedObjectBlockAfter; + +$langs = $GLOBALS['langs']; +$linkedObjectBlock = $GLOBALS['linkedObjectBlock']; + +// Load translation files required by the page +$langs->load("assets"); + +$linkedObjectBlock = dol_sort_array($linkedObjectBlock, 'date', 'desc', 0, 0, 1); + +$total = 0; +$ilink = 0; +foreach ($linkedObjectBlock as $key => $objectlink) { + $ilink++; + + $trclass = 'oddeven'; + if ($ilink == count($linkedObjectBlock) && empty($noMoreLinkedObjectBlockAfter) && count($linkedObjectBlock) <= 1) { + $trclass .= ' liste_sub_total'; + } + echo '
    '.$langs->trans("Asset"); + if (!empty($showImportButton) && !empty($conf->global->MAIN_ENABLE_IMPORT_LINKED_OBJECT_LINES)) { + print ' '; + echo ''.$objectlink->getNomUrl(1).''.$objectlink->label.''.dol_print_date($objectlink->date_start, 'day').''; + if ($user->rights->asset->read) { + $total = $total + $objectlink->acquisition_value_ht; + echo price($objectlink->acquisition_value_ht); + } + echo ''.$objectlink->getLibStatut(3).''; + echo ''.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink').''; + echo '
    '.$langs->trans("Total").''.price($total).'
    '."\n"; - - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; - - $assettype = new AssetType($db); - - while ($i < $num) { - $objp = $db->fetch_object($result); - - $assettype->id = $objp->rowid; - $assettype->ref = $objp->rowid; - $assettype->label = $objp->rowid; - - print ''; - print ''; - print ''; - - print ''; - - print ''; - - print ''; - - if ($user->rights->asset->write) { - print ''; - } else { - print ''; - } - print ""; - $i++; - } - - // If no record found - if ($num == 0) { - $colspan = 6; - print ''; - } - - print "
    '.$langs->trans("Ref").''.$langs->trans("Label").''.$langs->trans("AccountancyCodeAsset").''.$langs->trans("AccountancyCodeDepreciationAsset").''.$langs->trans("AccountancyCodeDepreciationExpense").' 
    '; - print $assettype->getNomUrl(1); - //'.img_object($langs->trans("ShowType"),'group').' '.$objp->rowid.' - print ''.dol_escape_htmltag($objp->label).''; - if (!empty($conf->accounting->enabled)) { - $accountingaccount = new AccountingAccount($db); - $accountingaccount->fetch('', $objp->accountancy_code_asset, 1); - - print $accountingaccount->getNomUrl(0, 1, 1, '', 0); - } else { - print $objp->accountancy_code_asset; - } - print ''; - if (!empty($conf->accounting->enabled)) { - $accountingaccount2 = new AccountingAccount($db); - $accountingaccount2->fetch('', $objp->accountancy_code_depreciation_asset, 1); - - print $accountingaccount2->getNomUrl(0, 1, 1, '', 0); - } else { - print $objp->accountancy_code_depreciation_asset; - } - print ''; - if (!empty($conf->accounting->enabled)) { - $accountingaccount3 = new AccountingAccount($db); - $accountingaccount3->fetch('', $objp->accountancy_code_depreciation_expense, 1); - - print $accountingaccount3->getNomUrl(0, 1, 1, '', 0); - } else { - print $objp->accountancy_code_depreciation_expense; - } - print 'rowid.'">'.img_edit().' 
    '.$langs->trans("NoRecordFound").'
    "; - print '
    '; - - print ''; - } else { - dol_print_error($db); - } -} - - -/* ************************************************************************** */ -/* */ -/* Creation mode */ -/* */ -/* ************************************************************************** */ -if ($action == 'create') { - $object = new AssetType($db); - if (!empty($conf->accounting->enabled)) { - $formaccounting = new FormAccounting($db); - } - - print load_fiche_titre($langs->trans("NewAssetType"), '', $object->picto); - - print '
    '; - print ''; - print ''; - - print dol_get_fiche_head(''); - - print ''; - print ''; - - print ''; - - if (!empty($conf->accounting->enabled)) { - // Accountancy_code_asset - print ''; - print ''; - - // Accountancy_code_depreciation_expense - print ''; - print ''; - - // Accountancy_code_depreciation_expense - print ''; - print ''; - } else // For external software - { - // Accountancy_code_asset - print ''; - print ''; - - // Accountancy_code_depreciation_asset - print ''; - print ''; - - // Accountancy_code_depreciation_expense - print ''; - print ''; - } - - print ''; - - // Other attributes - $parameters = array(); - $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (empty($reshook)) { - print $object->showOptionals($extrafields, 'create', $parameters); - } - print ''; - print "
    '.$langs->trans("Label").'
    '.$langs->trans("AccountancyCodeAsset").''; - print $formaccounting->select_account($object->accountancy_code_asset, 'accountancy_code_asset', 1, '', 1, 1); - print '
    '.$langs->trans("AccountancyCodeDepreciationAsset").''; - print $formaccounting->select_account($object->accountancy_code_depreciation_asset, 'accountancy_code_depreciation_asset', 1, '', 1, 1); - print '
    '.$langs->trans("AccountancyCodeDepreciationExpense").''; - print $formaccounting->select_account($object->accountancy_code_depreciation_expense, 'accountancy_code_depreciation_expense', 1, '', 1, 1); - print '
    '.$langs->trans("AccountancyCodeAsset").''; - print '
    '.$langs->trans("AccountancyCodeDepreciationAsset").''; - print '
    '.$langs->trans("AccountancyCodeDepreciationExpense").''; - print '
    '.$langs->trans("Description").''; - print '
    \n"; - - print dol_get_fiche_end(); - - print $form->buttonsSaveCancel("Add"); - - print "
    \n"; -} - -/* ************************************************************************** */ -/* */ -/* View mode */ -/* */ -/* ************************************************************************** */ -if ($rowid > 0) { - if ($action != 'edit') { - $object = new AssetType($db); - $object->fetch($rowid); - $object->fetch_optionals(); - - /* - * Confirmation suppression - */ - if ($action == 'delete') { - print $form->formconfirm($_SERVER['PHP_SELF']."?rowid=".$object->id, $langs->trans("DeleteAnAssetType"), $langs->trans("ConfirmDeleteAssetType", $object->label), "confirm_delete", '', 0, 1); - } - - $head = asset_type_prepare_head($object); - - print dol_get_fiche_head($head, 'card', $langs->trans("AssetType"), -1, 'asset'); - - $linkback = ''.$langs->trans("BackToList").''; - - $morehtmlref = '
    '; - // Ref asset type - $morehtmlref .= $form->editfieldkey("Label", 'label', $object->label, $object, $user->rights->asset->write, 'string', '', 0, 1); - $morehtmlref .= $form->editfieldval("Label", 'label', $object->label, $object, $user->rights->asset->write, 'string', '', null, null, '', 1); - $morehtmlref .= '
    '; - - dol_banner_tab($object, 'rowid', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlright); - - print '
    '; - print '
    '; - - print ''; - - print ''; - print ''; - print ''; - - print ''; - print ''; - print ''; - - print ''; - print ''; - print ''; - - print '"; - - // Other attributes - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; - - print '
    '; - print $langs->trans("AccountancyCodeAsset"); - print ''; - if (!empty($conf->accounting->enabled)) { - $accountingaccount = new AccountingAccount($db); - $accountingaccount->fetch('', $object->accountancy_code_asset, 1); - - print $accountingaccount->getNomUrl(0, 1, 1, '', 1); - } else { - print $object->accountancy_code_asset; - } - print '
    '; - print $langs->trans("AccountancyCodeDepreciationAsset"); - print ''; - if (!empty($conf->accounting->enabled)) { - $accountingaccount2 = new AccountingAccount($db); - $accountingaccount2->fetch('', $object->accountancy_code_depreciation_asset, 1); - - print $accountingaccount2->getNomUrl(0, 1, 1, '', 1); - } else { - print $object->accountancy_code_depreciation_asset; - } - print '
    '; - print $langs->trans("AccountancyCodeDepreciationExpense"); - print ''; - if (!empty($conf->accounting->enabled)) { - $accountingaccount3 = new AccountingAccount($db); - $accountingaccount3->fetch('', $object->accountancy_code_depreciation_expense, 1); - - print $accountingaccount3->getNomUrl(0, 1, 1, '', 1); - } else { - print $object->accountancy_code_depreciation_expense; - } - print '
    '.$langs->trans("Description").''; - print nl2br($object->note)."
    '; - print '
    '; - - print dol_get_fiche_end(); - - /* - * Buttons - */ - - print '
    '; - - // Edit - if ($user->rights->asset->write) { - print ''; - } - - // Delete - if ($user->rights->asset->write) { - print ''; - } - - print "
    "; - } - - /* ************************************************************************** */ - /* */ - /* Edition mode */ - /* */ - /* ************************************************************************** */ - - if ($action == 'edit') { - $object = new AssetType($db); - $object->fetch($rowid); - $object->fetch_optionals(); - if (!empty($conf->accounting->enabled)) { - $formaccounting = new FormAccounting($db); - } - - $head = asset_type_prepare_head($object); - - print '
    '; - print ''; - print ''; - print ''; - - print dol_get_fiche_head($head, 'card', $langs->trans("AssetsType"), -1, 'setup'); - - print ''; - - print ''; - - print ''; - - if (!empty($conf->accounting->enabled)) { - // Accountancy_code_asset - print ''; - print ''; - - // Accountancy_code_depreciation_expense - print ''; - print ''; - - // Accountancy_code_depreciation_expense - print ''; - print ''; - } else // For external software - { - // Accountancy_code_asset - print ''; - print ''; - - // Accountancy_code_depreciation_asset - print ''; - print ''; - - // Accountancy_code_depreciation_expense - print ''; - print ''; - } - - print ''; - - // Other attributes - $parameters = array(); - $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $act, $action); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (empty($reshook)) { - print $object->showOptionals($extrafields, 'edit', $parameters); - } - - // Other attributes - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; - - print '
    '.$langs->trans("Ref").''.$object->id.'
    '.$langs->trans("Label").'
    '.$langs->trans("AccountancyCodeAsset").''; - print $formaccounting->select_account($object->accountancy_code_asset, 'accountancy_code_asset', 1, '', 1, 1); - print '
    '.$langs->trans("AccountancyCodeDepreciationAsset").''; - print $formaccounting->select_account($object->accountancy_code_depreciation_asset, 'accountancy_code_depreciation_asset', 1, '', 1, 1); - print '
    '.$langs->trans("AccountancyCodeDepreciationExpense").''; - print $formaccounting->select_account($object->accountancy_code_depreciation_expense, 'accountancy_code_depreciation_expense', 1, '', 1, 1); - print '
    '.$langs->trans("AccountancyCodeAsset").''; - print '
    '.$langs->trans("AccountancyCodeDepreciationAsset").''; - print '
    '.$langs->trans("AccountancyCodeDepreciationExpense").''; - print '
    '.$langs->trans("Description").''; - print '
    '; - - print dol_get_fiche_end(); - - print $form->buttonsSaveCancel(); - - print "
    "; - } -} - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/barcode/codeinit.php b/htdocs/barcode/codeinit.php index ef3c23eff2b..1a5f99b27ee 100644 --- a/htdocs/barcode/codeinit.php +++ b/htdocs/barcode/codeinit.php @@ -286,7 +286,7 @@ if ($conf->product->enabled || $conf->product->service) { print ''; $moretags2 = (($nbno == $nbtotal) ? ' disabled' : ''); print '   '; - print ''; + print ''; print '



    '; } diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php index 8663d50e66a..763463d6fb8 100644 --- a/htdocs/barcode/printsheet.php +++ b/htdocs/barcode/printsheet.php @@ -23,7 +23,7 @@ * \brief Page to print sheets with barcodes using the document templates into core/modules/printsheets */ -if (!empty($_POST['mode']) && $_POST['mode'] === 'label') { // Page is called to build a PDF and output, we must ne renew the token. +if (!empty($_POST['mode']) && $_POST['mode'] === 'label') { // Page is called to build a PDF and output, we must not renew the token. if (!defined('NOTOKENRENEWAL')) { define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) } diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php index 4698222bda8..4490b3897df 100644 --- a/htdocs/blockedlog/admin/blockedlog_list.php +++ b/htdocs/blockedlog/admin/blockedlog_list.php @@ -118,7 +118,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_ref = ''; $search_amount = ''; $search_showonlyerrors = 0; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } diff --git a/htdocs/blockedlog/ajax/block-info.php b/htdocs/blockedlog/ajax/block-info.php index eb851af169a..e6f9ea0de15 100644 --- a/htdocs/blockedlog/ajax/block-info.php +++ b/htdocs/blockedlog/ajax/block-info.php @@ -92,11 +92,11 @@ function formatObject($objtoshow, $prefix) $s .= ''.($prefix ? $prefix.' > ' : '').$key.''; $s .= ''; if (in_array($key, array('date', 'datef', 'dateh', 'datec', 'datem', 'datep'))) { - /*var_dump(is_object($val)); - var_dump(is_array($val)); - var_dump(is_array($val)); - var_dump(@get_class($val)); - var_dump($val);*/ + //var_dump(is_object($val)); + //var_dump(is_array($val)); + //var_dump(is_array($val)); + //var_dump(@get_class($val)); + //var_dump($val); $s .= dol_print_date($val, 'dayhour'); } else { $s .= $val; diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php index 578e1afa497..ef4ca462008 100644 --- a/htdocs/blockedlog/class/blockedlog.class.php +++ b/htdocs/blockedlog/class/blockedlog.class.php @@ -1,6 +1,7 @@ - * Copyright (C) 2017-2020 Laurent Destailleur +/* Copyright (C) 2017 ATM Consulting + * Copyright (C) 2017-2020 Laurent Destailleur + * Copyright (C) 2022 charlene benke * * 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 @@ -139,76 +140,53 @@ class BlockedLog $this->trackedevents = array(); - if ($conf->facture->enabled) { + if (!empty($conf->facture->enabled)) { $this->trackedevents['BILL_VALIDATE'] = 'logBILL_VALIDATE'; - } - if ($conf->facture->enabled) { $this->trackedevents['BILL_DELETE'] = 'logBILL_DELETE'; - } - if ($conf->facture->enabled) { $this->trackedevents['BILL_SENTBYMAIL'] = 'logBILL_SENTBYMAIL'; - } - if ($conf->facture->enabled) { $this->trackedevents['DOC_DOWNLOAD'] = 'BlockedLogBillDownload'; - } - if ($conf->facture->enabled) { $this->trackedevents['DOC_PREVIEW'] = 'BlockedLogBillPreview'; - } - if ($conf->facture->enabled) { $this->trackedevents['PAYMENT_CUSTOMER_CREATE'] = 'logPAYMENT_CUSTOMER_CREATE'; - } - if ($conf->facture->enabled) { $this->trackedevents['PAYMENT_CUSTOMER_DELETE'] = 'logPAYMENT_CUSTOMER_DELETE'; } /* Supplier - if ($conf->fournisseur->enabled) $this->trackedevents['BILL_SUPPLIER_VALIDATE']='BlockedLogSupplierBillValidate'; - if ($conf->fournisseur->enabled) $this->trackedevents['BILL_SUPPLIER_DELETE']='BlockedLogSupplierBillDelete'; - if ($conf->fournisseur->enabled) $this->trackedevents['BILL_SUPPLIER_SENTBYMAIL']='BlockedLogSupplierBillSentByEmail'; // Trigger key does not exists, we want just into array to list it as done - if ($conf->fournisseur->enabled) $this->trackedevents['SUPPLIER_DOC_DOWNLOAD']='BlockedLogSupplierBillDownload'; // Trigger key does not exists, we want just into array to list it as done - if ($conf->fournisseur->enabled) $this->trackedevents['SUPPLIER_DOC_PREVIEW']='BlockedLogSupplierBillPreview'; // Trigger key does not exists, we want just into array to list it as done + if (!empty($conf->fournisseur->enabled)) { + $this->trackedevents['BILL_SUPPLIER_VALIDATE']='BlockedLogSupplierBillValidate'; + $this->trackedevents['BILL_SUPPLIER_DELETE']='BlockedLogSupplierBillDelete'; + $this->trackedevents['BILL_SUPPLIER_SENTBYMAIL']='BlockedLogSupplierBillSentByEmail'; // Trigger key does not exists, we want just into array to list it as done + $this->trackedevents['SUPPLIER_DOC_DOWNLOAD']='BlockedLogSupplierBillDownload'; // Trigger key does not exists, we want just into array to list it as done + $this->trackedevents['SUPPLIER_DOC_PREVIEW']='BlockedLogSupplierBillPreview'; // Trigger key does not exists, we want just into array to list it as done - if ($conf->fournisseur->enabled) $this->trackedevents['PAYMENT_SUPPLIER_CREATE']='BlockedLogSupplierBillPaymentCreate'; - if ($conf->fournisseur->enabled) $this->trackedevents['PAYMENT_SUPPLIER_DELETE']='BlockedLogsupplierBillPaymentCreate'; + $this->trackedevents['PAYMENT_SUPPLIER_CREATE']='BlockedLogSupplierBillPaymentCreate'; + $this->trackedevents['PAYMENT_SUPPLIER_DELETE']='BlockedLogsupplierBillPaymentCreate'; + } */ - if ($conf->don->enabled) { + if (!empty($conf->don->enabled)) { $this->trackedevents['DON_VALIDATE'] = 'logDON_VALIDATE'; - } - if ($conf->don->enabled) { $this->trackedevents['DON_DELETE'] = 'logDON_DELETE'; - } - //if ($conf->don->enabled) $this->trackedevents['DON_SENTBYMAIL']='logDON_SENTBYMAIL'; - - if ($conf->don->enabled) { + //$this->trackedevents['DON_SENTBYMAIL']='logDON_SENTBYMAIL'; $this->trackedevents['DONATION_PAYMENT_CREATE'] = 'logDONATION_PAYMENT_CREATE'; - } - if ($conf->don->enabled) { $this->trackedevents['DONATION_PAYMENT_DELETE'] = 'logDONATION_PAYMENT_DELETE'; } /* - if ($conf->salary->enabled) $this->trackedevents['PAYMENT_SALARY_CREATE']='BlockedLogSalaryPaymentCreate'; - if ($conf->salary->enabled) $this->trackedevents['PAYMENT_SALARY_MODIFY']='BlockedLogSalaryPaymentCreate'; - if ($conf->salary->enabled) $this->trackedevents['PAYMENT_SALARY_DELETE']='BlockedLogSalaryPaymentCreate'; + if (!empty($conf->salary->enabled)) { + $this->trackedevents['PAYMENT_SALARY_CREATE']='BlockedLogSalaryPaymentCreate'; + $this->trackedevents['PAYMENT_SALARY_MODIFY']='BlockedLogSalaryPaymentCreate'; + $this->trackedevents['PAYMENT_SALARY_DELETE']='BlockedLogSalaryPaymentCreate'; + } */ - if ($conf->adherent->enabled) { + if (!empty($conf->adherent->enabled)) { $this->trackedevents['MEMBER_SUBSCRIPTION_CREATE'] = 'logMEMBER_SUBSCRIPTION_CREATE'; - } - if ($conf->adherent->enabled) { $this->trackedevents['MEMBER_SUBSCRIPTION_MODIFY'] = 'logMEMBER_SUBSCRIPTION_MODIFY'; - } - if ($conf->adherent->enabled) { $this->trackedevents['MEMBER_SUBSCRIPTION_DELETE'] = 'logMEMBER_SUBSCRIPTION_DELETE'; } - if ($conf->banque->enabled) { + if (!empty($conf->banque->enabled)) { $this->trackedevents['PAYMENT_VARIOUS_CREATE'] = 'logPAYMENT_VARIOUS_CREATE'; - } - if ($conf->banque->enabled) { $this->trackedevents['PAYMENT_VARIOUS_MODIFY'] = 'logPAYMENT_VARIOUS_MODIFY'; - } - if ($conf->banque->enabled) { $this->trackedevents['PAYMENT_VARIOUS_DELETE'] = 'logPAYMENT_VARIOUS_DELETE'; } // $conf->global->BANK_ENABLE_POS_CASHCONTROL must be set to 1 by all external POS modules diff --git a/htdocs/bom/bom_agenda.php b/htdocs/bom/bom_agenda.php index 2b9c6f57bbd..4bc9095a57e 100644 --- a/htdocs/bom/bom_agenda.php +++ b/htdocs/bom/bom_agenda.php @@ -40,6 +40,7 @@ $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); +$socid = GETPOST('socid', 'int'); if (GETPOST('actioncode', 'array')) { $actioncode = GETPOST('actioncode', 'array', 3); @@ -79,7 +80,7 @@ $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->bom->multidir_output[$object->entity]."/".$object->id; + $upload_dir = (!empty($conf->bom->multidir_output[$object->entity]) ? $conf->bom->multidir_output[$object->entity] : $conf->bom->dir_output)."/".$object->id; } // Security check - Protection if external user diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index 748aea4ddb2..aee1f6ba0bf 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -28,6 +28,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php'; require_once DOL_DOCUMENT_ROOT.'/bom/lib/bom.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/mrp/lib/mrp.lib.php'; + // Load translation files required by the page $langs->loadLangs(array("mrp", "other")); @@ -148,8 +150,17 @@ if (empty($reshook)) { $error = 0; // Set if we used free entry or predefined product - $idprod = (int) GETPOST('idprod', 'int'); - $bom_child = (int) GETPOST('bom_select', 'int'); + $bom_child_id = (int) GETPOST('bom_id', 'int'); + if ($bom_child_id > 0) { + $bom_child = new BOM($db); + $res = $bom_child->fetch($bom_child_id); + if ($res) { + $idprod = $bom_child->fk_product; + } + } else { + $idprod = (int) GETPOST('idprod', 'int'); + } + $qty = price2num(GETPOST('qty', 'alpha'), 'MS'); $qty_frozen = price2num(GETPOST('qty_frozen', 'alpha'), 'MS'); $disable_stock_change = GETPOST('disable_stock_change', 'int'); @@ -173,7 +184,7 @@ if (empty($reshook)) { $bomline = new BOMLine($db); $bomline->fk_bom = $id; $bomline->fk_product = $idprod; - $bomline->fk_bom_child = $bom_child; + $bomline->fk_bom_child = $bom_child_id; $bomline->qty = $qty; $bomline->qty_frozen = (int) $qty_frozen; $bomline->disable_stock_change = (int) $disable_stock_change; @@ -354,8 +365,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $formquestion = array(); if (!empty($conf->bom->enabled)) { $langs->load("mrp"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct = new FormProduct($db); $forcecombo = 0; if ($conf->browser->name == 'ie') { $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy @@ -384,8 +393,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $formquestion = array(); if (!empty($conf->bom->enabled)) { $langs->load("mrp"); - require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct = new FormProduct($db); $forcecombo = 0; if ($conf->browser->name == 'ie') { $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy @@ -415,7 +422,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (!empty($conf->bom->enabled)) { $langs->load("mrp"); require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; - $formproduct = new FormProduct($db); $forcecombo = 0; if ($conf->browser->name == 'ie') { $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy @@ -514,8 +520,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Common attributes $keyforbreak = 'duration'; include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; - - print ''.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).''.price($object->total_cost).''; + $object->calculateCosts(); + print ''.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).''.price($object->total_cost).''; print ''.$langs->trans("UnitCost").''.price($object->unit_cost).''; // Other attributes @@ -577,46 +583,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print "\n"; - ?> - - - id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $MAXEVENT = 10; - $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-list-alt imgforviewmode', DOL_URL_ROOT.'/bom/bom_agenda.php?id='.$object->id); + $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/bom/bom_agenda.php?id='.$object->id); // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; diff --git a/htdocs/bom/bom_document.php b/htdocs/bom/bom_document.php index 64f3cdbfac1..a0390ef5105 100644 --- a/htdocs/bom/bom_document.php +++ b/htdocs/bom/bom_document.php @@ -104,6 +104,7 @@ $form = new Form($db); $title = $langs->trans("BillOfMaterials").' - '.$langs->trans("Files"); $help_url = 'EN:Module_BOM'; +$morehtmlref = ""; llxHeader('', $title, $help_url); diff --git a/htdocs/bom/bom_net_needs.php b/htdocs/bom/bom_net_needs.php new file mode 100644 index 00000000000..baf4b096324 --- /dev/null +++ b/htdocs/bom/bom_net_needs.php @@ -0,0 +1,329 @@ + + * Copyright (C) 2019 Frédéric France + * + * 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 . + */ + +/** + * \file htdocs/bom/bom_net_needs.php + * \ingroup bom + * \brief Page to create/edit/view bom + */ + +// Load Dolibarr environment +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php'; +require_once DOL_DOCUMENT_ROOT.'/bom/lib/bom.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("mrp", "other", "stocks")); + +// Get parameters +$id = GETPOST('id', 'int'); +$lineid = GETPOST('lineid', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm', 'alpha'); +$cancel = GETPOST('cancel', 'aZ09'); +$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'bomnet_needs'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); + + + +// Initialize technical objects +$object = new BOM($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->bom->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('bomnetneeds')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); +$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); + +// Initialize array of search criterias +$search_all = GETPOST("search_all", 'alpha'); +$search = array(); +foreach ($object->fields as $key => $val) { + if (GETPOST('search_'.$key, 'alpha')) { + $search[$key] = GETPOST('search_'.$key, 'alpha'); + } +} + +if (empty($action) && empty($id) && empty($ref)) { + $action = 'view'; +} + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. +if ($object->id > 0) { + $object->calculateCosts(); +} + + + +// Security check - Protection if external user +//if ($user->socid > 0) accessforbidden(); +//if ($user->socid > 0) $socid = $user->socid; +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +$result = restrictedArea($user, 'bom', $object->id, 'bom_bom', '', '', 'rowid', $isdraft); + +$permissionnote = $user->rights->bom->write; // Used by the include of actions_setnotes.inc.php +$permissiondellink = $user->rights->bom->write; // Used by the include of actions_dellink.inc.php +$permissiontoadd = $user->rights->bom->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php +$permissiontodelete = $user->rights->bom->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT); +$upload_dir = $conf->bom->multidir_output[isset($object->entity) ? $object->entity : 1]; + + +/* + * Actions + */ + +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + $error = 0; + + $backurlforlist = DOL_URL_ROOT.'/bom/bom_list.php'; + + if (empty($backtopage) || ($cancel && empty($id))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = DOL_URL_ROOT.'/bom/bom_net_needs.php?id='.($id > 0 ? $id : '__ID__'); + } + } + } + if ($action == 'treeview') $object->getNetNeedsTree($TChildBom, 1); + else $object->getNetNeeds($TChildBom, 1); +} + + +/* + * View + */ + +$form = new Form($db); +$formfile = new FormFile($db); + + +$title = $langs->trans('BOM'); +$help_url ='EN:Module_BOM'; +llxHeader('', $title, $help_url); + + + +// Part to show record +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { + $head = bomPrepareHead($object); + print dol_get_fiche_head($head, 'net_needs', $langs->trans("BillOfMaterials"), -1, 'bom'); + + $formconfirm = ''; + + // Call Hook formConfirm + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + $formconfirm .= $hookmanager->resPrint; + } elseif ($reshook > 0) { + $formconfirm = $hookmanager->resPrint; + } + + // Print form confirm + print $formconfirm; + + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
    '; + print '
    '; + print '
    '; + print ''."\n"; + + // Common attributes + $keyforbreak = 'duration'; + include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; + + print ''; + print ''; + + // Other attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; + + print '
    '.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).''.price($object->total_cost).'
    '.$langs->trans("UnitCost").''.price($object->unit_cost).'
    '; + print '
    '; + print '
    '; + + print '
    '; + + print dol_get_fiche_end(); + + $viewlink = dolGetButtonTitle($langs->trans('GroupByProduct'), '', 'fa fa-bars imgforviewmode', $_SERVER['PHP_SELF'].'?id='.$object->id.'&token='.newToken(), '', 1, array('morecss' => 'reposition '.($action !== 'treeview' ? 'btnTitleSelected':''))); + $viewlink .= dolGetButtonTitle($langs->trans('TreeStructure'), '', 'fa fa-stream imgforviewmode', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=treeview&token='.newToken(), '', 1, array('morecss' => 'reposition marginleftonly '.($action == 'treeview' ? 'btnTitleSelected':''))); + + print load_fiche_titre($langs->trans("BOMNetNeeds"), $viewlink, ''); + + /* + * Lines + */ + $text_stock_options = $langs->trans("RealStockDesc").'
    '; + $text_stock_options .= $langs->trans("RealStockWillAutomaticallyWhen").'
    '; + $text_stock_options .= (! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT) || ! empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE) ? '- '.$langs->trans("DeStockOnShipment").'
    ' : ''); + $text_stock_options .= (! empty($conf->global->STOCK_CALCULATE_ON_VALIDATE_ORDER) ? '- '.$langs->trans("DeStockOnValidateOrder").'
    ' : ''); + $text_stock_options .= (! empty($conf->global->STOCK_CALCULATE_ON_BILL) ? '- '.$langs->trans("DeStockOnBill").'
    ' : ''); + $text_stock_options .= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_BILL) ? '- '.$langs->trans("ReStockOnBill").'
    ' : ''); + $text_stock_options .= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) ? '- '.$langs->trans("ReStockOnValidateOrder").'
    ' : ''); + $text_stock_options .= (! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) ? '- '.$langs->trans("ReStockOnDispatchOrder").'
    ' : ''); + $text_stock_options .= (!empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE) ? '- '.$langs->trans("StockOnReception").'
    ' : ''); + + print ''; + print "\n"; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if (! empty($TChildBom)) { + if ($action == 'treeview') { + foreach ($TChildBom as $fk_bom => $TProduct) { + $repeatChar = ' '; + if (! empty($TProduct['bom'])) { + if ($TProduct['parentid'] != $object->id) print ''; + else print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + if (! empty($TProduct['product'])) { + foreach ($TProduct['product'] as $fk_product => $TInfos) { + $prod = new Product($db); + $prod->fetch($fk_product); + $prod->load_virtual_stock(); + if (empty($prod->stock_reel)) $prod->stock_reel = 0; + if ($fk_bom != $object->id) print ''; + else print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + } + } + } else { + foreach ($TChildBom as $fk_product => $qty) { + $prod = new Product($db); + $prod->fetch($fk_product); + $prod->load_virtual_stock(); + if (empty($prod->stock_reel)) $prod->stock_reel = 0; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + } + } + } + print ''; + print '
    '.$langs->trans('Product'); + if (! empty($conf->global->BOM_SUB_BOM) && $action == 'treeview') { + print '   '.img_picto('', 'folder-open', 'class="paddingright"').$langs->trans("ExpandAll").'  '; + print ''.img_picto('', 'folder', 'class="paddingright"').$langs->trans("UndoExpandAll").' '; + } + print ''.$langs->trans('Quantity').''.$form->textwithpicto($langs->trans("PhysicalStock"), $text_stock_options, 1).''.$form->textwithpicto($langs->trans("VirtualStock"), $langs->trans("VirtualStockDesc")).'
    '.str_repeat($repeatChar, $TProduct['level']).$TProduct['bom']->getNomUrl(1); + print ' '; + print img_picto('', 'folder-open'); + print ''; + print ''.$TProduct['qty'].'
    '.str_repeat($repeatChar, $TInfos['level']).$prod->getNomUrl(1).''.$TInfos['qty'].''.price2num($prod->stock_reel, 'MS').''.$prod->stock_theorique.'
    '.$prod->getNomUrl(1).''.$qty.''.price2num($prod->stock_reel, 'MS').''.$prod->stock_theorique.'
    '; + + + + /* + * ButAction + */ + print '
    '."\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + } + print '
    '; + + + ?> + + + + close(); diff --git a/htdocs/bom/bom_note.php b/htdocs/bom/bom_note.php index 8ace40cc900..9984a1498b8 100644 --- a/htdocs/bom/bom_note.php +++ b/htdocs/bom/bom_note.php @@ -54,7 +54,7 @@ $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->bom->multidir_output[$object->entity]."/".$object->id; + $upload_dir = (!empty($conf->bom->multidir_output[$object->entity]) ? $conf->bom->multidir_output[$object->entity] : $conf->bom->dir_output)."/".$object->id; } $permissionnote = $user->rights->bom->write; // Used by the include of actions_setnotes.inc.php diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 68cd44dcf46..598c4c73945 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -78,7 +78,7 @@ class BOM extends CommonObject * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). - * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'maxwidth200', 'wordbreak', 'tdoverflowmax200' + * 'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'cssview'=>'wordbreak', 'csslist'=>'tdoverflowmax200' * 'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click. * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. @@ -97,7 +97,7 @@ class BOM extends CommonObject 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=> 1, 'default'=>1, 'index'=>1, 'position'=>5), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'noteditable'=>1, 'visible'=>4, 'position'=>10, 'notnull'=>1, 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of BOM", 'showoncombobox'=>'1',), - 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'notnull'=>1, 'searchall'=>1, 'showoncombobox'=>'2', 'autofocusoncreate'=>1, 'css'=>'maxwidth300', 'csslist'=>'tdoverflowmax200'), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'notnull'=>1, 'searchall'=>1, 'showoncombobox'=>'2', 'autofocusoncreate'=>1, 'css'=>'minwidth300 maxwidth400', 'csslist'=>'tdoverflowmax200'), 'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>1, 'position'=>33, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing', 1=>'Disassemble'), 'css'=>'minwidth175', 'csslist'=>'minwidth175 center'), //'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>-1, 'position'=>32, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing')), 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php:1:(finished IS NULL or finished <> 0)', 'label'=>'Product', 'picto'=>'product', 'enabled'=>1, 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'help'=>'ProductBOMHelp', 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax100'), @@ -820,13 +820,6 @@ class BOM extends CommonObject } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('bomdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -847,7 +840,7 @@ class BOM extends CommonObject global $action, $hookmanager; $hookmanager->initHooks(array('bomdao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; @@ -916,27 +909,27 @@ class BOM extends CommonObject if ($this->db->num_rows($result)) { $obj = $this->db->fetch_object($result); $this->id = $obj->rowid; - if ($obj->fk_user_author) { + if (!empty($obj->fk_user_author)) { $cuser = new User($this->db); $cuser->fetch($obj->fk_user_author); $this->user_creation = $cuser; } - if ($obj->fk_user_valid) { + if (!empty($obj->fk_user_valid)) { $vuser = new User($this->db); $vuser->fetch($obj->fk_user_valid); $this->user_validation = $vuser; } - if ($obj->fk_user_cloture) { + if (!empty($obj->fk_user_cloture)) { $cluser = new User($this->db); $cluser->fetch($obj->fk_user_cloture); $this->user_cloture = $cluser; } $this->date_creation = $this->db->jdate($obj->datec); - $this->date_modification = $this->db->jdate($obj->datem); - $this->date_validation = $this->db->jdate($obj->datev); + $this->date_modification = !empty($obj->datem) ? $this->db->jdate($obj->datem) : ""; + $this->date_validation = !empty($obj->datev) ? $this->db->jdate($obj->datev) : ""; } $this->db->free($result); @@ -1064,26 +1057,109 @@ class BOM extends CommonObject $tmpproduct->cost_price = 0; $tmpproduct->pmp = 0; - $result = $tmpproduct->fetch($line->fk_product, '', '', '', 0, 1, 1); // We discard selling price and language loading - if ($result < 0) { - $this->error = $tmpproduct->error; - return -1; - } - $line->unit_cost = price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp); - if (empty($line->unit_cost)) { - if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) { - $line->unit_cost = $productFournisseur->fourn_unitprice; + if (empty($line->fk_bom_child)) { + $result = $tmpproduct->fetch($line->fk_product, '', '', '', 0, 1, 1); // We discard selling price and language loading + if ($result < 0) { + $this->error = $tmpproduct->error; + return -1; + } + $line->unit_cost = price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp); + if (empty($line->unit_cost)) { + if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) { + $line->unit_cost = $productFournisseur->fourn_unitprice; + } + } + + $line->total_cost = price2num($line->qty * $line->unit_cost, 'MT'); + + $this->total_cost += $line->total_cost; + } else { + $bom_child= new BOM($this->db); + $res = $bom_child->fetch($line->fk_bom_child); + if ($res>0) { + $bom_child->calculateCosts(); + $line->childBom[] = $bom_child; + $this->total_cost += $bom_child->total_cost * $line->qty; + } else { + $this->error = $bom_child->error; + return -2; } } - - $line->total_cost = price2num($line->qty * $line->unit_cost, 'MT'); - - $this->total_cost += $line->total_cost; } $this->total_cost = price2num($this->total_cost, 'MT'); - if ($this->qty) { + if ($this->qty > 0) { $this->unit_cost = price2num($this->total_cost / $this->qty, 'MU'); + } elseif ($this->qty < 0) { + $this->unit_cost = price2num($this->total_cost * $this->qty, 'MU'); + } + } + } + + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'bom_bomline' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + + /** + * Get Net needs by product + * + * @param array $TNetNeeds Array of ChildBom and infos linked to + * @param int $qty qty needed + * @return void + */ + public function getNetNeeds(&$TNetNeeds = array(), $qty = 0) + { + if (! empty($this->lines)) { + foreach ($this->lines as $line) { + if (! empty($line->childBom)) { + foreach ($line->childBom as $childBom) $childBom->getNetNeeds($TNetNeeds, $line->qty*$qty); + } else { + if (empty($TNetNeeds[$line->fk_product])) { + $TNetNeeds[$line->fk_product] = 0; + } + $TNetNeeds[$line->fk_product] += $line->qty*$qty; + } + } + } + } + + /** + * Get Net needs Tree by product or bom + * + * @param array $TNetNeeds Array of ChildBom and infos linked to + * @param int $qty qty needed + * @param int $level level of recursivity + * @return void + */ + public function getNetNeedsTree(&$TNetNeeds = array(), $qty = 0, $level = 0) + { + if (! empty($this->lines)) { + foreach ($this->lines as $line) { + if (! empty($line->childBom)) { + foreach ($line->childBom as $childBom) { + $TNetNeeds[$childBom->id]['bom'] = $childBom; + $TNetNeeds[$childBom->id]['parentid'] = $this->id; + $TNetNeeds[$childBom->id]['qty'] = $line->qty*$qty; + $TNetNeeds[$childBom->id]['level'] = $level; + $childBom->getNetNeedsTree($TNetNeeds, $line->qty*$qty, $level+1); + } + } else { + $TNetNeeds[$this->id]['product'][$line->fk_product]['qty'] += $line->qty * $qty; + $TNetNeeds[$this->id]['product'][$line->fk_product]['level'] = $level; + } } } } @@ -1213,6 +1289,12 @@ class BOMLine extends CommonObjectLine public $unit_cost = 0; + /** + * @var Bom array of Bom in line + */ + public $childBom = array(); + + /** * Constructor * @@ -1426,13 +1508,6 @@ class BOMLine extends CommonObjectLine } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('bomlinedao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -1453,7 +1528,7 @@ class BOMLine extends CommonObjectLine global $action, $hookmanager; $hookmanager->initHooks(array('bomlinedao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; diff --git a/htdocs/bom/lib/bom.lib.php b/htdocs/bom/lib/bom.lib.php index 805ba304c1d..94debfbee7b 100644 --- a/htdocs/bom/lib/bom.lib.php +++ b/htdocs/bom/lib/bom.lib.php @@ -84,6 +84,11 @@ function bomPrepareHead($object) $head[$h][2] = 'card'; $h++; + $head[$h][0] = DOL_URL_ROOT."/bom/bom_net_needs.php?id=".$object->id; + $head[$h][1] = $langs->trans("BOMNetNeeds"); + $head[$h][2] = 'net_needs'; + $h++; + if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { $nbNote = 0; if (!empty($object->note_private)) { @@ -131,3 +136,55 @@ function bomPrepareHead($object) return $head; } + +/** + * Manage collapse bom display + * + * @return void + */ +function mrpCollapseBomManagement() +{ + ?> + + + + \n"; +print "\n"; global $user, $db; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/bom/tpl/objectline_create.tpl.php b/htdocs/bom/tpl/objectline_create.tpl.php index 7419c4618e0..0a3a3b34e7a 100644 --- a/htdocs/bom/tpl/objectline_create.tpl.php +++ b/htdocs/bom/tpl/objectline_create.tpl.php @@ -109,7 +109,7 @@ if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { if (!empty($conf->global->BOM_SUB_BOM)) { print '
    '.$langs->trans("or").'
    '.$langs->trans("BOM"); // TODO Add component to select a BOM - print ''; + $form->select_bom(); } print ''; diff --git a/htdocs/bom/tpl/objectline_view.tpl.php b/htdocs/bom/tpl/objectline_view.tpl.php index 82626c12fec..61b394a3b0f 100644 --- a/htdocs/bom/tpl/objectline_view.tpl.php +++ b/htdocs/bom/tpl/objectline_view.tpl.php @@ -41,7 +41,7 @@ if (empty($object) || !is_object($object)) { } -global $forceall, $senderissupplier, $inputalsopricewithtax, $outputalsopricetotalwithtax; +global $forceall, $senderissupplier, $inputalsopricewithtax, $outputalsopricetotalwithtax, $langs; if (empty($dateSelector)) { $dateSelector = 0; @@ -83,8 +83,12 @@ $tmpproduct->fetch($line->fk_product); $tmpbom = new BOM($object->db); $res = $tmpbom->fetch($line->fk_bom_child); if ($tmpbom->id > 0) { + print $tmpproduct->getNomUrl(1); + print ' '.$langs->trans("or").' '; print $tmpbom->getNomUrl(1); - print '' . (empty($conf->global->BOM_SHOW_ALL_BOM_BY_DEFAULT) ? '(+)' : '(-)') . ' '; + print ' '; + print (empty($conf->global->BOM_SHOW_ALL_BOM_BY_DEFAULT) ? img_picto('', 'folder') : img_picto('', 'folder-open')); + print ''; } else { print $tmpproduct->getNomUrl(1); print ' - '.$tmpproduct->label; @@ -122,7 +126,7 @@ print ''; $total_cost = 0; print ''; $coldisplay++; -echo price($line->total_cost); +echo ''.price($line->total_cost).''; print ''; if ($this->status == 0 && ($object_rights->write) && $action != 'selectlines') { @@ -148,12 +152,12 @@ if ($this->status == 0 && ($object_rights->write) && $action != 'selectlines') { print ''; $coldisplay++; if ($i > 0) { - print 'id.'">'; + print 'id.'">'; echo img_up('default', 0, 'imgupforline'); print ''; } if ($i < $num - 1) { - print 'id.'">'; + print 'id.'">'; echo img_down('default', 0, 'imgdownforline'); print ''; } @@ -176,7 +180,8 @@ if ($action == 'selectlines') { print ''; // Select of all the sub-BOM lines -$sql = 'SELECT rowid, fk_bom_child, fk_product FROM '.MAIN_DB_PREFIX.'bom_bomline AS bl'; +// From this pont to the end of the file, we only take care of sub-BOM lines +$sql = 'SELECT rowid, fk_bom_child, fk_product, qty FROM '.MAIN_DB_PREFIX.'bom_bomline AS bl'; $sql.= ' WHERE fk_bom ='. (int) $tmpbom->id; $resql = $object->db->query($sql); @@ -187,7 +192,9 @@ if ($resql) { $sub_bom_product->fetch($obj->fk_product); $sub_bom = new BOM($object->db); - $sub_bom->fetch($obj->fk_bom_child); + if (!empty($obj->fk_bom_child)) { + $sub_bom->fetch($obj->fk_bom_child); + } $sub_bom_line = new BOMLine($object->db); $sub_bom_line->fetch($obj->rowid); @@ -199,21 +206,23 @@ if ($resql) { print ''; } - // Product - print ''.$sub_bom_product->getNomUrl(1).''; - - // Sub-BOM - if ($sub_bom_line->fk_bom_child > 0) { - print ''.$sub_bom->getNomUrl(1).''; + // Product OR BOM + print ''; + if (!empty($obj->fk_bom_child)) { + print $sub_bom_product->getNomUrl(1); + print ' '.$langs->trans('or').' '; + print $sub_bom->getNomUrl(1); } else { - print ' '; + print $sub_bom_product->getNomUrl(1); + print ''; } // Qty - print ''.price($sub_bom_line->qty * $line->qty, 0, '', 0, 0).''; if ($sub_bom_line->qty_frozen > 0) { - print ''.$sub_bom_line->qty_frozen.''; + print ''.price($sub_bom_line->qty, 0, '', 0, 0).''; + print ''.$langs->trans('Yes').''; } else { + print ''.price($sub_bom_line->qty * $line->qty, 0, '', 0, 0).''; print ' '; } @@ -227,21 +236,27 @@ if ($resql) { // Efficiency print ''.$sub_bom_line->efficiency.''; - // Cost price if it's defined - if ($sub_bom_product->cost_price > 0) { - print ''.price($sub_bom_product->cost_price * $line->qty).''; - $total_cost.= $sub_bom_product->cost_price * $line->qty; + // Cost + if (!empty($sub_bom->id)) { + $sub_bom->calculateCosts(); + print ''.price($sub_bom->total_cost * $sub_bom_line->qty * $line->qty).''; + $total_cost+= $sub_bom->total_cost * $sub_bom_line->qty * $line->qty; + } elseif ($sub_bom_product->cost_price > 0) { + print ''.price($sub_bom_product->cost_price * $sub_bom_line->qty * $line->qty).''; + $total_cost+= $sub_bom_product->cost_price * $sub_bom_line->qty * $line->qty; } elseif ($sub_bom_product->pmp > 0) { // PMP if cost price isn't defined - print ''.price($sub_bom_product->pmp * $line->qty).''; - $total_cost.= $sub_bom_product->pmp * $line->qty; + print ''.price($sub_bom_product->pmp * $sub_bom_line->qty * $line->qty).''; + $total_cost.= $sub_bom_product->pmp * $sub_bom_line->qty * $line->qty; } else { // Minimum purchase price if cost price and PMP aren't defined - $sql_supplier_price = 'SELECT MIN(price) AS min_price FROM '.MAIN_DB_PREFIX.'product_fournisseur_price'; + $sql_supplier_price = 'SELECT MIN(price) AS min_price, quantity AS qty FROM '.MAIN_DB_PREFIX.'product_fournisseur_price'; $sql_supplier_price.= ' WHERE fk_product = '. (int) $sub_bom_product->id; $resql_supplier_price = $object->db->query($sql_supplier_price); if ($resql_supplier_price) { $obj = $object->db->fetch_object($resql_supplier_price); - print ''.price($obj->min_price * $line->qty).''; - $total_cost+= $obj->min_price * $line->qty; + $line_cost = $obj->min_price/$obj->qty * $sub_bom_line->qty * $line->qty; + + print ''.price($line_cost).''; + $total_cost+= $line_cost; } } @@ -252,11 +267,12 @@ if ($resql) { } // Replace of the total_cost value by the sum of all sub-BOM lines total_cost +// TODO Remove this bad practice. We should not replace content of ouput using javascript but value should be good during generation of output. if ($total_cost > 0) { $line->total_cost = price($total_cost); ?> initHooks(array('mybookmarkdao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; diff --git a/htdocs/categories/admin/categorie_extrafields.php b/htdocs/categories/admin/categorie_extrafields.php index 02cd6e2a784..7dbf31835ca 100644 --- a/htdocs/categories/admin/categorie_extrafields.php +++ b/htdocs/categories/admin/categorie_extrafields.php @@ -82,7 +82,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index 786af013dc6..05b1822f45f 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -10,7 +10,7 @@ * Copyright (C) 2015 Marcos García * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2016 Charlie Benke - * Copyright (C) 2018-2019 Frédéric France + * Copyright (C) 2018-2022 Frédéric France * * 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 @@ -114,7 +114,7 @@ class Categorie extends CommonObject * * @todo Move to const array when PHP 5.6 will be our minimum target */ - protected $MAP_CAT_FK = array( + public $MAP_CAT_FK = array( 'customer' => 'soc', 'supplier' => 'soc', 'contact' => 'socpeople', @@ -126,7 +126,7 @@ class Categorie extends CommonObject * * @note Move to const array when PHP 5.6 will be our minimum target */ - protected $MAP_CAT_TABLE = array( + public $MAP_CAT_TABLE = array( 'customer' => 'societe', 'supplier' => 'fournisseur', 'bank_account'=> 'account', @@ -137,7 +137,7 @@ class Categorie extends CommonObject * * @note Move to const array when PHP 5.6 will be our minimum target */ - protected $MAP_OBJ_CLASS = array( + public $MAP_OBJ_CLASS = array( 'product' => 'Product', 'customer' => 'Societe', 'supplier' => 'Fournisseur', @@ -179,7 +179,7 @@ class Categorie extends CommonObject * * @note Move to const array when PHP 5.6 will be our minimum target */ - protected $MAP_OBJ_TABLE = array( + public static $MAP_OBJ_TABLE = array( 'customer' => 'societe', 'supplier' => 'societe', 'member' => 'adherent', @@ -259,6 +259,12 @@ class Categorie extends CommonObject */ public $motherof = array(); + /** + * @var array Childs + */ + public $childs = array(); + + /** * Constructor * @@ -820,7 +826,7 @@ class Categorie extends CommonObject /** * Return list of fetched instance of elements having this category * - * @param string $type Type of category ('customer', 'supplier', 'contact', 'product', 'member', ...) + * @param string $type Type of category ('customer', 'supplier', 'contact', 'product', 'member', 'knowledge_management' ...) * @param int $onlyids Return only ids of objects (consume less memory) * @param int $limit Limit * @param int $offset Offset @@ -914,7 +920,7 @@ class Categorie extends CommonObject $categories = array(); - $type = checkVal($type, 'aZ09'); + $type = sanitizeVal($type, 'aZ09'); $sub_type = $type; $subcol_name = "fk_".$type; @@ -1142,10 +1148,10 @@ class Categorie extends CommonObject } // We add the fullpath property to each elements of first level (no parent exists) - dol_syslog(get_class($this)."::get_full_arbo call to build_path_from_id_categ", LOG_DEBUG); + dol_syslog(get_class($this)."::get_full_arbo call to buildPathFromId", LOG_DEBUG); foreach ($this->cats as $key => $val) { //print 'key='.$key.'
    '."\n"; - $this->build_path_from_id_categ($key, 0); // Process a branch from the root category key (this category has no parent) + $this->buildPathFromId($key, 0); // Process a branch from the root category key (this category has no parent) } // Include or exclude leaf including $markafterid from tree @@ -1175,7 +1181,6 @@ class Categorie extends CommonObject return $this->cats; } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * For category id_categ and its childs available in this->cats, define property fullpath and fulllabel. * It is called by get_full_arbo() @@ -1186,19 +1191,18 @@ class Categorie extends CommonObject * @return void * @see get_full_arbo() */ - public function build_path_from_id_categ($id_categ, $protection = 1000) + private function buildPathFromId($id_categ, $protection = 1000) { - // phpcs:enable - dol_syslog(get_class($this)."::build_path_from_id_categ id_categ=".$id_categ." protection=".$protection, LOG_DEBUG); + //dol_syslog(get_class($this)."::buildPathFromId id_categ=".$id_categ." protection=".$protection, LOG_DEBUG); if (!empty($this->cats[$id_categ]['fullpath'])) { // Already defined - dol_syslog(get_class($this)."::build_path_from_id_categ fullpath and fulllabel already defined", LOG_WARNING); + dol_syslog(get_class($this)."::buildPathFromId fullpath and fulllabel already defined", LOG_WARNING); return; } // First build full array $motherof - //$this->load_motherof(); // Disabled because already done by caller of build_path_from_id_categ + //$this->load_motherof(); // Disabled because already done by caller of buildPathFromId // $this->cats[$id_categ] is supposed to be already an array. We just want to complete it with property fullpath and fulllabel @@ -1614,7 +1618,7 @@ class Categorie extends CommonObject */ public function getNomUrl($withpicto = 0, $option = '', $maxlength = 0, $moreparam = '') { - global $langs; + global $langs, $hookmanager; $result = ''; $label = $langs->trans("ShowCategory").': '.($this->ref ? $this->ref : $this->label); @@ -1642,6 +1646,15 @@ class Categorie extends CommonObject if ($withpicto != 2) { $result .= $link.dol_trunc(($this->ref ? $this->ref : $this->label), $maxlength).$linkend; } + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } diff --git a/htdocs/categories/edit.php b/htdocs/categories/edit.php index 2b3ffc95c41..518889b85b3 100644 --- a/htdocs/categories/edit.php +++ b/htdocs/categories/edit.php @@ -178,7 +178,9 @@ print ''; // Parent category print ''.$langs->trans("In").''; +print img_picto('', 'category', 'class="pictofixedwidth"'); print $form->select_all_categories($type, $object->fk_parent, 'parent', 64, $object->id); +print ajax_combobox('parent'); print ''; $parameters = array(); diff --git a/htdocs/categories/index.php b/htdocs/categories/index.php index 04f2288ae08..4a9e771416c 100644 --- a/htdocs/categories/index.php +++ b/htdocs/categories/index.php @@ -102,7 +102,8 @@ if (empty($nosearch)) { print ''.$langs->trans("Search").''; print ''; print ''; - print $langs->trans("Name").':'; + print $langs->trans("Name").':'; + print ''; print ''; @@ -133,7 +134,9 @@ if (empty($nosearch)) { print ''; print "\n"; print "\t\t"; - print dolGetFirstLineOfText($cat->description); + $text = dolGetFirstLineOfText(dol_string_nohtmltag($cat->description, 1)); + $trunclength = 48; + print $form->textwithtooltip(dol_trunc($text, $trunclength), $cat->description); print "\n"; print "\t\n"; } diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 02f52de7388..b1ae9dee61b 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -461,6 +461,13 @@ if (empty($reshook) && $action == 'add') { } } + // Modify $moreparam so we are sure to see the event we have just created, whatever are the default value of filter on next page. + /*$moreparam .= ($moreparam ? '&' : '').'search_actioncode=0'; + $moreparam .= ($moreparam ? '&' : '').'search_status=-1'; + $moreparam .= ($moreparam ? '&' : '').'search_filtert='.$object->userownerid; + */ + $moreparam .= ($moreparam ? '&' : '').'disabledefaultvalues=1'; + if ($error) { $db->rollback(); } else { @@ -674,7 +681,7 @@ if (empty($reshook) && $action == 'update') { $object->errors[] = $object->error; } else { if ($db->num_rows($resql) > 0) { - // already in use + // Resource already in use $error++; $object->error = $langs->trans('ErrorResourcesAlreadyInUse').' : '; while ($obj = $db->fetch_object($resql)) { @@ -853,7 +860,7 @@ if (empty($reshook) && GETPOST('actionmove', 'alpha') == 'mupdate') { $object->errors[] = $object->error; } else { if ($db->num_rows($resql) > 0) { - // already in use + // Resource already in use $error++; $object->error = $langs->trans('ErrorResourcesAlreadyInUse').' : '; while ($obj = $db->fetch_object($resql)) { @@ -952,16 +959,17 @@ if ($action == 'create') { console.log("setdatefields"); setdatefields(); }); + $("#selectcomplete").change(function() { - if ($("#selectcomplete").val() == 100) - { + console.log("we change the complete status - set the doneby"); + if ($("#selectcomplete").val() == 100) { if ($("#doneby").val() <= 0) $("#doneby").val(\''.((int) $user->id).'\'); } - if ($("#selectcomplete").val() == 0) - { + if ($("#selectcomplete").val() == 0) { $("#doneby").val(-1); } }); + $("#actioncode").change(function() { if ($("#actioncode").val() == \'AC_RDV\') $("#dateend").addClass("fieldrequired"); else $("#dateend").removeClass("fieldrequired"); @@ -1019,59 +1027,15 @@ if ($action == 'create') { print 'global->AGENDA_USE_EVENT_TYPE) ? ' class="fieldrequired titlefieldcreate"' : '').'>'.$langs->trans("Label").''; // Full day - print ''; + print ''.$langs->trans("Date").''; - $datep = ($datep ? $datep : (is_null($object->datep) ? '' : $object->datep)); - if (GETPOST('datep', 'int', 1)) { - $datep = dol_stringtotime(GETPOST('datep', 'int', 1), 'tzuser'); - } - $datef = ($datef ? $datef : $object->datef); - if (GETPOST('datef', 'int', 1)) { - $datef = dol_stringtotime(GETPOST('datef', 'int', 1), 'tzuser'); - } - if (empty($datef) && !empty($datep)) { - if (GETPOST("actioncode", 'aZ09') == 'AC_RDV' || empty($conf->global->AGENDA_USE_EVENT_TYPE_DEFAULT)) { - $datef = dol_time_plus_duree($datep, (empty($conf->global->AGENDA_AUTOSET_END_DATE_WITH_DELTA_HOURS) ? 1 : $conf->global->AGENDA_AUTOSET_END_DATE_WITH_DELTA_HOURS), 'h'); - } - } - - // Date start - print ''; - print ''.$langs->trans("DateActionStart").''; - print ' - '; - print ''.$langs->trans("DateActionEnd").''; - print ''; - if (GETPOST("afaire") == 1) { - print $form->selectDate($datep, 'ap', 1, 1, 0, "action", 1, 2, 0, 'fulldaystart', '', '', '', 1, '', '', 'tzuserrel'); // Empty value not allowed for start date and hours if "todo" - } else { - print $form->selectDate($datep, 'ap', 1, 1, 1, "action", 1, 2, 0, 'fulldaystart', '', '', '', 1, '', '', 'tzuserrel'); - } - print '     -     '; - //print ' - '; - if (GETPOST("afaire") == 1) { - print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 0, 0, 'fulldayend', '', '', '', 1, '', '', 'tzuserrel'); - } else { - print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 0, 0, 'fulldayend', '', '', '', 1, '', '', 'tzuserrel'); - } - print ''; - - // Date end - /*print ''; - print ''.$langs->trans("DateActionEnd").''; - print ''; - print ''; - if (GETPOST("afaire") == 1) { - print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 2, 0, 'fulldayend'); - } else { - print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 2, 0, 'fulldayend'); - } - print '';*/ - - // Dev in progress + // Recurring event $userepeatevent = ($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0); if ($userepeatevent) { // Repeat - print ''; + //print ''; + print '        
    '; + print img_picto($langs->trans("Recurrence"), 'recurring', 'class="paddingright2"'); print ''; $selectedrecurrulefreq = 'no'; $selectedrecurrulebymonthday = ''; @@ -1120,34 +1084,51 @@ if ($action == 'create') { }); }); '; - print ''; + print '
    '; + //print ''; } - // Status - print ''.$langs->trans("Status").' / '.$langs->trans("Percentage").''; - print ''; - $percent = $complete !=='' ? $complete : -1; - if (GETPOSTISSET('status')) { - $percent = GETPOST('status'); - } elseif (GETPOSTISSET('percentage')) { - $percent = GETPOST('percentage', 'int'); - } else { - if ($complete == '0' || GETPOST("afaire") == 1) { - $percent = '0'; - } elseif ($complete == 100 || GETPOST("afaire") == 2) { - $percent = 100; - } - } - $formactions->form_select_status_action('formaction', $percent, 1, 'complete', 0, 0, 'maxwidth200'); print ''; - // Location - if (empty($conf->global->AGENDA_DISABLE_LOCATION)) { - print ''.$langs->trans("Location").''; + $datep = ($datep ? $datep : (is_null($object->datep) ? '' : $object->datep)); + if (GETPOST('datep', 'int', 1)) { + $datep = dol_stringtotime(GETPOST('datep', 'int', 1), 'tzuser'); + } + $datef = ($datef ? $datef : $object->datef); + if (GETPOST('datef', 'int', 1)) { + $datef = dol_stringtotime(GETPOST('datef', 'int', 1), 'tzuser'); + } + if (empty($datef) && !empty($datep)) { + if (GETPOST("actioncode", 'aZ09') == 'AC_RDV' || empty($conf->global->AGENDA_USE_EVENT_TYPE_DEFAULT)) { + $datef = dol_time_plus_duree($datep, (empty($conf->global->AGENDA_AUTOSET_END_DATE_WITH_DELTA_HOURS) ? 1 : $conf->global->AGENDA_AUTOSET_END_DATE_WITH_DELTA_HOURS), 'h'); + } } + // Date start + print ''; + /* + print ''.$langs->trans("DateActionStart").''; + print ' - '; + print ''.$langs->trans("DateActionEnd").''; + */ + print ''; + if (GETPOST("afaire") == 1) { + print $form->selectDate($datep, 'ap', 1, 1, 0, "action", 1, 2, 0, 'fulldaystart', '', '', '', 1, '', '', 'tzuserrel'); // Empty value not allowed for start date and hours if "todo" + } else { + print $form->selectDate($datep, 'ap', 1, 1, 1, "action", 1, 2, 0, 'fulldaystart', '', '', '', 1, '', '', 'tzuserrel'); + } + print '     -     '; + if (GETPOST("afaire") == 1) { + print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 0, 0, 'fulldayend', '', '', '', 1, '', '', 'tzuserrel'); + } else { + print $form->selectDate($datef, 'p2', 1, 1, 1, "action", 1, 0, 0, 'fulldayend', '', '', '', 1, '', '', 'tzuserrel'); + } + print ''; + + print ' '; + // Assigned to - print ''.$langs->trans("ActionAffectedTo").''; + print ''.$langs->trans("ActionAffectedTo").''; $listofuserid = array(); $listofcontactid = array(); $listofotherid = array(); @@ -1181,7 +1162,30 @@ if ($action == 'create') { print ''; } - if ($conf->categorie->enabled) { + // Location + if (empty($conf->global->AGENDA_DISABLE_LOCATION)) { + print ''.$langs->trans("Location").''; + } + + // Status + print ''.$langs->trans("Status").' / '.$langs->trans("Percentage").''; + print ''; + $percent = $complete !=='' ? $complete : -1; + if (GETPOSTISSET('status')) { + $percent = GETPOST('status'); + } elseif (GETPOSTISSET('percentage')) { + $percent = GETPOST('percentage', 'int'); + } else { + if ($complete == '0' || GETPOST("afaire") == 1) { + $percent = '0'; + } elseif ($complete == 100 || GETPOST("afaire") == 2) { + $percent = 100; + } + } + $formactions->form_select_status_action('formaction', $percent, 1, 'complete', 0, 0, 'maxwidth200'); + print ''; + + if (!empty($conf->categorie->enabled)) { // Categories print ''.$langs->trans("Categories").''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_ACTIONCOMM, '', 'parent', 64, 0, 1); @@ -1197,7 +1201,7 @@ if ($action == 'create') { print ''; - if ($conf->societe->enabled) { + if (!empty($conf->societe->enabled)) { // Related company print ''; + print 'global->AGENDA_USE_EVENT_TYPE) ? ' class="fieldrequired titlefieldcreate"' : '').'>'.$langs->trans("Title").''; // Full day event - print ''; + print ''; - - // Dev in progress + // Recurring event $userepeatevent = ($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0); if ($userepeatevent) { // Repeat - print ''; + print ''; + //print ''; } - - // Status - print ''; - // Location - if (empty($conf->global->AGENDA_DISABLE_LOCATION)) { - print ''; + // Date start - end + print ''; + + print ''; // Assigned to $listofuserid = array(); // User assigned @@ -1678,8 +1680,20 @@ if ($id > 0) { print $form->select_dolusers($object->userdoneid > 0 ? $object->userdoneid : -1, 'doneby', 1); print ''; } + + // Location + if (empty($conf->global->AGENDA_DISABLE_LOCATION)) { + print ''; + } + + // Status + print ''; + // Tags-Categories - if ($conf->categorie->enabled) { + if (!empty($conf->categorie->enabled)) { print ''; +} + + +print '
    '.$langs->trans("ActionOnCompany").''; if (GETPOST('socid', 'int') > 0) { @@ -1523,6 +1527,7 @@ if ($id > 0) { if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) { print '
    '.$langs->trans("Type").''; if ($object->type_code != 'AC_OTH_AUTO') { + print img_picto($langs->trans("ActionType"), 'square', 'class="fawidth30 inline-block" style="color: #ddd;"'); print $formactions->select_type_actions(GETPOST("actioncode", 'aZ09') ? GETPOST("actioncode", 'aZ09') : $object->type_code, "actioncode", "systemauto", 0, 0, 0, 1); } else { print ''; @@ -1533,40 +1538,19 @@ if ($id > 0) { } // Title - print '
    '.$langs->trans("Title").'
    '.$langs->trans("EventOnFullDay").'fulldayevent ? ' checked' : '').'>
    '.$langs->trans("Date").'fulldayevent ? ' checked' : '').'>'; + print ''; - // Date start - end - print '
    '; - print ''.$langs->trans("DateActionStart").''; - print ' - '; - print 'type_code == 'AC_RDV' ? ' class="fieldrequired"' : '').'>'.$langs->trans("DateActionEnd").''; - print ''; - $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT'); - if (GETPOST("afaire") == 1) { - print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 0, "action", 1, 1, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); - } elseif (GETPOST("afaire") == 2) { - print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 1, "action", 1, 1, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); - } else { - print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 1, "action", 1, 1, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); - } - print ' - '; - if (GETPOST("afaire") == 1) { - print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); - } elseif (GETPOST("afaire") == 2) { - print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); - } else { - print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 1, 0, 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); - } - print '
    '; + //print '
    '; + print '        
    '; + print img_picto($langs->trans("Recurrence"), 'recurring', 'class="paddingright2"'); print ''; $selectedrecurrulefreq = 'no'; $selectedrecurrulebymonthday = ''; @@ -1615,19 +1599,37 @@ if ($id > 0) { }); }); '; - print '
    '.$langs->trans("Status").' / '.$langs->trans("Percentage").''; - $percent = GETPOSTISSET("percentage") ? GETPOST("percentage", "int") : $object->percentage; - $formactions->form_select_status_action('formaction', $percent, 1, 'complete', 0, 0, 'maxwidth200'); print '
    '.$langs->trans("Location").'
    '; + /*print ''.$langs->trans("DateActionStart").''; + print ' - '; + print 'type_code == 'AC_RDV' ? ' class="fieldrequired"' : '').'>'.$langs->trans("DateActionEnd").''; + */ + print ''; + $tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT'); + if (GETPOST("afaire") == 1) { + print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 0, "action", 1, 1, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); + } elseif (GETPOST("afaire") == 2) { + print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 1, "action", 1, 1, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); + } else { + print $form->selectDate($datep ? $datep : $object->datep, 'ap', 1, 1, 1, "action", 1, 1, 0, 'fulldaystart', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); } + print '     -     '; + if (GETPOST("afaire") == 1) { + print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 0, 0, 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); + } elseif (GETPOST("afaire") == 2) { + print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 0, 0, 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); + } else { + print $form->selectDate($datef ? $datef : $object->datef, 'p2', 1, 1, 1, "action", 1, 0, 0, 'fulldayend', '', '', '', 1, '', '', $object->fulldayevent ? ($tzforfullday ? $tzforfullday : 'tzuserrel') : 'tzuserrel'); + } + print '
     
    '.$langs->trans("Location").'
    '.$langs->trans("Status").' / '.$langs->trans("Percentage").''; + $percent = GETPOSTISSET("percentage") ? GETPOST("percentage", "int") : $object->percentage; + $formactions->form_select_status_action('formaction', $percent, 1, 'complete', 0, 0, 'maxwidth200'); + print '
    '.$langs->trans("Categories").''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_ACTIONCOMM, '', 'parent', 64, 0, 1); $c = new Categorie($db); @@ -1700,7 +1714,7 @@ if ($id > 0) { print ''; - if ($conf->societe->enabled) { + if (!empty($conf->societe->enabled)) { // Related company print ''; print ''; @@ -1898,7 +1912,7 @@ if ($id > 0) { $linkback = ''; // Link to other agenda views $linkback .= ''; - $linkback .= img_picto($langs->trans("BackToList"), 'object_list', 'class="pictoactionview pictofixedwidth"'); + $linkback .= img_picto($langs->trans("BackToList"), 'object_calendarlist', 'class="pictoactionview pictofixedwidth"'); $linkback .= ''.$langs->trans("BackToList").''; $linkback .= ''; $linkback .= ''; @@ -2085,7 +2099,7 @@ if ($id > 0) { } // Categories - if ($conf->categorie->enabled) { + if (!empty($conf->categorie->enabled)) { print '"; @@ -2100,7 +2114,7 @@ if ($id > 0) { print '
    '; print '
    '.$langs->trans("ActionOnCompany").''; @@ -1786,7 +1800,7 @@ if ($id > 0) { print '
    '.$langs->trans("Description").''; // Editeur wysiwyg require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('note', $object->note_private, '', 200, 'dolibarr_notes', 'In', true, true, $conf->fckeditor->enabled, ROWS_5, '90%'); + $doleditor = new DolEditor('note', $object->note_private, '', 120, 'dolibarr_notes', 'In', true, true, $conf->fckeditor->enabled, ROWS_4, '90%'); $doleditor->Create(); print '
    '.$langs->trans("Categories").''; print $form->showCategories($object->id, Categorie::TYPE_ACTIONCOMM, 1); print "
    '; - if ($conf->societe->enabled) { + if (!empty($conf->societe->enabled)) { // Related company print ''; -print "\n"; +print ''."\n"; +$totalarray = array(); +$totalarray['nbfield'] = 0; + +// Fields title label +// -------------------------------------------------------------------- print ''; if (!empty($arrayfields['a.id']['checked'])) { print_liste_field_titre($arrayfields['a.id']['label'], $_SERVER["PHP_SELF"], "a.id", $param, "", "", $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['owner']['checked'])) { print_liste_field_titre($arrayfields['owner']['label'], $_SERVER["PHP_SELF"], "", $param, "", "", $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['c.libelle']['checked'])) { print_liste_field_titre($arrayfields['c.libelle']['label'], $_SERVER["PHP_SELF"], "c.libelle", $param, "", "", $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['a.label']['checked'])) { print_liste_field_titre($arrayfields['a.label']['label'], $_SERVER["PHP_SELF"], "a.label", $param, "", "", $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['a.note']['checked'])) { print_liste_field_titre($arrayfields['a.note']['label'], $_SERVER["PHP_SELF"], "a.note", $param, "", "", $sortfield, $sortorder); + $totalarray['nbfield']++; } //if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) if (!empty($arrayfields['a.datep']['checked'])) { print_liste_field_titre($arrayfields['a.datep']['label'], $_SERVER["PHP_SELF"], "a.datep,a.id", $param, '', 'align="center"', $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['a.datep2']['checked'])) { print_liste_field_titre($arrayfields['a.datep2']['label'], $_SERVER["PHP_SELF"], "a.datep2", $param, '', 'align="center"', $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['s.nom']['checked'])) { print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"], "s.nom", $param, "", "", $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['a.fk_contact']['checked'])) { print_liste_field_titre($arrayfields['a.fk_contact']['label'], $_SERVER["PHP_SELF"], "", $param, "", "", $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['a.fk_element']['checked'])) { print_liste_field_titre($arrayfields['a.fk_element']['label'], $_SERVER["PHP_SELF"], "", $param, "", "", $sortfield, $sortorder); + $totalarray['nbfield']++; } - // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; - // Hook fields $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook @@ -842,18 +860,21 @@ print $hookmanager->resPrint; if (!empty($arrayfields['a.datec']['checked'])) { print_liste_field_titre($arrayfields['a.datec']['label'], $_SERVER["PHP_SELF"], "a.datec,a.id", $param, "", 'align="center"', $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['a.tms']['checked'])) { print_liste_field_titre($arrayfields['a.tms']['label'], $_SERVER["PHP_SELF"], "a.tms,a.id", $param, "", 'align="center"', $sortfield, $sortorder); + $totalarray['nbfield']++; } if (!empty($arrayfields['a.percent']['checked'])) { print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "a.percent", $param, "", 'align="center"', $sortfield, $sortorder); + $totalarray['nbfield']++; } print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', 'align="center"', $sortfield, $sortorder, 'maxwidthsearch '); +$totalarray['nbfield']++; print "\n"; -$contactstatic = new Contact($db); $now = dol_now(); $delay_warning = $conf->global->MAIN_DELAY_ACTIONS_TODO * 24 * 60 * 60; @@ -862,8 +883,20 @@ $caction = new CActionComm($db); $arraylist = $caction->liste_array(1, 'code', '', (empty($conf->global->AGENDA_USE_EVENT_TYPE) ? 1 : 0), '', 1); $contactListCache = array(); -while ($i < min($num, $limit)) { +// Loop on record +// -------------------------------------------------------------------- +$i = 0; +//$savnbfield = $totalarray['nbfield']; +//$totalarray['nbfield'] = 0; +$imaxinloop = ($limit ? min($num, $limit) : $num); +while ($i < $imaxinloop) { $obj = $db->fetch_object($resql); + if (empty($obj)) { + break; // Should not happen + } + + // Store properties in $object + $object->setVarsFromFetchObj($obj); // Discard auto action if option is on if (!empty($conf->global->AGENDA_ALWAYS_HIDE_AUTO) && $obj->type_code == 'AC_OTH_AUTO') { @@ -943,8 +976,8 @@ while ($i < min($num, $limit)) { // Description if (!empty($arrayfields['a.note']['checked'])) { print ''; } @@ -1080,12 +1113,20 @@ while ($i < min($num, $limit)) { } print ''; - print "\n"; + print ''."\n"; + $i++; } -print "
    '.$langs->trans("ActionOnCompany").''.($object->thirdparty->id ? $object->thirdparty->getNomUrl(1) : (''.$langs->trans("None").'')); if (is_object($object->thirdparty) && $object->thirdparty->id > 0 && $object->type_code == 'AC_TEL') { diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index a5c8a11ade0..19eb35376cd 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -123,16 +123,17 @@ class ActionComm extends CommonObject */ public $label; + /** + * @var string Agenda event label + * @deprecated Use $label + */ + public $libelle; + /** * @var integer Date creation record (datec) */ public $datec; - /** - * @var integer Date end record (datef) - */ - public $datef; - /** * @var integer Duration (duree) */ @@ -172,6 +173,21 @@ class ActionComm extends CommonObject */ public $datep; + /** + * @var integer Date action end (datef) + */ + public $datef; + + /** + * @var integer This is date start action (datep) but modified to not be outside calendar view. + */ + public $date_start_in_calendar; + + /** + * @var integer This is date end action (datef) but modified to not be outside calendar view. + */ + public $date_end_in_calendar; + /** * @var integer Date action end (datep2) */ @@ -188,6 +204,11 @@ class ActionComm extends CommonObject */ public $fulldayevent = 0; + /** + * @var int 1=??? + */ + public $ponctuel; + /** * @var integer Percentage */ @@ -219,8 +240,7 @@ class ActionComm extends CommonObject public $userownerid; /** - * @var int Id of user done (deprecated) - * @deprecated + * @var int Id of user that has done the event. Used only if AGENDA_ENABLE_DONEBY is set. */ public $userdoneid; @@ -239,20 +259,6 @@ class ActionComm extends CommonObject */ public $reminders = array(); - /** - * @var User Object user of owner - * @deprecated - * @see $userownerid - */ - public $usertodo; - - /** - * @var User Object user that did action - * @deprecated - * @see $userdoneid - */ - public $userdone; - /** * @var int thirdparty id linked to action */ @@ -383,6 +389,9 @@ class ActionComm extends CommonObject const EVENT_FINISHED = 100; + public $fields = array(); + + /** * Constructor * @@ -772,7 +781,7 @@ class ActionComm extends CommonObject $sql .= " a.fk_contact, a.percent as percentage,"; $sql .= " a.fk_element as elementid, a.elementtype,"; $sql .= " a.priority, a.fulldayevent, a.location, a.transparency,"; - $sql .= " a.email_msgid, a.email_subject, a.email_from, a.email_to, a.email_tocc, a.email_tobcc, a.errors_to,"; + $sql .= " a.email_msgid, a.email_subject, a.email_from, a.email_sender, a.email_to, a.email_tocc, a.email_tobcc, a.errors_to,"; $sql .= " c.id as type_id, c.type as type_type, c.code as type_code, c.libelle as type_label, c.color as type_color, c.picto as type_picto,"; $sql .= " s.nom as socname,"; $sql .= " u.firstname, u.lastname as lastname,"; @@ -831,18 +840,17 @@ class ActionComm extends CommonObject $this->usermodid = $obj->fk_user_mod; if (!is_object($this->author)) { - $this->author = new stdClass(); // To avoid warning + $this->author = new User($this->db); // To avoid warning } $this->author->id = $obj->fk_user_author; // deprecated $this->author->firstname = $obj->firstname; // deprecated $this->author->lastname = $obj->lastname; // deprecated if (!is_object($this->usermod)) { - $this->usermod = new stdClass(); // To avoid warning + $this->usermod = new User($this->db); // To avoid warning } $this->usermod->id = $obj->fk_user_mod; // deprecated $this->userownerid = $obj->fk_user_action; - $this->userdoneid = $obj->fk_user_done; $this->priority = $obj->priority; $this->fulldayevent = $obj->fulldayevent; $this->location = $obj->location; @@ -863,6 +871,16 @@ class ActionComm extends CommonObject $this->event_paid = $obj->event_paid; $this->status = $obj->status; + //email information + $this->email_msgid=$obj->email_msgid; + $this->email_from=$obj->email_from; + $this->email_sender=$obj->email_sender; + $this->email_to=$obj->email_to; + $this->email_tocc=$obj->email_tocc; + $this->email_tobcc=$obj->email_tobcc; + $this->email_subject=$obj->email_subject; + $this->errors_to=$obj->errors_to; + $this->fetch_optionals(); if ($loadresources) { @@ -1142,18 +1160,18 @@ class ActionComm extends CommonObject $sql .= ", datep2 = ".(strval($this->datef) != '' ? "'".$this->db->idate($this->datef)."'" : 'null'); $sql .= ", durationp = ".(isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '' ? "'".$this->db->escape($this->durationp)."'" : "null"); // deprecated $sql .= ", note = '".$this->db->escape($this->note_private)."'"; - $sql .= ", fk_project =".($this->fk_project > 0 ? $this->fk_project : "null"); - $sql .= ", fk_soc =".($socid > 0 ? $socid : "null"); - $sql .= ", fk_contact =".($contactid > 0 ? $contactid : "null"); + $sql .= ", fk_project =".($this->fk_project > 0 ? ((int) $this->fk_project) : "null"); + $sql .= ", fk_soc =".($socid > 0 ? ((int) $socid) : "null"); + $sql .= ", fk_contact =".($contactid > 0 ? ((int) $contactid) : "null"); $sql .= ", priority = '".$this->db->escape($this->priority)."'"; $sql .= ", fulldayevent = '".$this->db->escape($this->fulldayevent)."'"; $sql .= ", location = ".($this->location ? "'".$this->db->escape($this->location)."'" : "null"); $sql .= ", transparency = '".$this->db->escape($this->transparency)."'"; - $sql .= ", fk_user_mod = ".$user->id; - $sql .= ", fk_user_action = ".($userownerid > 0 ? "'".$this->db->escape($userownerid)."'" : "null"); - $sql .= ", fk_user_done = ".($userdoneid > 0 ? "'".$this->db->escape($userdoneid)."'" : "null"); + $sql .= ", fk_user_mod = ".((int) $user->id); + $sql .= ", fk_user_action = ".($userownerid > 0 ? ((int) $userownerid) : "null"); + $sql .= ", fk_user_done = ".($userdoneid > 0 ? ((int) $userdoneid) : "null"); if (!empty($this->fk_element)) { - $sql .= ", fk_element=".($this->fk_element ? $this->db->escape($this->fk_element) : "null"); + $sql .= ", fk_element=".($this->fk_element ? ((int) $this->fk_element) : "null"); } if (!empty($this->elementtype)) { $sql .= ", elementtype=".($this->elementtype ? "'".$this->db->escape($this->elementtype)."'" : "null"); @@ -1213,11 +1231,14 @@ class ActionComm extends CommonObject if (!empty($this->socpeopleassigned)) { $already_inserted = array(); - foreach (array_keys($this->socpeopleassigned) as $id) { + foreach (array_keys($this->socpeopleassigned) as $key => $val) { + if (!is_array($val)) { // For backward compatibility when val=id + $val = array('id'=>$val); + } if (!empty($already_inserted[$val['id']])) continue; $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)"; - $sql .= " VALUES(".((int) $this->id).", 'socpeople', ".((int) $id).", 0, 0, 0)"; + $sql .= " VALUES(".((int) $this->id).", 'socpeople', ".((int) $val['id']).", 0, 0, 0)"; $resql = $this->db->query($sql); if (!$resql) { @@ -1451,9 +1472,9 @@ class ActionComm extends CommonObject /** - * Return label of status + * Return the label of the status * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @param int $mode 0=Long label, 1=Short label, 2=Picto+Short label, 3=Picto, 4=Picto+Short label, 5=Short label+Picto, 6=Picto+Long label, 7=Very short label+Picto * @param int $hidenastatus 1=Show nothing if status is "Not applicable" * @return string String with status */ @@ -1585,8 +1606,25 @@ class ActionComm extends CommonObject if (isset($this->transparency)) { $tooltip .= '
    '.$langs->trans('Busy').': '.yn($this->transparency); } + if (!empty($this->email_msgid)) { + $langs->load("mails"); + $tooltip .= '
    '; + //$tooltip .= '
    '.img_picto('', 'email').' '.$langs->trans("Email").''; + $tooltip .= '
    '.$langs->trans('MailTopic').': '.$this->email_subject; + $tooltip .= '
    '.$langs->trans('MailFrom').': '.str_replace(array('<', '>'), array('&lt', '&gt'), $this->email_from); + $tooltip .= '
    '.$langs->trans('MailTo').': '.str_replace(array('<', '>'), array('&lt', '&gt'), $this->email_to); + if (!empty($this->email_tocc)) { + $tooltip .= '
    '.$langs->trans('MailCC').': '.str_replace(array('<', '>'), array('&lt', '&gt'), $this->email_tocc); + } + /* Disabled because bcc must remain by defintion not visible + if (!empty($this->email_tobcc)) { + $tooltip .= '
    '.$langs->trans('MailCCC').': '.$this->email_tobcc; + } */ + } if (!empty($this->note_private)) { - $tooltip .= '
    '.$langs->trans('Note').': '.(dol_textishtml($this->note_private) ? str_replace(array("\r", "\n"), "", $this->note_private) : str_replace(array("\r", "\n"), '
    ', $this->note_private)); + $tooltip .= '

    '.$langs->trans('Description').':
    '; + $texttoshow = dolGetFirstLineOfText($this->note_private, 10); + $tooltip .= (dol_textishtml($texttoshow) ? str_replace(array("\r", "\n"), "", $texttoshow) : str_replace(array("\r", "\n"), '
    ', $texttoshow)); } $linkclose = ''; //if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && $this->type_color) @@ -1597,15 +1635,8 @@ class ActionComm extends CommonObject $label = $langs->trans("ShowAction"); $linkclose .= ' alt="'.dol_escape_htmltag($tooltip, 1).'"'; } - $linkclose .= ' title="'.dol_escape_htmltag($tooltip, 1).'"'; + $linkclose .= ' title="'.dol_escape_htmltag($tooltip, 1, 0, '', 1).'"'; $linkclose .= ' class="'.$classname.' classfortooltip"'; - - /* - $hookmanager->initHooks(array('actiondao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - $linkclose = ($hookmanager->resPrint ? $hookmanager->resPrint : $linkclose); - */ } else { $linkclose .= ' class="'.$classname.'"'; } @@ -1640,41 +1671,39 @@ class ActionComm extends CommonObject } if ($withpicto == 2) { - $libelle = $label; if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) { - $libelle = $labeltype; + $label = $labeltype; } - $libelleshort = ''; + $labelshort = ''; } else { - $libelle = (empty($this->libelle) ? $label : $this->libelle.(($label && $label != $this->libelle) ? ' '.$label : '')); - if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && empty($libelle)) { - $libelle = $labeltype; + if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && empty($label)) { + $label = $labeltype; } if ($maxlength < 0) { - $libelleshort = $this->ref; + $labelshort = $this->ref; } else { - $libelleshort = dol_trunc($libelle, $maxlength); + $labelshort = dol_trunc($label, $maxlength); } } if ($withpicto) { if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) { // Add code into () if ($labeltype) { - $libelle .= (preg_match('/'.preg_quote($labeltype, '/').'/', $libelle) ? '' : ' ('.$langs->transnoentities("Action".$this->type_code).')'); + $label .= (preg_match('/'.preg_quote($labeltype, '/').'/', $label) ? '' : ' ('.$langs->transnoentities("Action".$this->type_code).')'); } } } $result .= $linkstart; if ($withpicto) { - $result .= img_object(($notooltip ? '' : $langs->trans("ShowAction").': '.$libelle), ($overwritepicto ? $overwritepicto : 'action'), (($this->type_color && $overwritepicto) ? 'style="color: #'.$this->type_color.' !important;" ' : '').($notooltip ? 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"' : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= img_object(($notooltip ? '' : $langs->trans("ShowAction").': '.$label), ($overwritepicto ? $overwritepicto : 'action'), (($this->type_color && $overwritepicto) ? 'style="color: #'.$this->type_color.' !important;" ' : '').($notooltip ? 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"' : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); } - $result .= $libelleshort; + $result .= $labelshort; $result .= $linkend; global $action; $hookmanager->initHooks(array('actiondao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; @@ -2215,6 +2244,26 @@ class ActionComm extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $dbs Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $dbs, $origin_id, $dest_id) + { + $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'actioncomm SET fk_element = ' . ((int) $dest_id) . ' WHERE elementtype="product" AND fk_element = '.((int) $origin_id); + // using $dbs, not $this->db because function is static + if (!$dbs->query($sql)) { + //$this->errors = $dbs->lasterror(); + return false; + } + + return true; + } + /** * Is the action delayed? * diff --git a/htdocs/comm/action/class/actioncommreminder.class.php b/htdocs/comm/action/class/actioncommreminder.class.php index aa693d2e41f..ff242430b0a 100644 --- a/htdocs/comm/action/class/actioncommreminder.class.php +++ b/htdocs/comm/action/class/actioncommreminder.class.php @@ -205,9 +205,9 @@ class ActionCommReminder extends CommonObject } /** - * Retourne le libelle du status d'un user (actif, inactif) + * Return label of the status of a reminder * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto * @return string Label of status */ public function getLibStatut($mode = 0) diff --git a/htdocs/comm/action/class/ical.class.php b/htdocs/comm/action/class/ical.class.php index 5449975e777..7ab09e8d891 100644 --- a/htdocs/comm/action/class/ical.class.php +++ b/htdocs/comm/action/class/ical.class.php @@ -25,6 +25,7 @@ * \brief File of class to parse ical calendars */ require_once DOL_DOCUMENT_ROOT.'/core/lib/xcal.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; /** @@ -39,6 +40,7 @@ class ICal public $todo_count; // Number of Todos public $freebusy_count; // Number of Freebusy public $last_key; //Help variable save last key (multiline string) + public $error; /** @@ -61,11 +63,15 @@ class ICal $this->file = $file; $file_text = ''; - $tmparray = file($file); - if (is_array($tmparray)) { - $file_text = join("", $tmparray); //load file - $file_text = preg_replace("/[\r\n]{1,} /", "", $file_text); + $tmpresult = getURLContent($file, 'GET'); + if ($tmpresult['http_code'] != 200) { + $file_text = ''; + $this->error = 'Error: '.$tmpresult['http_code'].' '.$tmpresult['content']; + } else { + $file_text = preg_replace("/[\r\n]{1,} /", "", $tmpresult['content']); } + //var_dump($tmpresult); + return $file_text; // return all text } @@ -396,19 +402,19 @@ class ICal public function get_event_list() { // phpcs:enable - return (!empty($this->cal['VEVENT']) ? $this->cal['VEVENT'] : ''); + return (empty($this->cal['VEVENT']) ? '' : $this->cal['VEVENT']); } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Return eventlist array (not sort eventlist array) + * Return freebusy array (not sort eventlist array) * * @return array */ public function get_freebusy_list() { // phpcs:enable - return $this->cal['VFREEBUSY']; + return (empty($this->cal['VFREEBUSY']) ? '' : $this->cal['VFREEBUSY']); } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps diff --git a/htdocs/comm/action/document.php b/htdocs/comm/action/document.php index 3de00e9cb6f..38779e300ed 100644 --- a/htdocs/comm/action/document.php +++ b/htdocs/comm/action/document.php @@ -139,7 +139,7 @@ if ($object->id > 0) { print dol_get_fiche_head($head, 'documents', $langs->trans("Action"), -1, 'action'); - $linkback = img_picto($langs->trans("BackToList"), 'object_list', 'class="hideonsmartphone pictoactionview"'); + $linkback = img_picto($langs->trans("BackToList"), 'object_calendarlist', 'class="hideonsmartphone pictoactionview"'); $linkback .= ''.$langs->trans("BackToList").''; // Link to other agenda views diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 419d98dbef8..ec80dc90a4c 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -49,6 +49,8 @@ if (empty($conf->global->AGENDA_EXT_NB)) { } $MAXAGENDA = $conf->global->AGENDA_EXT_NB; +$disabledefaultvalues = GETPOST('disabledefaultvalues', 'int'); + $check_holiday = GETPOST('check_holiday', 'int'); $filter = GETPOST("search_filter", 'alpha', 3) ? GETPOST("search_filter", 'alpha', 3) : GETPOST("filter", 'alpha', 3); $filtert = GETPOST("search_filtert", "int", 3) ? GETPOST("search_filtert", "int", 3) : GETPOST("filtert", "int", 3); @@ -110,7 +112,7 @@ $week = GETPOST("week", "int") ?GETPOST("week", "int") : date("W"); $day = GETPOST("day", "int") ?GETPOST("day", "int") : date("d"); $pid = GETPOST("search_projectid", "int", 3) ? GETPOST("search_projectid", "int", 3) : GETPOST("projectid", "int", 3); $status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo' -$type = GETPOSTISSET("search_type", 'aZ09') ? GETPOST("search_type", 'aZ09') : GETPOST("type", 'aZ09'); +$type = GETPOSTISSET("search_type") ? GETPOST("search_type", 'aZ09') : GETPOST("type", 'aZ09'); $maxprint = GETPOSTISSET("maxprint") ? GETPOST("maxprint", 'int') : $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW; $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') @@ -128,14 +130,11 @@ if (GETPOST('search_actioncode', 'array:aZ09')) { $actioncode = '0'; } } else { - $actioncode = GETPOST("search_actioncode", "alpha", 3) ?GETPOST("search_actioncode", "alpha", 3) : (GETPOST("search_actioncode") == '0' ? '0' : (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE)); -} -if ($actioncode == '' && empty($actioncodearray)) { - $actioncode = (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE); + $actioncode = GETPOST("search_actioncode", "alpha", 3) ?GETPOST("search_actioncode", "alpha", 3) : (GETPOST("search_actioncode") == '0' ? '0' : ((empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE) || $disabledefaultvalues) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE)); } if ($status == '' && !GETPOSTISSET('search_status')) { - $status = (empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); + $status = ((empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS) || $disabledefaultvalues) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); } $defaultview = (empty($conf->global->AGENDA_DEFAULT_VIEW) ? 'show_month' : $conf->global->AGENDA_DEFAULT_VIEW); @@ -277,12 +276,12 @@ if (empty($conf->global->AGENDA_DISABLE_EXT)) { if (!empty($conf->global->$source) && !empty($conf->global->$name)) { // Note: $conf->global->buggedfile can be empty or 'uselocalandtznodaylight' or 'uselocalandtzdaylight' $listofextcals[] = array( - 'src'=>$conf->global->$source, - 'name'=>$conf->global->$name, + 'src' => getDolGlobalString($source), + 'name' => getDolGlobalString($name), 'offsettz' => (!empty($conf->global->$offsettz) ? $conf->global->$offsettz : 0), - 'color'=>$conf->global->$color, - 'default'=>$conf->global->$default, - 'buggedfile'=>(isset($conf->global->buggedfile) ? $conf->global->buggedfile : 0) + 'color' => getDolGlobalString($color), + 'default' => getDolGlobalString($default), + 'buggedfile' => (isset($conf->global->buggedfile) ? $conf->global->buggedfile : 0) ); } } @@ -302,12 +301,12 @@ if (empty($user->conf->AGENDA_DISABLE_EXT)) { if (!empty($user->conf->$source) && !empty($user->conf->$name)) { // Note: $conf->global->buggedfile can be empty or 'uselocalandtznodaylight' or 'uselocalandtzdaylight' $listofextcals[] = array( - 'src'=>$user->conf->$source, - 'name'=>$user->conf->$name, + 'src' => $user->conf->$source, + 'name' => $user->conf->$name, 'offsettz' => (!empty($user->conf->$offsettz) ? $user->conf->$offsettz : 0), - 'color'=>$user->conf->$color, - 'default'=>$user->conf->$default, - 'buggedfile'=>(isset($user->conf->buggedfile) ? $user->conf->buggedfile : 0) + 'color' => $user->conf->$color, + 'default' => $user->conf->$default, + 'buggedfile' => (isset($user->conf->buggedfile) ? $user->conf->buggedfile : 0) ); } } @@ -397,7 +396,7 @@ if ($actioncode || GETPOSTISSET('search_actioncode')) { if ($resourceid > 0) { $param .= "&search_resourceid=".urlencode($resourceid); } -if ($status || GETPOSTISSET('status')) { +if ($status || GETPOSTISSET('status') || GETPOSTISSET('search_status')) { $param .= "&search_status=".urlencode($status); } if ($filter) { @@ -498,7 +497,7 @@ print ''; $viewmode = ''; $viewmode .= ''; //$viewmode .= ''; -$viewmode .= img_picto($langs->trans("List"), 'object_list', 'class="imgforviewmode pictoactionview block"'); +$viewmode .= img_picto($langs->trans("List"), 'object_calendarlist', 'class="imgforviewmode pictoactionview block"'); //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewList").''; @@ -622,7 +621,7 @@ if (!empty($conf->use_javascript_ajax)) { // If javascript on $s .= '
     
    '; // Calendars from hooks - $parameters = array(); $object = null; + $parameters = array(); $reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action); if (empty($reshook)) { $s .= $hookmanager->resPrint; @@ -860,10 +859,6 @@ if ($resql) { } else { $event->date_end_in_calendar = $event->datep; } - // Define ponctual property - if ($event->date_start_in_calendar == $event->date_end_in_calendar) { - $event->ponctuel = 1; - } // Check values if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) { @@ -935,7 +930,7 @@ if ($showbirthday) { $sql = 'SELECT sp.rowid, sp.lastname, sp.firstname, sp.birthday'; $sql .= ' FROM '.MAIN_DB_PREFIX.'socpeople as sp'; $sql .= ' WHERE (priv=0 OR (priv=1 AND fk_user_creat='.((int) $user->id).'))'; - $sql .= " AND sp.entity IN (".getEntity('socpeople').")"; + $sql .= " AND sp.entity IN (".getEntity('contact').")"; if ($mode == 'show_day') { $sql .= ' AND MONTH(birthday) = '.((int) $month); $sql .= ' AND DAY(birthday) = '.((int) $day); @@ -975,7 +970,6 @@ if ($showbirthday) { $event->date_start_in_calendar = $db->jdate($event->datep); $event->date_end_in_calendar = $db->jdate($event->datef); - $event->ponctuel = 0; // Add an entry in eventarray for each day $daycursor = $event->datep; @@ -1196,7 +1190,8 @@ if (count($listofextcals)) { foreach ($icalevents as $icalevent) { //var_dump($icalevent); - //print $icalevent['SUMMARY'].'->'.var_dump($icalevent).'
    ';exit; + //print $icalevent['SUMMARY'].'->'; + //var_dump($icalevent);exit; if (!empty($icalevent['RRULE'])) { continue; // We found a repeatable event. It was already split into unitary events, so we discard general rule. } @@ -1218,7 +1213,7 @@ if (count($listofextcals)) { $addevent = true; } elseif (!is_array($icalevent['DTSTART'])) { // not fullday event (DTSTART is not array. It is a value like '19700101T000000Z' for 00:00 in greenwitch) $datestart = $icalevent['DTSTART']; - $dateend = $icalevent['DTEND']; + $dateend = empty($icalevent['DTEND']) ? $datestart : $icalevent['DTEND']; $datestart += +($offsettz * 3600); $dateend += +($offsettz * 3600); @@ -1318,12 +1313,6 @@ if (count($listofextcals)) { $event->date_end_in_calendar = $event->datep; } - // Define ponctual property - if ($event->date_start_in_calendar == $event->date_end_in_calendar) { - $event->ponctuel = 1; - //print 'x'.$datestart.'-'.$dateend;exit; - } - // Add event into $eventarray if date range are ok. if ($event->date_end_in_calendar < $firstdaytoshow || $event->date_start_in_calendar >= $lastdaytoshow) { //print 'x'.$datestart.'-'.$dateend;exit; @@ -2030,7 +2019,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print '
    ('.dol_trunc($event->icalname, $maxnbofchar).')'; } - $thirdparty_id = ($event->thirdparty_id > 0 ? $event->thirdparty_id : ((is_object($event->societe) && $event->societe->id > 0) ? $event->societe->id : 0)); + $thirdparty_id = ($event->socid > 0 ? $event->socid : ((is_object($event->societe) && $event->societe->id > 0) ? $event->societe->id : 0)); $contact_id = ($event->contact_id > 0 ? $event->contact_id : ((is_object($event->contact) && $event->contact->id > 0) ? $event->contact->id : 0)); // If action related to company / contact diff --git a/htdocs/comm/action/info.php b/htdocs/comm/action/info.php index 225bc8b29fc..19f4c4bfa03 100644 --- a/htdocs/comm/action/info.php +++ b/htdocs/comm/action/info.php @@ -66,7 +66,7 @@ $object->info($object->id); $head = actions_prepare_head($object); print dol_get_fiche_head($head, 'info', $langs->trans("Action"), -1, 'action'); -$linkback = img_picto($langs->trans("BackToList"), 'object_list', 'class="hideonsmartphone pictoactionview"'); +$linkback = img_picto($langs->trans("BackToList"), 'object_calendarlist', 'class="hideonsmartphone pictoactionview"'); $linkback .= ''.$langs->trans("BackToList").''; // Link to other agenda views diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php index e2b412e15db..06e6684d99b 100644 --- a/htdocs/comm/action/list.php +++ b/htdocs/comm/action/list.php @@ -45,6 +45,11 @@ $langs->loadLangs(array("users", "companies", "agenda", "commercial", "other", " $action = GETPOST('action', 'aZ09'); $massaction = GETPOST('massaction', 'alpha'); $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'actioncommlist'; // To manage different context of search +$optioncss = GETPOST('optioncss', 'alpha'); +$toselect = GETPOST('toselect', 'array'); +$confirm = GETPOST('confirm', 'alpha'); + +$disabledefaultvalues = GETPOST('disabledefaultvalues', 'int'); $mode = GETPOST('mode', 'aZ09'); if (empty($mode) && preg_match('/show_/', $action)) { @@ -54,12 +59,9 @@ $resourceid = GETPOST("search_resourceid", "int") ?GETPOST("search_resourceid", $pid = GETPOST("search_projectid", 'int', 3) ?GETPOST("search_projectid", 'int', 3) : GETPOST("projectid", 'int', 3); $search_status = (GETPOST("search_status", 'aZ09') != '') ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); $type = GETPOST('search_type', 'alphanohtml') ?GETPOST('search_type', 'alphanohtml') : GETPOST('type', 'alphanohtml'); -$optioncss = GETPOST('optioncss', 'alpha'); $year = GETPOST("year", 'int'); $month = GETPOST("month", 'int'); $day = GETPOST("day", 'int'); -$toselect = GETPOST('toselect', 'array'); -$confirm = GETPOST('confirm', 'alpha'); // Set actioncode (this code must be same for setting actioncode into peruser, listacton and index) if (GETPOST('search_actioncode', 'array')) { @@ -68,11 +70,9 @@ if (GETPOST('search_actioncode', 'array')) { $actioncode = '0'; } } else { - $actioncode = GETPOST("search_actioncode", "alpha", 3) ?GETPOST("search_actioncode", "alpha", 3) : (GETPOST("search_actioncode") == '0' ? '0' : (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE)); -} -if ($actioncode == '' && empty($actioncodearray)) { - $actioncode = (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE); + $actioncode = GETPOST("search_actioncode", "alpha", 3) ?GETPOST("search_actioncode", "alpha", 3) : (GETPOST("search_actioncode") == '0' ? '0' : ((empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE) || $disabledefaultvalues) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE)); } + $search_id = GETPOST('search_id', 'alpha'); $search_title = GETPOST('search_title', 'alpha'); $search_note = GETPOST('search_note', 'alpha'); @@ -83,7 +83,7 @@ $datestart_dtend = dol_mktime(23, 59, 59, GETPOST('datestart_dtendmonth', 'int') $dateend_dtstart = dol_mktime(0, 0, 0, GETPOST('dateend_dtstartmonth', 'int'), GETPOST('dateend_dtstartday', 'int'), GETPOST('dateend_dtstartyear', 'int'), 'tzuserrel'); $dateend_dtend = dol_mktime(23, 59, 59, GETPOST('dateend_dtendmonth', 'int'), GETPOST('dateend_dtendday', 'int'), GETPOST('dateend_dtendyear', 'int'), 'tzuserrel'); if ($search_status == '' && !GETPOSTISSET('search_status')) { - $search_status = (empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); + $search_status = ((empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS) || $disabledefaultvalues) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); } if (empty($mode) && !GETPOSTISSET('mode')) { $mode = (empty($conf->global->AGENDA_DEFAULT_VIEW) ? 'show_month' : $conf->global->AGENDA_DEFAULT_VIEW); @@ -183,7 +183,8 @@ if ($user->socid && $socid) { */ if (GETPOST('cancel', 'alpha')) { - $mode = 'list'; $massaction = ''; + $mode = 'list'; + $massaction = ''; } if (GETPOST("viewcal") || GETPOST("viewweek") || GETPOST("viewday")) { @@ -216,8 +217,15 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $datestart_dtend = ''; $dateend_dtstart = ''; $dateend_dtend = ''; + $actioncode = ''; $search_status = ''; - $toselect = ''; + $pid = ''; + $socid = ''; + $resourceid = ''; + $filter = ''; + $filtert = ''; + $usergroup = ''; + $toselect = array(); $search_array_options = array(); } @@ -261,13 +269,17 @@ if (empty($reshook)) { } /* - * View + * View */ $form = new Form($db); $userstatic = new User($db); $formactions = new FormActions($db); +$actionstatic = new ActionComm($db); +$societestatic = new Societe($db); +$contactstatic = new Contact($db); + $nav = ''; $nav .= $form->selectDate($dateselect, 'dateselect', 0, 0, 1, '', 1, 0); $nav .= ' '; @@ -275,7 +287,8 @@ $nav .= ' trans("Agenda"); +llxHeader('', $title, $help_url); // Define list of all external calendars $listofextcals = array(); @@ -299,7 +312,7 @@ if ($actioncode != '') { if ($resourceid > 0) { $param .= "&search_resourceid=".urlencode($resourceid); } -if ($search_status != '' && $search_status > -1) { +if ($search_status != '') { $param .= "&search_status=".urlencode($search_status); } if ($filter) { @@ -563,11 +576,11 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $nbtotalofrecords++; }*/ /* The fast and low memory method to get and count full list converts the sql into a sql count */ - $sqlforcount = preg_replace('/^SELECT[a-z0-9\._\s\(\),]+FROM/i', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),]+FROM/i', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); $resql = $db->query($sqlforcount); $objforcount = $db->fetch_object($resql); $nbtotalofrecords = $objforcount->nbtotalofrecords; - if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 + if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0 $page = 0; $offset = 0; } @@ -588,12 +601,6 @@ if (!$resql) { $num = $db->num_rows($resql); - -$actionstatic = new ActionComm($db); -$societestatic = new Societe($db); - -$num = $db->num_rows($resql); - $arrayofselected = is_array($toselect) ? $toselect : array(); // Local calendar @@ -635,7 +642,6 @@ $s = $newtitle; // Calendars from hooks $parameters = array(); -$object = null; $reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action); if (empty($reshook)) { $s .= $hookmanager->resPrint; @@ -648,7 +654,7 @@ $viewday = is_object($object) ? dol_print_date($object->datep, '%d') : ''; $viewmode = ''; $viewmode .= ''; //$viewmode .= ''; -$viewmode .= img_picto($langs->trans("List"), 'object_list', 'class="imgforviewmode pictoactionview block"'); +$viewmode .= img_picto($langs->trans("List"), 'object_calendarlist', 'class="imgforviewmode pictoactionview block"'); //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewList").''; @@ -680,7 +686,6 @@ $viewmode .= ''; // Add more views from hooks $parameters = array(); -$object = null; $reshook = $hookmanager->executeHooks('addCalendarView', $parameters, $object, $action); if (empty($reshook)) { $viewmode .= $hookmanager->resPrint; @@ -797,44 +802,57 @@ print '
    '; $searchpicto = $form->showFilterButtons(); print $searchpicto; print '
    '; - $text = dolGetFirstLineOfText(dol_string_nohtmltag($actionstatic->note_private, 0)); - print $form->textwithtooltip(dol_trunc($text, 40), $actionstatic->note_private); + $text = dolGetFirstLineOfText(dol_string_nohtmltag($actionstatic->note_private, 1)); + print $form->textwithtooltip(dol_trunc($text, 48), $actionstatic->note_private); print '
    "; -print ''; -print ''; +// If no record found +if ($num == 0) { + print '
    '.$langs->trans("NoRecordFound").'
    '."\n"; +print ''."\n"; + +print ''."\n"; $db->free($resql); diff --git a/htdocs/comm/action/pertype.php b/htdocs/comm/action/pertype.php index 43d55424cd3..85eb355f2b6 100644 --- a/htdocs/comm/action/pertype.php +++ b/htdocs/comm/action/pertype.php @@ -45,6 +45,8 @@ if (!isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) { $action = GETPOST('action', 'aZ09'); +$disabledefaultvalues = GETPOST('disabledefaultvalues', 'int'); + $filter = GETPOST("search_filter", 'alpha', 3) ? GETPOST("search_filter", 'alpha', 3) : GETPOST("filter", 'alpha', 3); $filtert = GETPOST("search_filtert", "int", 3) ? GETPOST("search_filtert", "int", 3) : GETPOST("filtert", "int", 3); $usergroup = GETPOST("search_usergroup", "int", 3) ? GETPOST("search_usergroup", "int", 3) : GETPOST("usergroup", "int", 3); @@ -93,15 +95,15 @@ if (empty($user->rights->agenda->allactions->read) || $filter == 'mine') { // I } $mode = 'show_pertype'; -$resourceid = GETPOST("search_resourceid", "int") ?GETPOST("search_resourceid", "int") : GETPOST("resourceid", "int"); -$year = GETPOST("year", "int") ?GETPOST("year", "int") : date("Y"); -$month = GETPOST("month", "int") ?GETPOST("month", "int") : date("m"); -$week = GETPOST("week", "int") ?GETPOST("week", "int") : date("W"); -$day = GETPOST("day", "int") ?GETPOST("day", "int") : date("d"); -$pid = GETPOST("search_projectid", "int", 3) ?GETPOST("search_projectid", "int", 3) : GETPOST("projectid", "int", 3); -$status = GETPOST("search_status", 'alpha') ?GETPOST("search_status", 'alpha') : GETPOST("status", 'alpha'); -$type = GETPOST("search_type", 'alpha') ?GETPOST("search_type", 'alpha') : GETPOST("type", 'alpha'); -$maxprint = ((GETPOST("maxprint", 'int') != '') ?GETPOST("maxprint", 'int') : $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); +$resourceid = GETPOST("search_resourceid", "int") ? GETPOST("search_resourceid", "int") : GETPOST("resourceid", "int"); +$year = GETPOST("year", "int") ? GETPOST("year", "int") : date("Y"); +$month = GETPOST("month", "int") ? GETPOST("month", "int") : date("m"); +$week = GETPOST("week", "int") ? GETPOST("week", "int") : date("W"); +$day = GETPOST("day", "int") ? GETPOST("day", "int") : date("d"); +$pid = GETPOSTISSET("search_projectid") ? GETPOST("search_projectid", "int", 3) : GETPOST("projectid", "int", 3); +$status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'alpha') : GETPOST("status", 'alpha'); +$type = GETPOSTISSET("search_type") ? GETPOST("search_type", 'alpha') : GETPOST("type", 'alpha'); +$maxprint = ((GETPOST("maxprint", 'int') != '') ? GETPOST("maxprint", 'int') : $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') // Set actioncode (this code must be same for setting actioncode into peruser, listacton and index) if (GETPOST('search_actioncode', 'array')) { @@ -110,10 +112,7 @@ if (GETPOST('search_actioncode', 'array')) { $actioncode = '0'; } } else { - $actioncode = GETPOST("search_actioncode", "alpha", 3) ?GETPOST("search_actioncode", "alpha", 3) : (GETPOST("search_actioncode", "alpha") == '0' ? '0' : (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE)); -} -if ($actioncode == '' && empty($actioncodearray)) { - $actioncode = (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE); + $actioncode = GETPOST("search_actioncode", "alpha", 3) ?GETPOST("search_actioncode", "alpha", 3) : (GETPOST("search_actioncode", "alpha") == '0' ? '0' : ((empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE) || $disabledefaultvalues) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE)); } $dateselect = dol_mktime(0, 0, 0, GETPOST('dateselectmonth', 'int'), GETPOST('dateselectday', 'int'), GETPOST('dateselectyear', 'int')); @@ -144,8 +143,8 @@ $tmparray = explode('-', $tmp); $begin_d = 1; $end_d = 53; -if ($status == '' && !GETPOSTISSET('status')) { - $status = (empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); +if ($status == '' && !GETPOSTISSET('search_status')) { + $status = ((empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS) || $disabledefaultvalues) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); } if (empty($mode) && !GETPOSTISSET('mode')) { $mode = (empty($conf->global->AGENDA_DEFAULT_VIEW) ? 'show_month' : $conf->global->AGENDA_DEFAULT_VIEW); @@ -164,6 +163,8 @@ if (GETPOST('viewyear', 'alpha') || $mode == 'show_year') { $mode = 'show_year'; } // View by year +$object = new ActionComm($db); + // Load translation files required by the page $langs->loadLangs(array('users', 'agenda', 'other', 'commercial')); @@ -175,6 +176,8 @@ if ($user->socid && $socid) { $result = restrictedArea($user, 'societe', $socid); } +$search_status = $status; + /* * Actions @@ -276,7 +279,7 @@ if ($actioncode || GETPOSTISSET('search_actioncode')) { if ($resourceid > 0) { $param .= "&search_resourceid=".urlencode($resourceid); } -if ($status || GETPOSTISSET('status')) { +if ($status || GETPOSTISSET('status') || GETPOSTISSET('search_status')) { $param .= "&search_status=".urlencode($status); } if ($filter) { @@ -402,7 +405,7 @@ if ($conf->use_javascript_ajax) { //$s.='
    '.$langs->trans("AgendaShowBirthdayEvents").'  
    '; // Calendars from hooks - $parameters = array(); $object = null; + $parameters = array(); $reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action); if (empty($reshook)) { $s .= $hookmanager->resPrint; @@ -417,7 +420,7 @@ $massactionbutton = ''; $viewmode = ''; $viewmode .= ''; //$viewmode .= ''; -$viewmode .= img_picto($langs->trans("List"), 'object_list', 'class="imgforviewmode pictoactionview block"'); +$viewmode .= img_picto($langs->trans("List"), 'object_calendarlist', 'class="imgforviewmode pictoactionview block"'); //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewList").''; @@ -683,10 +686,6 @@ if ($resql) { $event->date_end_in_calendar = $datep; } } - // Define ponctual property - if ($event->date_start_in_calendar == $event->date_end_in_calendar) { - $event->ponctuel = 1; - } // Check values if ($event->date_end_in_calendar < $firstdaytoshow || @@ -961,7 +960,9 @@ function show_day_events_pertype($username, $day, $month, $year, $monthshown, $s $ymd = sprintf("%04d", $year).sprintf("%02d", $month).sprintf("%02d", $day); $nextindextouse = count($colorindexused); // At first run, this is 0, so fist user has 0, next 1, ... - //if ($username->id && $day==1) var_dump($eventarray); + //if ($username->id && $day==1) { + //var_dump($eventarray); + //} // We are in a particular day for $username, now we scan all events foreach ($eventarray as $daykey => $notused) { diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index 82c15392349..18f62872630 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -45,6 +45,8 @@ if (!isset($conf->global->AGENDA_MAX_EVENTS_DAY_VIEW)) { $action = GETPOST('action', 'aZ09'); +$disabledefaultvalues = GETPOST('disabledefaultvalues', 'int'); + $filter = GETPOST("search_filter", 'alpha', 3) ? GETPOST("search_filter", 'alpha', 3) : GETPOST("filter", 'alpha', 3); $filtert = GETPOST("search_filtert", "int", 3) ? GETPOST("search_filtert", "int", 3) : GETPOST("filtert", "int", 3); $usergroup = GETPOST("search_usergroup", "int", 3) ? GETPOST("search_usergroup", "int", 3) : GETPOST("usergroup", "int", 3); @@ -98,9 +100,9 @@ $year = GETPOST("year", "int") ?GETPOST("year", "int") : date("Y"); $month = GETPOST("month", "int") ?GETPOST("month", "int") : date("m"); $week = GETPOST("week", "int") ?GETPOST("week", "int") : date("W"); $day = GETPOST("day", "int") ?GETPOST("day", "int") : date("d"); -$pid = GETPOST("search_projectid", "int", 3) ?GETPOST("search_projectid", "int", 3) : GETPOST("projectid", "int", 3); +$pid = GETPOSTISSET("search_projectid") ? GETPOST("search_projectid", "int", 3) : GETPOST("projectid", "int", 3); $status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo' -$type = GETPOST("search_type", 'alpha') ?GETPOST("search_type", 'alpha') : GETPOST("type", 'alpha'); +$type = GETPOSTISSET("search_type") ? GETPOST("search_type", 'alpha') : GETPOST("type", 'alpha'); $maxprint = ((GETPOST("maxprint", 'int') != '') ?GETPOST("maxprint", 'int') : $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') // Set actioncode (this code must be same for setting actioncode into peruser, listacton and index) @@ -110,10 +112,7 @@ if (GETPOST('search_actioncode', 'array:aZ09')) { $actioncode = '0'; } } else { - $actioncode = GETPOST("search_actioncode", "alpha", 3) ?GETPOST("search_actioncode", "alpha", 3) : (GETPOST("search_actioncode", "alpha") == '0' ? '0' : (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE)); -} -if ($actioncode == '' && empty($actioncodearray)) { - $actioncode = (empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE); + $actioncode = GETPOST("search_actioncode", "alpha", 3) ?GETPOST("search_actioncode", "alpha", 3) : (GETPOST("search_actioncode", "alpha") == '0' ? '0' : ((empty($conf->global->AGENDA_DEFAULT_FILTER_TYPE) || $disabledefaultvalues) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_TYPE)); } $dateselect = dol_mktime(0, 0, 0, GETPOST('dateselectmonth', 'int'), GETPOST('dateselectday', 'int'), GETPOST('dateselectyear', 'int')); @@ -154,7 +153,7 @@ if ($end_d < $begin_d) { } if ($status == '' && !GETPOSTISSET('search_status')) { - $status = (empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); + $status = ((empty($conf->global->AGENDA_DEFAULT_FILTER_STATUS) || $disabledefaultvalues) ? '' : $conf->global->AGENDA_DEFAULT_FILTER_STATUS); } if (empty($mode) && !GETPOSTISSET('mode')) { @@ -171,6 +170,8 @@ if (GETPOST('viewday', 'alpha') || $mode == 'show_day') { $mode = 'show_day'; $day = ($day ? $day : date("d")); } // View by day +$object = new ActionComm($db); + // Load translation files required by the page $langs->loadLangs(array('users', 'agenda', 'other', 'commercial')); @@ -182,6 +183,8 @@ if ($user->socid && $socid) { $result = restrictedArea($user, 'societe', $socid); } +$search_status = $status; + /* * Actions @@ -283,7 +286,8 @@ if ($actioncode || GETPOSTISSET('search_actioncode')) { if ($resourceid > 0) { $param .= "&search_resourceid=".urlencode($resourceid); } -if ($status || GETPOSTISSET('status')) { + +if ($status || GETPOSTISSET('status') || GETPOSTISSET('search_status')) { $param .= "&search_status=".urlencode($status); } if ($filter) { @@ -413,7 +417,7 @@ if ($conf->use_javascript_ajax) { //$s.='
    '.$langs->trans("AgendaShowBirthdayEvents").'  
    '; // Calendars from hooks - $parameters = array(); $object = null; + $parameters = array(); $reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action); if (empty($reshook)) { $s .= $hookmanager->resPrint; @@ -428,7 +432,7 @@ $massactionbutton = ''; $viewmode = ''; $viewmode .= ''; //$viewmode .= ''; -$viewmode .= img_picto($langs->trans("List"), 'object_list', 'class="imgforviewmode pictoactionview block"'); +$viewmode .= img_picto($langs->trans("List"), 'object_calendarlist', 'class="imgforviewmode pictoactionview block"'); //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewList").''; @@ -510,10 +514,7 @@ $s = $newtitle; print $s; print '
    '; -if (empty($search_status)) { - $search_status = ''; -} -print_actions_filter($form, $canedit, $status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid); +print_actions_filter($form, $canedit, $search_status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid); print '
    '; @@ -712,10 +713,6 @@ if ($resql) { $event->date_end_in_calendar = $datep; } } - // Define ponctual property - if ($event->date_start_in_calendar == $event->date_end_in_calendar) { - $event->ponctuel = 1; - } // Check values if ($event->date_end_in_calendar < $firstdaytoshow || @@ -1131,7 +1128,9 @@ function show_day_events2($username, $day, $month, $year, $monthshown, $style, & $colorindexused[$user->id] = 0; // Color index for current user (user->id) is always 0 $nextindextouse = count($colorindexused); // At first run this is 0, so first user has 0, next 1, ... - //if ($username->id && $day==1) var_dump($eventarray); + //if ($username->id && $day==1) { + //var_dump($eventarray); + //} // We are in a particular day for $username, now we scan all events foreach ($eventarray as $daykey => $notused) { diff --git a/htdocs/comm/admin/propal_extrafields.php b/htdocs/comm/admin/propal_extrafields.php index bfa62eba7fc..7a4cfe7a6ea 100644 --- a/htdocs/comm/admin/propal_extrafields.php +++ b/htdocs/comm/admin/propal_extrafields.php @@ -82,7 +82,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/comm/admin/propaldet_extrafields.php b/htdocs/comm/admin/propaldet_extrafields.php index 19b7674449f..91517d456c5 100644 --- a/htdocs/comm/admin/propaldet_extrafields.php +++ b/htdocs/comm/admin/propaldet_extrafields.php @@ -85,7 +85,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 177d3e1f668..d0cb4d7be2f 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -10,6 +10,7 @@ * Copyright (C) 2015-2021 Frédéric France * Copyright (C) 2015 Marcos García * Copyright (C) 2020 Open-Dsi + * Copyright (C) 2022 Anthony Berton * * 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 @@ -38,6 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; if (!empty($conf->facture->enabled)) { require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; } @@ -112,6 +114,7 @@ $cancel = GETPOST('cancel', 'alpha'); $object = new Client($db); $extrafields = new ExtraFields($db); +$formfile = new FormFile($db); // fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); @@ -170,7 +173,7 @@ if (empty($reshook)) { // terms of the settlement if ($action == 'setconditions' && $user->rights->societe->creer) { $object->fetch($id); - $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'), GETPOST('cond_reglement_id_deposit_percent', 'alpha')); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); } @@ -215,7 +218,7 @@ if (empty($reshook)) { // assujetissement a la TVA if ($action == 'setassujtva' && $user->rights->societe->creer) { $object->fetch($id); - $object->tva_assuj = $_POST['assujtva_value']; + $object->tva_assuj = GETPOST('assujtva_value'); $result = $object->update($object->id); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); @@ -412,9 +415,9 @@ if ($object->id > 0) { print ''; print ''; if ($action == 'editconditions') { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_id, 'cond_reglement_id', 1); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_id, 'cond_reglement_id', 1, '', 1, $object->deposit_percent); } else { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_id, 'none'); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?socid='.$object->id, $object->cond_reglement_id, 'none', 0, '', 1, $object->deposit_percent); } print ""; print ''; @@ -684,7 +687,7 @@ if ($object->id > 0) { } print '
    '; - print '
    '; + print '
    '; $boxstat = ''; @@ -692,7 +695,7 @@ if ($object->id > 0) { $MAXLIST = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT; // Lien recap - $boxstat .= '
    '; + $boxstat .= '
    '; $boxstat .= ''; $boxstat .= ''; print '\n"; + // Preview + $filedir = $conf->commande->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + $file_list = null; + if (!empty($filedir)) { + $file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + } + if (is_array($file_list)) { + // Defined relative dir to DOL_DATA_ROOT + $relativedir = ''; + if ($filedir) { + $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir); + $relativedir = preg_replace('/^[\\/]/', '', $relativedir); + } + // Get list of files stored into database for same relative directory + if ($relativedir) { + completeFileArrayWithDatabaseInfo($file_list, $relativedir); + + //var_dump($sortfield.' - '.$sortorder); + if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + $file_list = dol_sort_array($file_list, $sortfield, $sortorder); + } + } + $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf'; + print $formfile->showPreview($file_list, $commande_static->element, $relativepath, 0, $param); + } + // $filename = dol_sanitizeFileName($objp->ref); + // $filedir = $conf->order->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + // $urlsource = '/commande/card.php?id='.$objp->cid; + // print $formfile->getDocumentsLink($commande_static->element, $filename, $filedir); + print ''; + + print '\n"; print ''; print ''; $i++; @@ -1004,6 +1068,35 @@ if ($object->id > 0) { print ''; print ''; if ($objp->date_creation > 0) { print ''; @@ -1077,6 +1170,35 @@ if ($object->id > 0) { print ''; print '\n"; print '\n"; @@ -1104,7 +1226,7 @@ if ($object->id > 0) { * Latest interventions */ if (!empty($conf->ficheinter->enabled) && $user->rights->ficheinter->lire) { - $sql = "SELECT s.nom, s.rowid, f.rowid as id, f.ref, f.fk_statut, f.duree as duration, f.datei as startdate"; + $sql = "SELECT s.nom, s.rowid, f.rowid as id, f.ref, f.fk_statut, f.duree as duration, f.datei as startdate, f.entity"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as f"; $sql .= " WHERE f.fk_soc = s.rowid"; $sql .= " AND s.rowid = ".((int) $object->id); @@ -1138,6 +1260,35 @@ if ($object->id > 0) { print ''; print ''."\n"; //print ''."\n"; print ''."\n"; @@ -1214,6 +1365,7 @@ if ($object->id > 0) { print ''; + if ($objp->frequency && $objp->date_last_gen > 0) { print ''; } else { @@ -1302,6 +1454,35 @@ if ($object->id > 0) { print ''; print ''; if ($objp->df > 0) { print ''; diff --git a/htdocs/comm/contact.php b/htdocs/comm/contact.php index 57a88bef157..d83fdbcb78c 100644 --- a/htdocs/comm/contact.php +++ b/htdocs/comm/contact.php @@ -88,7 +88,7 @@ if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " ".MAIN_DB_PREFIX."socpeople as p"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = p.fk_soc"; $sql .= " WHERE s.fk_stcomm = st.id"; -$sql .= " AND p.entity IN (".getEntity('socpeople').")"; +$sql .= " AND p.entity IN (".getEntity('contact').")"; if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } @@ -157,10 +157,10 @@ if ($resql) { print ''; print ''; - print ""; + print ''; print '\n"; + print ''.$obj->name."\n"; print ''; diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php index aad02f2bd07..5903b7e4bdb 100644 --- a/htdocs/comm/index.php +++ b/htdocs/comm/index.php @@ -568,9 +568,15 @@ if (!empty($conf->societe->enabled) && $user->rights->societe->lire) { if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } - if ($socid) { - $sql .= " AND s.rowid = $socid"; + // Add where from hooks + $parameters = array('socid' => $socid); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $companystatic); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if ($socid > 0) { + $sql .= " AND s.rowid = ".((int) $socid); + } } + $sql .= $hookmanager->resPrint; $sql .= " ORDER BY s.tms DESC"; $sql .= $db->plimit($max, 0); @@ -628,7 +634,11 @@ if (!empty($conf->societe->enabled) && $user->rights->societe->lire) { print $s; print ''; - print ''; + + $datem = $db->jdate($objp->tms); + print ''; print ''; $i++; @@ -664,9 +674,15 @@ if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_S if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } - if ($socid) { - $sql .= " AND s.rowid = ".((int) $socid); + // Add where from hooks + $parameters = array('socid' => $socid); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $companystatic); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if ($socid > 0) { + $sql .= " AND s.rowid = ".((int) $socid); + } } + $sql .= $hookmanager->resPrint; $sql .= " ORDER BY s.datec DESC"; $sql .= $db->plimit($max, 0); @@ -713,7 +729,11 @@ if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_S print $s; print ''; - print ''; + + $datem = $db->jdate($objp->dm); + print ''; print ''; $i++; @@ -910,7 +930,10 @@ if (!empty($conf->propal->enabled) && $user->rights->propal->lire) { print ''; print ''; - print ''; + $datem = $db->jdate($obj->dp); + print ''; print ''; print ''; @@ -1027,7 +1050,11 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire) { print ''; print ''; - print ''; + $datem = $db->jdate($obj->dv); + print ''; + print ''; print ''; diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index 79faf4b2cd2..b3d3dd25e90 100644 --- a/htdocs/comm/mailing/card.php +++ b/htdocs/comm/mailing/card.php @@ -745,7 +745,7 @@ if ($action == 'create') { print '
    '; @@ -824,7 +827,7 @@ if ($object->id > 0) { $sql .= ", p.total_tva"; $sql .= ", p.total_ttc"; $sql .= ", p.ref, p.ref_client, p.remise"; - $sql .= ", p.datep as dp, p.fin_validite as date_limit"; + $sql .= ", p.datep as dp, p.fin_validite as date_limit, p.entity"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as p, ".MAIN_DB_PREFIX."c_propalst as c"; $sql .= " WHERE p.fk_soc = s.rowid AND p.fk_statut = c.id"; $sql .= " AND s.rowid = ".((int) $object->id); @@ -860,6 +863,36 @@ if ($object->id > 0) { $propal_static->total_tva = $objp->total_tva; $propal_static->total_ttc = $objp->total_ttc; print $propal_static->getNomUrl(1); + + // Preview + $filedir = $conf->propal->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + $file_list = null; + if (!empty($filedir)) { + $file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + } + if (is_array($file_list)) { + // Defined relative dir to DOL_DATA_ROOT + $relativedir = ''; + if ($filedir) { + $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir); + $relativedir = preg_replace('/^[\\/]/', '', $relativedir); + } + // Get list of files stored into database for same relative directory + if ($relativedir) { + completeFileArrayWithDatabaseInfo($file_list, $relativedir); + + //var_dump($sortfield.' - '.$sortorder); + if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + $file_list = dol_sort_array($file_list, $sortfield, $sortorder); + } + } + $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf'; + print $formfile->showPreview($file_list, $propal_static->element, $relativepath, 0); + } + // $filename = dol_sanitizeFileName($objp->ref); + // $filedir = $conf->propal->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + // $urlsource = '/comm/propal/card.php?id='.$objp->cid; + // print $formfile->getDocumentsLink($propal_static->element, $filename, $filedir); if (($db->jdate($objp->date_limit) < ($now - $conf->propal->cloture->warning_delay)) && $objp->fk_statut == $propal_static::STATUS_VALIDATED) { print " ".img_warning(); } @@ -941,7 +974,38 @@ if ($object->id > 0) { print '
    '; print $commande_static->getNomUrl(1); - print ''.dol_print_date($db->jdate($objp->dc), 'day')."'.dol_print_date($db->jdate($objp->dc), 'day')."'.price($objp->total_ht).''.$commande_static->LibStatut($objp->fk_statut, $objp->facture, 5).'
    '; print $sendingstatic->getNomUrl(1); + // Preview + $filedir = $conf->expedition->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + $file_list = null; + if (!empty($filedir)) { + $file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + } + if (is_array($file_list)) { + // Defined relative dir to DOL_DATA_ROOT + $relativedir = ''; + if ($filedir) { + $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir); + $relativedir = preg_replace('/^[\\/]/', '', $relativedir); + } + // Get list of files stored into database for same relative directory + if ($relativedir) { + completeFileArrayWithDatabaseInfo($file_list, $relativedir); + + //var_dump($sortfield.' - '.$sortorder); + if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + $file_list = dol_sort_array($file_list, $sortfield, $sortorder); + } + } + $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf'; + print $formfile->showPreview($file_list, $sendingstatic->element, $relativepath, 0, $param); + } + // $filename = dol_sanitizeFileName($objp->ref); + // $filedir = $conf->expedition->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + // $urlsource = '/expedition/card.php?id='.$objp->cid; + // print $formfile->getDocumentsLink($sendingstatic->element, $filename, $filedir); print ''.dol_print_date($db->jdate($objp->date_creation), 'day').'
    '; print $contrat->getNomUrl(1, 12); + // Preview + $filedir = $conf->contrat->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + $file_list = null; + if (!empty($filedir)) { + $file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + } + if (is_array($file_list)) { + // Defined relative dir to DOL_DATA_ROOT + $relativedir = ''; + if ($filedir) { + $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir); + $relativedir = preg_replace('/^[\\/]/', '', $relativedir); + } + // Get list of files stored into database for same relative directory + if ($relativedir) { + completeFileArrayWithDatabaseInfo($file_list, $relativedir); + + //var_dump($sortfield.' - '.$sortorder); + if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + $file_list = dol_sort_array($file_list, $sortfield, $sortorder); + } + } + $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf'; + print $formfile->showPreview($file_list, $contrat->element, $relativepath, 0, $param); + } + // $filename = dol_sanitizeFileName($objp->ref); + // $filedir = $conf->contrat->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + // $urlsource = '/contrat/card.php?id='.$objp->cid; + // print $formfile->getDocumentsLink($contrat->element, $filename, $filedir); print $late; print "'.dol_trunc($objp->refsup, 12)."
    '; print $fichinter_static->getNomUrl(1); + // Preview + $filedir = $conf->ficheinter->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + $file_list = null; + if (!empty($filedir)) { + $file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + } + if (is_array($file_list)) { + // Defined relative dir to DOL_DATA_ROOT + $relativedir = ''; + if ($filedir) { + $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir); + $relativedir = preg_replace('/^[\\/]/', '', $relativedir); + } + // Get list of files stored into database for same relative directory + if ($relativedir) { + completeFileArrayWithDatabaseInfo($file_list, $relativedir); + + //var_dump($sortfield.' - '.$sortorder); + if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + $file_list = dol_sort_array($file_list, $sortfield, $sortorder); + } + } + $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf'; + print $formfile->showPreview($file_list, $fichinter_static->element, $relativepath, 0); + } + // $filename = dol_sanitizeFileName($objp->ref); + // $filedir = $conf->fichinter->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + // $urlsource = '/fichinter/card.php?id='.$objp->cid; + // print $formfile->getDocumentsLink($fichinter_static->element, $filename, $filedir); print ''.dol_print_date($db->jdate($objp->startdate)).''.convertSecondToTime($objp->duration).''; print $invoicetemplate->getNomUrl(1); print ''.dol_print_date($db->jdate($objp->date_last_gen), 'day').'
    '; print $facturestatic->getNomUrl(1); + // Preview + $filedir = $conf->facture->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + $file_list = null; + if (!empty($filedir)) { + $file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC); + } + if (is_array($file_list)) { + // Defined relative dir to DOL_DATA_ROOT + $relativedir = ''; + if ($filedir) { + $relativedir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filedir); + $relativedir = preg_replace('/^[\\/]/', '', $relativedir); + } + // Get list of files stored into database for same relative directory + if ($relativedir) { + completeFileArrayWithDatabaseInfo($file_list, $relativedir); + + //var_dump($sortfield.' - '.$sortorder); + if (!empty($sortfield) && !empty($sortorder)) { // If $sortfield is for example 'position_name', we will sort on the property 'position_name' (that is concat of position+name) + $file_list = dol_sort_array($file_list, $sortfield, $sortorder); + } + } + $relativepath = dol_sanitizeFileName($objp->ref).'/'.dol_sanitizeFileName($objp->ref).'.pdf'; + print $formfile->showPreview($file_list, $facturestatic->element, $relativepath, 0, $param); + } + // $filename = dol_sanitizeFileName($objp->ref); + // $filedir = $conf->facture->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref); + // $urlsource = '/compta/facture/card.php?id='.$objp->cid; + //print $formfile->getDocumentsLink($facturestatic->element, $filename, $filedir); print ''.dol_print_date($db->jdate($objp->df), 'day').'
    '.img_object($langs->trans("ShowContact"), "contact"); print ' '.$obj->name.'$obj->firstname'.dol_escape_htmltag($obj->firstname).''.img_object($langs->trans("ShowCompany"), "company").' '; - print "rowid."\">$obj->name'.dol_print_phone($obj->email, $obj->cidp, $obj->rowid, 'AC_EMAIL').''.dol_print_date($db->jdate($objp->tms), 'day').''; + print dol_print_date($datem, 'day', 'tzuserrel'); + print '
    '.dol_print_date($db->jdate($objp->dm), 'day').''; + print dol_print_date($datem, 'day', 'tzuserrel'); + print '
    '.$companystatic->getNomUrl(1, 'customer', 44).''.dol_print_date($db->jdate($obj->dp), 'day').''; + print dol_print_date($datem, 'day', 'tzserver'); + print ''.price(!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT) ? $obj->total_ht : $obj->total_ttc).''.$propalstatic->LibStatut($obj->fk_statut, 3).''.$companystatic->getNomUrl(1, 'customer', 44).''.dol_print_date($db->jdate($obj->dv), 'day').''; + print dol_print_date($datem, 'day', 'tzserver'); + print ''.price(!empty($conf->global->MAIN_DASHBOARD_USE_TOTAL_HT) ? $obj->total_ht : $obj->total_ttc).''.$orderstatic->LibStatut($obj->fk_statut, $obj->billed, 3).'
    '; print ''; print ''; print '
    '.$langs->trans("MailTopic").'
    '.$langs->trans("BackgroundColorByDefault").''; - print $htmlother->selectColor($_POST['bgcolor'], 'bgcolor', '', 0); + print $htmlother->selectColor(GETPOST('bgcolor'), 'bgcolor', '', 0); print '
    '; @@ -961,7 +961,7 @@ if ($action == 'create') { if (GETPOST('cancel', 'alpha') || $confirm == 'no' || $action == '' || in_array($action, array('settodraft', 'valid', 'delete', 'sendall', 'clone', 'test'))) { print "\n\n
    \n"; - if (($object->statut == 1) && ($user->rights->mailing->valider || $object->fk_user_valid == $user->id)) { + if (($object->statut == 1) && ($user->rights->mailing->valider || $object->user_validation == $user->id)) { print ''.$langs->trans("SetToDraft").''; } @@ -1066,7 +1066,7 @@ if ($action == 'create') { print dol_get_fiche_end(); - print dol_set_focus('#sendto'); + dol_set_focus('#sendto'); } diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php index 9069b63179f..95639a25997 100644 --- a/htdocs/comm/mailing/cibles.php +++ b/htdocs/comm/mailing/cibles.php @@ -135,7 +135,7 @@ if (GETPOST('exportcsv', 'int')) { $sql = "SELECT mc.rowid, mc.lastname, mc.firstname, mc.email, mc.other, mc.statut as status, mc.date_envoi, mc.tms,"; $sql .= " mc.source_id, mc.source_type, mc.error_text"; $sql .= " FROM ".MAIN_DB_PREFIX."mailing_cibles as mc"; - $sql .= " WHERE mc.fk_mailing=".((int) $object->id); + $sql .= " WHERE mc.fk_mailing = ".((int) $object->id); $sql .= $db->order($sortfield, $sortorder); $resql = $db->query($sql); @@ -365,17 +365,19 @@ if ($object->fetch($id) >= 0) { $obj = new $classname($db); + // Check if qualified + $qualified = (is_null($obj->enabled) ? 1 : dol_eval($obj->enabled, 1)); + // Check dependencies - $qualified = (isset($obj->enabled) ? $obj->enabled : 1); foreach ($obj->require_module as $key) { - if (!$conf->$key->enabled || (!$user->admin && $obj->require_admin)) { + if (empty($conf->$key->enabled) || (empty($user->admin) && $obj->require_admin)) { $qualified = 0; //print "Les prerequis d'activation du module mailing ne sont pas respectes. Il ne sera pas actif"; break; } } - // Si le module mailing est qualifie + // If module is qualified if ($qualified) { $var = !$var; @@ -402,7 +404,7 @@ if ($object->fetch($id) >= 0) { } print '
    '; - if ($nbofrecipient >= 0) { + if ($nbofrecipient === '' || $nbofrecipient >= 0) { print $nbofrecipient; } else { print $langs->trans("Error").' '.img_error($obj->error); diff --git a/htdocs/comm/mailing/class/advtargetemailing.class.php b/htdocs/comm/mailing/class/advtargetemailing.class.php index 79e25c83385..62dd24aaaf7 100644 --- a/htdocs/comm/mailing/class/advtargetemailing.class.php +++ b/htdocs/comm/mailing/class/advtargetemailing.class.php @@ -686,7 +686,7 @@ class AdvanceTargetingMailing extends CommonObject $sqlwhere = array(); - $sqlwhere[] = 't.entity IN ('.getEntity('socpeople').')'; + $sqlwhere[] = 't.entity IN ('.getEntity('contact').')'; if (count($arrayquery) > 0) { if (array_key_exists('contact_categ', $arrayquery)) { diff --git a/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php b/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php index cfdca4a1fc2..9e10d51031e 100644 --- a/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php +++ b/htdocs/comm/mailing/class/html.formadvtargetemailing.class.php @@ -128,7 +128,8 @@ class FormAdvTargetEmailing extends Form $i++; } - array_multisort($label, SORT_ASC, $countryArray); + $array1_sort_order = SORT_ASC; + array_multisort($label, $array1_sort_order, $countryArray); foreach ($countryArray as $row) { $label = dol_trunc($row['label'], $maxlength, 'middle'); @@ -230,7 +231,7 @@ class FormAdvTargetEmailing extends Form $InfoFieldList = explode(":", $param_list [0]); // 0 1 : tableName - // 1 2 : label field name Nom du champ contenant le libelle + // 1 2 : label field name Name of field that contains the label // 2 3 : key fields name (if differ of rowid) // 3 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value @@ -304,7 +305,7 @@ class FormAdvTargetEmailing extends Form if ($num) { while ($i < $num) { $obj = $this->db->fetch_object($resql); - // Si traduction existe, on l'utilise, sinon on prend le libelle par defaut + // If a translation exists, we use it, else we use the default label $label = ($langs->trans("Civility".$obj->code) != "Civility".$obj->code ? $langs->trans("Civility".$obj->code) : ($obj->civilite != '-' ? $obj->civilite : '')); $options_array[$obj->code] = $label; diff --git a/htdocs/comm/mailing/class/mailing.class.php b/htdocs/comm/mailing/class/mailing.class.php index cb900f7ac7b..4ea794bfbd4 100644 --- a/htdocs/comm/mailing/class/mailing.class.php +++ b/htdocs/comm/mailing/class/mailing.class.php @@ -86,6 +86,11 @@ class Mailing extends CommonObject */ public $email_from; + /** + * @var string email to + */ + public $sendto; + /** * @var string email reply to */ @@ -175,6 +180,16 @@ class Mailing extends CommonObject */ public $statuts = array(); + /** + * @var array substitutionarray + */ + public $substitutionarray; + + /** + * @var array substitutionarrayfortest + */ + public $substitutionarrayfortest; + /** * Constructor @@ -713,13 +728,6 @@ class Mailing extends CommonObject } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('myobjectdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -740,7 +748,7 @@ class Mailing extends CommonObject global $action; $hookmanager->initHooks(array('emailingdao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; @@ -754,7 +762,7 @@ class Mailing extends CommonObject /** * Return label of status of emailing (draft, validated, ...) * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long + * @param int $mode 0=Long label, 1=Short label, 2=Picto+Short label, 3=Picto, 4=Picto+Short label, 5=Short label+Picto, 6=Picto+Long label, 7=Very short label+Picto * @return string Label */ public function getLibStatut($mode = 0) @@ -764,10 +772,10 @@ class Mailing extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Renvoi le libelle d'un statut donne + * Return the label of a given status * * @param int $status Id status - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @param int $mode 0=Long label, 1=Short label, 2=Picto+Short label, 3=Picto, 4=Picto+Short label, 5=Short label+Picto, 6=Picto+Long label, 7=Very short label+Picto * @return string Label */ public function LibStatut($status, $mode = 0) @@ -792,11 +800,11 @@ class Mailing extends CommonObject /** - * Renvoi le libelle d'un statut donne + * Return the label of a given status of a recipient * TODO Add class mailin_target.class.php * * @param int $status Id status - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @param int $mode 0=Long label, 1=Short label, 2=Picto+Short label, 3=Picto, 4=Picto+Short label, 5=Short label+Picto, 6=Picto+Long label, 7=Very short label+Picto * @param string $desc Desc error * @return string Label */ diff --git a/htdocs/comm/mailing/list.php b/htdocs/comm/mailing/list.php index be458d41fe3..ecde836c428 100644 --- a/htdocs/comm/mailing/list.php +++ b/htdocs/comm/mailing/list.php @@ -103,7 +103,7 @@ if (empty($reshook)) { }*/ $search_ref = ''; $search_all = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index b40092abfaa..cc35cfc65a9 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -14,6 +14,7 @@ * Copyright (C) 2016 Marcos García * Copyright (C) 2018-2021 Frédéric France * Copyright (C) 2020 Nicolas ZABOURI + * Copyright (C) 2022 Gauthier VERDOL * * 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 @@ -80,6 +81,7 @@ $confirm = GETPOST('confirm', 'alpha'); $lineid = GETPOST('lineid', 'int'); $contactid = GETPOST('contactid', 'int'); $projectid = GETPOST('projectid', 'int'); +$rank = (GETPOST('rank', 'int') > 0) ? GETPOST('rank', 'int') : -1; // PDF $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); @@ -220,7 +222,7 @@ if (empty($reshook)) { } } - $result = $object->createFromClone($user, $socid, (GETPOSTISSET('entity') ? GETPOST('entity', 'int') : null)); + $result = $object->createFromClone($user, $socid, (GETPOSTISSET('entity') ? GETPOST('entity', 'int') : null), (GETPOST('update_prices', 'aZ') ? true : false)); if ($result > 0) { header("Location: ".$_SERVER['PHP_SELF'].'?id='.$result); exit(); @@ -305,7 +307,7 @@ if (empty($reshook)) { } } } elseif ($action == 'setdate' && $usercancreate) { - $datep = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']); + $datep = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); if (empty($datep)) { $error++; @@ -319,7 +321,7 @@ if (empty($reshook)) { } } } elseif ($action == 'setecheance' && $usercancreate) { - $result = $object->set_echeance($user, dol_mktime(12, 0, 0, $_POST['echmonth'], $_POST['echday'], $_POST['echyear'])); + $result = $object->set_echeance($user, dol_mktime(12, 0, 0, GETPOST('echmonth', 'int'), GETPOST('echday', 'int'), GETPOST('echyear', 'int'))); if ($result >= 0) { if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { $outputlangs = $langs; @@ -342,7 +344,7 @@ if (empty($reshook)) { setEventMessages($object->error, $object->errors, 'errors'); } } elseif ($action == 'setdate_livraison' && $usercancreate) { - $result = $object->setDeliveryDate($user, dol_mktime(12, 0, 0, $_POST['date_livraisonmonth'], $_POST['date_livraisonday'], $_POST['date_livraisonyear'])); + $result = $object->setDeliveryDate($user, dol_mktime(12, 0, 0, GETPOST('date_livraisonmonth', 'int'), GETPOST('date_livraisonday', 'int'), GETPOST('date_livraisonyear', 'int'))); if ($result < 0) { dol_print_error($db, $object->error); } @@ -400,6 +402,7 @@ if (empty($reshook)) { $object->warehouse_id = GETPOST('warehouse_id', 'int'); $object->duree_validite = $duration; $object->cond_reglement_id = GETPOST('cond_reglement_id'); + $object->deposit_percent = GETPOST('cond_reglement_id_deposit_percent', 'alpha'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); $object->fk_account = GETPOST('fk_account', 'int'); $object->remise_absolue = price2num(GETPOST('remise_absolue'), 'MU', 2); // deprecated @@ -432,6 +435,7 @@ if (empty($reshook)) { $object->warehouse_id = GETPOST('warehouse_id', 'int'); $object->duree_validite = price2num(GETPOST('duree_validite', 'alpha')); $object->cond_reglement_id = GETPOST('cond_reglement_id', 'int'); + $object->deposit_percent = GETPOST('cond_reglement_id_deposit_percent', 'alpha'); $object->mode_reglement_id = GETPOST('mode_reglement_id', 'int'); $object->fk_account = GETPOST('fk_account', 'int'); $object->contact_id = GETPOST('contactid', 'int'); @@ -685,10 +689,62 @@ if (empty($reshook)) { $error++; } + $deposit = null; + $locationTarget = ''; + + $deposit_percent_from_payment_terms = getDictionaryValue('c_payment_term', 'deposit_percent', $object->cond_reglement_id); + + if ( + !$error && GETPOST('statut', 'int') == $object::STATUS_SIGNED && GETPOST('generate_deposit', 'alpha') == 'on' + && ! empty($deposit_percent_from_payment_terms) && ! empty($conf->facture->enabled) && ! empty($user->rights->facture->creer) + ) { + require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; + + $date = dol_mktime(0, 0, 0, GETPOST('datefmonth', 'int'), GETPOST('datefday', 'int'), GETPOST('datefyear', 'int')); + $forceFields = array(); + + if (GETPOSTISSET('date_pointoftax')) { + $forceFields['date_pointoftax'] = dol_mktime(0, 0, 0, GETPOST('date_pointoftaxmonth', 'int'), GETPOST('date_pointoftaxday', 'int'), GETPOST('date_pointoftaxyear', 'int')); + } + + $deposit = Facture::createDepositFromOrigin($object, $date, GETPOST('cond_reglement_id', 'int'), $user, 0, GETPOST('validate_generated_deposit', 'alpha') == 'on', $forceFields); + + if ($deposit) { + setEventMessage('DepositGenerated'); + $locationTarget = DOL_URL_ROOT . '/compta/facture/card.php?id=' . $deposit->id; + } else { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } + } + if (!$error) { $db->commit(); + + if ($deposit && empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $ret = $deposit->fetch($deposit->id); // Reload to get new records + $outputlangs = $langs; + + if ($conf->global->MAIN_MULTILANGS) { + $outputlangs = new Translate('', $conf); + $outputlangs->setDefaultLang($deposit->thirdparty->default_lang); + $outputlangs->load('products'); + } + + $result = $deposit->generateDocument($deposit->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + + if ($result < 0) { + setEventMessages($deposit->error, $deposit->errors, 'errors'); + } + } + + if ($locationTarget) { + header('Location: ' . $locationTarget); + exit; + } } else { $db->rollback(); + $action = ''; } } } @@ -829,6 +885,13 @@ if (empty($reshook)) { foreach ($object->lines as $line) { $result = $object->updateline($line->id, $line->subprice, $line->qty, $line->remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, $line->desc, 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); } + } elseif ($action == 'addline' && GETPOST('submitforalllines', 'alpha') && GETPOST('remiseforalllines', 'alpha') !== '' && $usercancreate) { + // Define vat_rate + $remise_percent = (GETPOST('remiseforalllines') ? GETPOST('remiseforalllines') : 0); + $remise_percent = str_replace('*', '', $remise_percent); + foreach ($object->lines as $line) { + $result = $object->updateline($line->id, $line->subprice, $line->qty, $remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, $line->desc, 'HT', $line->info_bits, $line->special_code, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->product_type, $line->date_start, $line->date_end, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + } } elseif ($action == 'addline' && $usercancreate) { // Add line // Set if we used free entry or predefined product $predef = ''; @@ -1146,7 +1209,7 @@ if (empty($reshook)) { setEventMessages($mesg, null, 'errors'); } else { // Insert line - $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_options, $fk_unit, '', 0, $pu_ht_devise); + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $price_base_type, $pu_ttc, $info_bits, $type, min($rank, count($object->lines) + 1), 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $date_start, $date_end, $array_options, $fk_unit, '', 0, $pu_ht_devise); if ($result > 0) { $db->commit(); @@ -1361,7 +1424,7 @@ if (empty($reshook)) { $result = $object->set_demand_reason($user, GETPOST('demand_reason_id', 'int')); } elseif ($action == 'setconditions' && $usercancreate) { // Terms of payment - $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'), GETPOST('cond_reglement_id_deposit_percent', 'alpha')); } elseif ($action == 'setremisepercent' && $usercancreate) { $result = $object->set_remise_percent($user, price2num(GETPOST('remise_percent'), '', 2)); } elseif ($action == 'setremiseabsolue' && $usercancreate) { @@ -1577,19 +1640,19 @@ if ($action == 'create') { print ''; // Reference - print ''; + print ''; // Ref customer - print ''; + print ''; print ''; // Third party - print ''; - print ''; + print ''; + print ''; $shipping_method_id = 0; if ($socid > 0) { - print ''; @@ -1598,7 +1661,7 @@ if ($action == 'create') { } //$warehouse_id = $soc->warehouse_id; } else { - print ''; // Third party discounts info line - print ''; // Validaty duration - print ''; + print ''; // Terms of payment - print ''; // Mode of payment - print ''; // Bank Account if (!empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL) && !empty($conf->banque->enabled)) { - print ''; } // Source / Channel - What trigger creation - print ''; // Delivery delay - print ''; @@ -1686,7 +1749,7 @@ if ($action == 'create') { if (!empty($conf->global->SOCIETE_ASK_FOR_SHIPPING_METHOD) && !empty($soc->shipping_method_id)) { $shipping_method_id = $soc->shipping_method_id; } - print ''; @@ -1696,14 +1759,14 @@ if ($action == 'create') { if (!empty($conf->stock->enabled) && !empty($conf->global->WAREHOUSE_ASK_WAREHOUSE_DURING_PROPAL)) { require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; $formproduct = new FormProduct($db); - print ''; } // Delivery date (or manufacturing) - print ''; - print ''; + print ''; - print ''; + print ''; @@ -1728,18 +1791,18 @@ if ($action == 'create') { // Incoterms if (!empty($conf->incoterm->enabled)) { - print ''; - print ''; - print ''; + print ''; + print ''; } // Template to use by default - print ''; - print ''; - print ''; + print ''; + print ''; - print ''; - print ''; + print ''; + print ''; } // Public note - print ''; - print ''; - print ''; + print ''; + print ''; - print ''; - print ''; + print ''; + print '
    '.$langs->trans('Ref').''.$langs->trans("Draft").'
    '.$langs->trans('Ref').''.$langs->trans("Draft").'
    '.$langs->trans('RefCustomer').''; - print '
    '.$langs->trans('RefCustomer').''; + print '
    '.$langs->trans('Customer').'
    '.$langs->trans('Customer').''; + print ''; print $soc->getNomUrl(1); print ''; print ''; + print ''; print img_picto('', 'company').$form->select_company('', 'socid', '(s.client = 1 OR s.client = 2 OR s.client = 3) AND status=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300 maxwidth500 widthcentpercentminusxx'); // reload page to retrieve customer informations if (empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED)) { @@ -1621,13 +1684,13 @@ if ($action == 'create') { if ($socid > 0) { // Contacts (ask contact only if thirdparty already defined). - print "
    ".$langs->trans("DefaultContact").''; + print '
    '.$langs->trans("DefaultContact").''; print img_picto('', 'contact'); print $form->selectcontacts($soc->id, $contactid, 'contactid', 1, '', '', 0, 'minwidth300'); print '
    '.$langs->trans('Discounts').''; + print '
    '.$langs->trans('Discounts').''; $absolute_discount = $soc->getAvailableDiscounts(); @@ -1639,45 +1702,45 @@ if ($action == 'create') { } // Date - print '
    '.$langs->trans('DatePropal').''; + print '
    '.$langs->trans('DatePropal').''; print $form->selectDate('', '', '', '', '', "addprop", 1, 1); print '
    '.$langs->trans("ValidityDuration").''.img_picto('', 'clock').'  '.$langs->trans("days").'
    '.$langs->trans("ValidityDuration").''.img_picto('', 'clock', 'class="paddingright"').' '.$langs->trans("days").'
    '.$langs->trans('PaymentConditionsShort').''; + print '
    '.$langs->trans('PaymentConditionsShort').''; print img_picto('', 'paiment'); - $form->select_conditions_paiements((GETPOSTISSET('cond_reglement_id') && GETPOST('cond_reglement_id') != 0) ? GETPOST('cond_reglement_id', 'int') : $soc->cond_reglement_id, 'cond_reglement_id', -1, 1); + $form->select_conditions_paiements((GETPOSTISSET('cond_reglement_id') && GETPOST('cond_reglement_id') != 0) ? GETPOST('cond_reglement_id', 'int') : $soc->cond_reglement_id, 'cond_reglement_id', 1, 1, 0, '', (GETPOSTISSET('cond_reglement_id_deposit_percent') ? GETPOST('cond_reglement_id_deposit_percent', 'alpha') : $soc->deposit_percent)); print '
    '.$langs->trans('PaymentMode').''; - print img_picto('', 'bank').' '; + print '
    '.$langs->trans('PaymentMode').''; + print img_picto('', 'bank', 'class="pictofixedwidth"'); $form->select_types_paiements((GETPOSTISSET('mode_reglement_id') ? GETPOST('mode_reglement_id', 'int') : $soc->mode_reglement_id), 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx'); print '
    '.$langs->trans('BankAccount').''; + print '
    '.$langs->trans('Source').''; + print '
    '.$langs->trans('Source').''; print img_picto('', 'question', 'class="pictofixedwidth"'); $form->selectInputReason('', 'demand_reason_id', "SRC_PROP", 1, 'maxwidth200 widthcentpercentminusx'); print '
    '.$langs->trans('AvailabilityPeriod'); + print '
    '.$langs->trans('AvailabilityPeriod'); if (!empty($conf->commande->enabled)) { print ' ('.$langs->trans('AfterOrder').')'; } - print ''; - print img_picto('', 'clock').' '; + print ''; + print img_picto('', 'clock', 'class="pictofixedwidth"'); $form->selectAvailabilityDelay('', 'availability_id', '', 1, 'maxwidth200 widthcentpercentminusx'); print '
    '.$langs->trans('SendingMethod').''; + print '
    '.$langs->trans('SendingMethod').''; print img_picto('', 'object_dollyrevert', 'class="pictofixedwidth"'); print $form->selectShippingMethod($shipping_method_id, 'shipping_method_id', '', 1, '', 0, 'maxwidth200 widthcentpercentminusx'); print '
    '.$langs->trans('Warehouse').''; + print '
    '.$langs->trans('Warehouse').''; print img_picto('', 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses($warehouse_id, 'warehouse_id', '', 1, 0, 0, '', 0, 0, array(), 'maxwidth500 widthcentpercentminusxx'); print '
    '.$langs->trans("DeliveryDate").''; + print '
    '.$langs->trans("DeliveryDate").''; if (isset($conf->global->DATE_LIVRAISON_WEEK_DELAY) && is_numeric($conf->global->DATE_LIVRAISON_WEEK_DELAY)) { $tmpdte = time() + ((7 * $conf->global->DATE_LIVRAISON_WEEK_DELAY) * 24 * 60 * 60); $syear = date("Y", $tmpdte); @@ -1718,8 +1781,8 @@ if ($action == 'create') { // Project if (!empty($conf->projet->enabled)) { $langs->load("projects"); - print '
    '.$langs->trans("Project").''; + print '
    '.$langs->trans("Project").''; print img_picto('', 'project', 'class="pictofixedwidth"').$formproject->select_projects(($soc->id > 0 ? $soc->id : -1), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx'); print ' id).'">'; print '
    '; + print '
    '; print $form->select_incoterms((!empty($soc->fk_incoterms) ? $soc->fk_incoterms : ''), (!empty($soc->location_incoterms) ? $soc->location_incoterms : '')); print '
    '.$langs->trans("DefaultModel").''; - print img_picto('', 'pdf').' '; + print '
    '.$langs->trans("DefaultModel").''; + print img_picto('', 'pdf', 'class="pictofixedwidth"'); $liste = ModelePDFPropales::liste_modeles($db); $preselected = (!empty($conf->global->PROPALE_ADDON_PDF_ODT_DEFAULT) ? $conf->global->PROPALE_ADDON_PDF_ODT_DEFAULT : getDolGlobalString("PROPALE_ADDON_PDF")); print $form->selectarray('model', $liste, $preselected, 0, 0, 0, '', 0, 0, 0, '', 'maxwidth200 widthcentpercentminusx', 1); @@ -1747,26 +1810,26 @@ if ($action == 'create') { // Multicurrency if (!empty($conf->multicurrency->enabled)) { - print '
    '.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).''; - print $form->selectMultiCurrency($currency_code, 'multicurrency_code', 0); + print '
    '.$form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0).''; + print img_picto('', 'currency', 'class="pictofixedwidth"').$form->selectMultiCurrency($currency_code, 'multicurrency_code', 0); print '
    '.$langs->trans('NotePublic').''; + print '
    '.$langs->trans('NotePublic').''; $note_public = $object->getDefaultCreateValueFor('note_public', (!empty($objectsrc) ? $objectsrc->note_public : null)); $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, empty($conf->global->FCKEDITOR_ENABLE_NOTE_PUBLIC) ? 0 : 1, ROWS_3, '90%'); print $doleditor->Create(1); // Private note if (empty($user->socid)) { - print '
    '.$langs->trans('NotePrivate').''; + print '
    '.$langs->trans('NotePrivate').''; $note_private = $object->getDefaultCreateValueFor('note_private', ((!empty($origin) && !empty($originid) && is_object($objectsrc)) ? $objectsrc->note_private : null)); $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, empty($conf->global->FCKEDITOR_ENABLE_NOTE_PRIVATE) ? 0 : 1, ROWS_3, '90%'); print $doleditor->Create(1); @@ -1892,11 +1955,13 @@ if ($action == 'create') { $title = $langs->trans('ProductsAndServices'); print load_fiche_titre($title); + print '
    '; print ''; $objectsrc->printOriginLinesList(); print '
    '; + print '
    '; } } elseif ($object->id > 0) { /* @@ -1917,8 +1982,8 @@ if ($action == 'create') { $formquestion = array( // 'text' => $langs->trans("ConfirmClone"), // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1), - // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1), - array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')) + array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)', '', 0, 0, null, 0, 'maxwidth300')), + array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans('PuttingPricesUpToDate'), 'value' => (!empty($conf->global->PROPOSAL_CLONE_UPDATE_PRICES) ? 1 : 0)), ); if (!empty($conf->global->PROPAL_CLONE_DATE_DELIVERY) && !empty($object->delivery_date)) { $formquestion[] = array('type' => 'date', 'name' => 'date_delivery', 'label' => $langs->trans("DeliveryDate"), 'value' => $object->delivery_date); @@ -1934,6 +1999,129 @@ if ($action == 'create') { array('type' => 'text', 'name' => 'note_private', 'label' => $langs->trans("Note"), 'value' => '') // Field to complete private note (not replace) ); + $deposit_percent_from_payment_terms = getDictionaryValue('c_payment_term', 'deposit_percent', $object->cond_reglement_id); + + if (! empty($deposit_percent_from_payment_terms) && ! empty($conf->facture->enabled) && ! empty($user->rights->facture->creer)) { + require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; + + $object->fetchObjectLinked(); + + $eligibleForDepositGeneration = true; + + if (array_key_exists('facture', $object->linkedObjects)) { + foreach ($object->linkedObjects['facture'] as $invoice) { + if ($invoice->type == Facture::TYPE_DEPOSIT) { + $eligibleForDepositGeneration = false; + break; + } + } + } + + if ($eligibleForDepositGeneration && array_key_exists('commande', $object->linkedObjects)) { + foreach ($object->linkedObjects['commande'] as $order) { + $order->fetchObjectLinked(); + + if (array_key_exists('facture', $order->linkedObjects)) { + foreach ($order->linkedObjects['facture'] as $invoice) { + if ($invoice->type == Facture::TYPE_DEPOSIT) { + $eligibleForDepositGeneration = false; + break 2; + } + } + } + } + } + + + if ($eligibleForDepositGeneration) { + $formquestion[] = array( + 'type' => 'checkbox', + 'tdclass' => 'showonlyifsigned', + 'name' => 'generate_deposit', + 'label' => $form->textwithpicto($langs->trans('GenerateDeposit', $object->deposit_percent), $langs->trans('DepositGenerationPermittedByThePaymentTermsSelected')) + ); + + $formquestion[] = array( + 'type' => 'date', + 'tdclass' => 'fieldrequired showonlyifgeneratedeposit', + 'name' => 'datef', + 'label' => $langs->trans('DateInvoice'), + 'value' => dol_now(), + 'datenow' => true + ); + + if (! empty($conf->global->INVOICE_POINTOFTAX_DATE)) { + $formquestion[] = array( + 'type' => 'date', + 'tdclass' => 'fieldrequired showonlyifgeneratedeposit', + 'name' => 'date_pointoftax', + 'label' => $langs->trans('DatePointOfTax'), + 'value' => dol_now(), + 'datenow' => true + ); + } + + ob_start(); + $form->select_conditions_paiements(0, 'cond_reglement_id', -1, 0, 0, 'minwidth200'); + $paymentTermsSelect = ob_get_clean(); + + $formquestion[] = array( + 'type' => 'other', + 'tdclass' => 'fieldrequired showonlyifgeneratedeposit', + 'name' => 'cond_reglement_id', + 'label' => $langs->trans('PaymentTerm'), + 'value' => $paymentTermsSelect + ); + + $formquestion[] = array( + 'type' => 'checkbox', + 'tdclass' => 'showonlyifgeneratedeposit', + 'name' => 'validate_generated_deposit', + 'label' => $langs->trans('ValidateGeneratedDeposit') + ); + + $formquestion[] = array( + 'type' => 'onecolumn', + 'value' => ' + + ' + ); + } + } + if (!empty($conf->notification->enabled)) { require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php'; $notify = new Notify($db); @@ -2160,17 +2348,17 @@ if ($action == 'create') { print '
    '; print ''; if ($action == 'editconditions' && $usercancreate && $caneditfield) { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id'); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id', 0, '', 1, $object->deposit_percent); } else { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'none'); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'none', 0, '', 1, $object->deposit_percent); } print ''; print ''; // Payment mode - print ''; - print ''; - print ''; + print '\n"; print ""; - $totalpaye += $objp->amount; + $totalpaid += $objp->amount; $i++; } } else { @@ -741,10 +757,10 @@ if ($id > 0) { print ''; } - print '\n"; + print '\n"; print '\n"; - $resteapayer = $object->amount - $totalpaye; + $resteapayer = $object->amount - $totalpaid; $cssforamountpaymentcomplete = 'amountpaymentcomplete'; print '"; @@ -804,7 +820,7 @@ if ($id > 0) { } // Delete - if ($user->rights->tax->charges->supprimer && empty($totalpaye)) { + if ($user->rights->tax->charges->supprimer && empty($totalpaid)) { print ''; } else { print ''; @@ -847,7 +863,7 @@ if ($id > 0) { /* $MAXEVENT = 10; - $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-list-alt imgforviewmode', dol_buildpath('/mymodule/myobject_agenda.php', 1).'?id='.$object->id); + $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', dol_buildpath('/mymodule/myobject_agenda.php', 1).'?id='.$object->id); // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; diff --git a/htdocs/compta/sociales/class/chargesociales.class.php b/htdocs/compta/sociales/class/chargesociales.class.php index 431f0bcba72..3b9019868ec 100644 --- a/htdocs/compta/sociales/class/chargesociales.class.php +++ b/htdocs/compta/sociales/class/chargesociales.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2004-2007 Laurent Destailleur - * Copyright (C) 2016-2020 Frédéric France + * Copyright (C) 2016-2022 Frédéric France * Copyright (C) 2017 Alexandre Spangaro * Copyright (C) 2021 Gauthier VERDOL * @@ -113,6 +113,12 @@ class ChargeSociales extends CommonObject */ public $fk_user; + /** + * @var double total + */ + public $total; + + public $totalpaid; const STATUS_UNPAID = 0; const STATUS_PAID = 1; @@ -123,7 +129,7 @@ class ChargeSociales extends CommonObject * * @param DoliDB $db Database handler */ - public function __construct($db) + public function __construct(DoliDB $db) { $this->db = $db; } @@ -139,7 +145,7 @@ class ChargeSociales extends CommonObject { $sql = "SELECT cs.rowid, cs.date_ech"; $sql .= ", cs.libelle as label, cs.fk_type, cs.amount, cs.fk_projet as fk_project, cs.paye, cs.periode, cs.import_key"; - $sql .= ", cs.fk_account, cs.fk_mode_reglement, cs.fk_user"; + $sql .= ", cs.fk_account, cs.fk_mode_reglement, cs.fk_user, note_public, note_private"; $sql .= ", c.libelle as type_label"; $sql .= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle'; $sql .= " FROM ".MAIN_DB_PREFIX."chargesociales as cs"; @@ -172,6 +178,8 @@ class ChargeSociales extends CommonObject $this->amount = $obj->amount; $this->fk_project = $obj->fk_project; $this->fk_user = $obj->fk_user; + $this->note_public = $obj->note_public; + $this->note_private = $obj->note_private; $this->paye = $obj->paye; $this->periode = $this->db->jdate($obj->periode); $this->import_key = $this->import_key; @@ -362,7 +370,7 @@ class ChargeSociales extends CommonObject if (!$error) { if (!$notrigger) { // Call trigger - $result = $this->call_trigger('SOCIALCHARGES_MODIFY', $user); + $result = $this->call_trigger('SOCIALCONTRIBUTION_MODIFY', $user); if ($result < 0) { $error++; } @@ -560,7 +568,7 @@ class ChargeSociales extends CommonObject */ public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $short = 0, $save_lastsearch_value = -1) { - global $langs, $conf, $user, $form; + global $langs, $conf, $user, $form, $hookmanager; if (!empty($conf->dol_no_mouse_hover)) { $notooltip = 1; // Force disable tooltips @@ -625,7 +633,15 @@ class ChargeSociales extends CommonObject $result .= $this->ref; } $result .= $linkend; - + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } diff --git a/htdocs/compta/sociales/class/paymentsocialcontribution.class.php b/htdocs/compta/sociales/class/paymentsocialcontribution.class.php index 9a4b50e3474..1b83915714d 100644 --- a/htdocs/compta/sociales/class/paymentsocialcontribution.class.php +++ b/htdocs/compta/sociales/class/paymentsocialcontribution.class.php @@ -100,12 +100,28 @@ class PaymentSocialContribution extends CommonObject */ public $fk_user_modif; + /** + * @var int ID + */ + public $chid; + + /** + * @var integer|string datepaye + */ + public $datepaye; + + /** + * @var integer|string paiementtype + */ + public $paiementtype; + + /** * Constructor * * @param DoliDB $db Database handler */ - public function __construct($db) + public function __construct(DoliDB $db) { $this->db = $db; } diff --git a/htdocs/compta/sociales/document.php b/htdocs/compta/sociales/document.php index 6918b2c84ee..3de8687433f 100644 --- a/htdocs/compta/sociales/document.php +++ b/htdocs/compta/sociales/document.php @@ -139,7 +139,9 @@ if ($object->id) { $linkback = ''.$langs->trans("BackToList").''; - $object->totalpaye = $totalpaye; // To give a chance to dol_banner_tab to use already paid amount to show correct status + $object->totalpaid = $alreadypayed; // To give a chance to dol_banner_tab to use already paid amount to show correct status + + $morehtmlright = ''; dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlright); diff --git a/htdocs/compta/sociales/info.php b/htdocs/compta/sociales/info.php index 546a4c711d0..8363459171b 100644 --- a/htdocs/compta/sociales/info.php +++ b/htdocs/compta/sociales/info.php @@ -81,7 +81,9 @@ $object->info($id); $head = tax_prepare_head($object); -print dol_get_fiche_head($head, 'info', $langs->trans("SocialContribution"), -1, 'bill'); +$alreadypayed = $object->getSommePaiement(); + +print dol_get_fiche_head($head, 'info', $langs->trans("SocialContribution"), -1, $object->picto); $morehtmlref = '
    '; // Label of social contribution @@ -106,8 +108,9 @@ $morehtmlref .= '
    '; $linkback = ''.$langs->trans("BackToList").''; -$object->totalpaye = $totalpaye; // To give a chance to dol_banner_tab to use already paid amount to show correct status +$object->totalpaid = $alreadypayed; // To give a chance to dol_banner_tab to use already paid amount to show correct status +$morehtmlright = ''; dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlright); print '
    '; @@ -115,7 +118,7 @@ print '
    '; print '
    '; -print '
    '; + print '
    '; + print ''; if ($action != 'editmode' && $usercancreate && $caneditfield) { @@ -2189,7 +2377,7 @@ if ($action == 'create') { $langs->load('deliveries'); print ''; print ''; @@ -2220,7 +2408,7 @@ if ($action == 'create') { // Shipping Method if (!empty($conf->expedition->enabled)) { print ''; print "
    '; print $langs->trans('PaymentMode'); print '
    '; print $form->editfieldkey($langs->trans('DeliveryDate'), 'date_livraison', $object->delivery_date, $object, $usercancreate && $caneditfield, 'datepicker'); - print ''; + print ''; print $form->editfieldval($langs->trans('DeliveryDate'), 'date_livraison', $object->delivery_date, $object, $usercancreate && $caneditfield, 'datepicker'); print '
    '; - print ''; print ''; - print ''; + print ''; if ($object->date_trans <> 0) { $muser = new User($db); @@ -105,7 +105,7 @@ if ($id > 0 || $ref) { print ''; + print ' '.$langs->trans("By").' '.$muser->getNomUrl(-1).''; print ''; @@ -151,7 +151,9 @@ if ($id > 0 || $ref) { if ($object->type == 'bank-transfer') { $modulepart = 'paymentbybanktransfer'; } - print ''.$relativepath.''; + print ''.$relativepath; + print img_picto('', 'download', 'class="paddingleft"'); + print ''; print '
    '; + print ''; if ($action != 'editshippingmethod' && $usercancreate && $caneditfield) { @@ -2242,7 +2430,7 @@ if ($action == 'create') { $langs->load('stocks'); require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; $formproduct = new FormProduct($db); - print '"; diff --git a/htdocs/compta/paiement/card.php b/htdocs/compta/paiement/card.php index 345e3d26419..bd5c114e983 100644 --- a/htdocs/compta/paiement/card.php +++ b/htdocs/compta/paiement/card.php @@ -175,8 +175,8 @@ if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->facture } } -if ($action == 'setnum_paiement' && !empty($_POST['num_paiement'])) { - $res = $object->update_num($_POST['num_paiement']); +if ($action == 'setnum_paiement' && GETPOST('num_paiement')) { + $res = $object->update_num(GETPOST('num_paiement')); if ($res === 0) { setEventMessages($langs->trans('PaymentNumberUpdateSucceeded'), null, 'mesgs'); } else { @@ -184,7 +184,7 @@ if ($action == 'setnum_paiement' && !empty($_POST['num_paiement'])) { } } -if ($action == 'setdatep' && !empty($_POST['datepday'])) { +if ($action == 'setdatep' && GETPOST('datepday')) { $datepaye = dol_mktime(GETPOST('datephour', 'int'), GETPOST('datepmin', 'int'), GETPOST('datepsec', 'int'), GETPOST('datepmonth', 'int'), GETPOST('datepday', 'int'), GETPOST('datepyear', 'int')); $res = $object->update_date($datepaye); if ($res === 0) { @@ -271,7 +271,7 @@ print '
    '; print $langs->trans('SendingMethod'); print '
    '; + print '
    '; $editenable = $usercancreate; print $form->editfieldkey("Warehouse", 'warehouse', '', $object, $editenable); print ''; @@ -2257,7 +2445,7 @@ if ($action == 'create') { // Origin of demand print '
    '; - print ''; @@ -2522,27 +2694,27 @@ if ($action == 'create' && $usercancreate) { if (empty($reshook)) { // Reopen a closed order if (($object->statut == Commande::STATUS_CLOSED || $object->statut == Commande::STATUS_CANCELED) && $usercancreate) { - print ''.$langs->trans('ReOpen').''; + print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&token='.newToken().'&id='.$object->id, ''); } // Send if (empty($user->socid)) { if ($object->statut > Commande::STATUS_DRAFT || !empty($conf->global->COMMANDE_SENDBYEMAIL_FOR_ALL_STATUS)) { if ($usercansend) { - print ''.$langs->trans('SendMail').''; + print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?action=presend&token='.newToken().'&id='.$object->id.'&mode=init#formmailbeforetitle', ''); } else { - print ''.$langs->trans('SendMail').''; + print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER['PHP_SELF']. '#', '', false); } } } // Valid if ($object->statut == Commande::STATUS_DRAFT && ($object->total_ttc >= 0 || !empty($conf->global->ORDER_ENABLE_NEGATIVE)) && $numlines > 0 && $usercanvalidate) { - print ''.$langs->trans('Validate').''; + print dolGetButtonAction('', $langs->trans('Validate'), 'default', $_SERVER["PHP_SELF"].'?action=validate&token='.newToken().'&id='.$object->id, ''); } // Edit if ($object->statut == Commande::STATUS_VALIDATED && $usercancreate) { - print ''.$langs->trans('Modify').''; + print dolGetButtonAction('', $langs->trans('Modify'), 'default', $_SERVER["PHP_SELF"].'?action=modif&token='.newToken().'&id='.$object->id, ''); } // Create event /*if ($conf->agenda->enabled && ! empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) @@ -2557,7 +2729,7 @@ if ($action == 'create' && $usercancreate) { if (!empty($conf->global->WORKFLOW_CAN_CREATE_PURCHASE_ORDER_FROM_SALE_ORDER)) { if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled)) && $object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && $object->getNbOfServicesLines() > 0) { if ($usercancreatepurchaseorder) { - print ''.$langs->trans("AddPurchaseOrder").''; + print dolGetButtonAction('', $langs->trans('AddPurchaseOrder'), 'default', DOL_URL_ROOT.'/fourn/commande/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); } } } @@ -2568,19 +2740,19 @@ if ($action == 'create' && $usercancreate) { if ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && $object->getNbOfServicesLines() > 0) { if ($user->rights->ficheinter->creer) { - print ''.$langs->trans('AddIntervention').''; + print dolGetButtonAction('', $langs->trans('AddInterventionGR'), 'default', DOL_URL_ROOT.'/fichinter/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); } else { - print ''.$langs->trans('AddIntervention').''; + print dolGetButtonAction($langs->trans('NotAllowed'), $langs->trans('AddIntervention'), 'default', $_SERVER['PHP_SELF']. '#', '', false); } } } // Create contract - if ($conf->contrat->enabled && ($object->statut == Commande::STATUS_VALIDATED || $object->statut == Commande::STATUS_SHIPMENTONPROCESS || $object->statut == Commande::STATUS_CLOSED)) { + if (!empty($conf->contrat->enabled) && ($object->statut == Commande::STATUS_VALIDATED || $object->statut == Commande::STATUS_SHIPMENTONPROCESS || $object->statut == Commande::STATUS_CLOSED)) { $langs->load("contracts"); if ($user->rights->contrat->creer) { - print ''.$langs->trans('AddContract').''; + print dolGetButtonAction('', $langs->trans('AddContract'), 'default', DOL_URL_ROOT.'/contrat/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); } } @@ -2592,52 +2764,52 @@ if ($action == 'create' && $usercancreate) { if ($object->statut > Commande::STATUS_DRAFT && $object->statut < Commande::STATUS_CLOSED && ($object->getNbOfProductsLines() > 0 || !empty($conf->global->STOCK_SUPPORTS_SERVICES))) { if (($conf->expedition_bon->enabled && $user->rights->expedition->creer) || ($conf->delivery_note->enabled && $user->rights->expedition->delivery->creer)) { if ($user->rights->expedition->creer) { - print ''.$langs->trans('CreateShipment').''; + print dolGetButtonAction('', $langs->trans('CreateShipment'), 'default', DOL_URL_ROOT.'/expedition/shipment.php?id='.$object->id, ''); } else { - print ''.$langs->trans('CreateShipment').''; + print dolGetButtonAction($langs->trans('NotAllowed'), $langs->trans('CreateShipment'), 'default', $_SERVER['PHP_SELF']. '#', '', false); } } else { $langs->load("errors"); - print 'transnoentitiesnoconv("Shipment"))).'">'.$langs->trans('CreateShipment').''; + print dolGetButtonAction($langs->trans('ErrorModuleSetupNotComplete'), $langs->trans('CreateShipment'), 'default', $_SERVER['PHP_SELF']. '#', '', false); } } } // Set to shipped if (($object->statut == Commande::STATUS_VALIDATED || $object->statut == Commande::STATUS_SHIPMENTONPROCESS) && $usercanclose) { - print ''.$langs->trans('ClassifyShipped').''; + print dolGetButtonAction('', $langs->trans('ClassifyShipped'), 'default', $_SERVER["PHP_SELF"].'?action=shipped&token='.newToken().'&id='.$object->id, ''); } // Create bill and Classify billed // Note: Even if module invoice is not enabled, we should be able to use button "Classified billed" if ($object->statut > Commande::STATUS_DRAFT && !$object->billed && $object->total_ttc >= 0) { if (!empty($conf->facture->enabled) && $user->rights->facture->creer && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) { - print ''.$langs->trans("CreateBill").''; + print dolGetButtonAction('', $langs->trans('CreateBill'), 'default', DOL_URL_ROOT.'/compta/facture/card.php?action=create&token='.newToken().'&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); } if ($usercancreate && $object->statut >= Commande::STATUS_VALIDATED && empty($conf->global->WORKFLOW_DISABLE_CLASSIFY_BILLED_FROM_ORDER) && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) { - print ''.$langs->trans("ClassifyBilled").''; + print dolGetButtonAction('', $langs->trans('ClassifyBilled'), 'default', $_SERVER["PHP_SELF"].'?action=classifybilled&token='.newToken().'&id='.$object->id, ''); } } if ($object->statut > Commande::STATUS_DRAFT && $object->billed) { if ($usercancreate && $object->statut >= Commande::STATUS_VALIDATED && empty($conf->global->WORKFLOW_DISABLE_CLASSIFY_BILLED_FROM_ORDER) && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) { - print ''.$langs->trans("ClassifyUnBilled").''; + print dolGetButtonAction('', $langs->trans('ClassifyUnBilled'), 'default', $_SERVER["PHP_SELF"].'?action=classifyunbilled&token='.newToken().'&id='.$object->id, ''); } } // Clone if ($usercancreate) { - print ''.$langs->trans("ToClone").''; + print dolGetButtonAction('', $langs->trans('ToClone'), 'default', $_SERVER["PHP_SELF"].'?action=clone&token='.newToken().'&id='.$object->id.'&socid='.$object->socid, ''); } // Cancel order if ($object->statut == Commande::STATUS_VALIDATED && (!empty($usercanclose) || !empty($usercancancel))) { - print ''.$langs->trans("Cancel").''; + print dolGetButtonAction('', $langs->trans('Cancel'), 'danger', $_SERVER["PHP_SELF"].'?action=cancel&token='.newToken().'&id='.$object->id, ''); } // Delete order if ($usercandelete) { if ($numshipping == 0) { - print ''.$langs->trans('Delete').''; + print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id, ''); } else { - print ''.$langs->trans("Delete").''; + print dolGetButtonAction($langs->trans('ShippingExist'), $langs->trans('Delete'), 'default', $_SERVER['PHP_SELF']. '#', '', false); } } } diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index fb912139d5f..2c916abda9a 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -133,8 +133,16 @@ class Orders extends DolibarrApi } // Add external contacts ids - $this->commande->contacts_ids = $this->commande->liste_contact(-1, 'external', $contact_list); + $tmparray = $this->commande->liste_contact(-1, 'external', $contact_list); + if (is_array($tmparray)) { + $this->commande->contacts_ids = $tmparray; + } $this->commande->fetchObjectLinked(); + + // Add online_payment_url, cf #20477 + require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; + $this->commande->online_payment_url = getOnlinePaymentUrl(0, 'order', $this->commande->ref); + return $this->_cleanObjectDatas($this->commande); } @@ -229,7 +237,14 @@ class Orders extends DolibarrApi $commande_static = new Commande($this->db); if ($commande_static->fetch($obj->rowid)) { // Add external contacts ids - $commande_static->contacts_ids = $commande_static->liste_contact(-1, 'external', 1); + $tmparray = $commande_static->liste_contact(-1, 'external', 1); + if (is_array($tmparray)) { + $commande_static->contacts_ids = $tmparray; + } + // Add online_payment_url, cf #20477 + require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; + $commande_static->online_payment_url = getOnlinePaymentUrl(0, 'order', $commande_static->ref); + $obj_ret[] = $this->_cleanObjectDatas($commande_static); } $i++; @@ -335,8 +350,8 @@ class Orders extends DolibarrApi $request_data = (object) $request_data; - $request_data->desc = checkVal($request_data->desc, 'restricthtml'); - $request_data->label = checkVal($request_data->label); + $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml'); + $request_data->label = sanitizeVal($request_data->label); $updateRes = $this->commande->addline( $request_data->desc, @@ -403,8 +418,8 @@ class Orders extends DolibarrApi $request_data = (object) $request_data; - $request_data->desc = checkVal($request_data->desc, 'restricthtml'); - $request_data->label = checkVal($request_data->label); + $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml'); + $request_data->label = sanitizeVal($request_data->label); $updateRes = $this->commande->updateline( $lineid, @@ -430,7 +445,8 @@ class Orders extends DolibarrApi $request_data->fk_unit, $request_data->multicurrency_subprice, 0, - $request_data->ref_ext + $request_data->ref_ext, + $request_data->rang ); if ($updateRes > 0) { @@ -735,6 +751,10 @@ class Orders extends DolibarrApi $this->commande->fetchObjectLinked(); + //fix #20477 : add online_payment_url + require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; + $this->commande->online_payment_url = getOnlinePaymentUrl(0, 'order', $this->commande->ref); + return $this->_cleanObjectDatas($this->commande); } diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 728e0f62ede..44cc5c6effd 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -9,9 +9,10 @@ * Copyright (C) 2012 Cedric Salvador * Copyright (C) 2013 Florian Henry * Copyright (C) 2014-2015 Marcos García - * Copyright (C) 2018 Nicolas ZABOURI + * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2016-2022 Ferran Marcet - * Copyright (C) 2021 Frédéric France + * Copyright (C) 2021-2022 Frédéric France + * Copyright (C) 2022 Gauthier VERDOL * * 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 @@ -133,6 +134,11 @@ class Commande extends CommonOrder */ public $cond_reglement_code; + /** + * @var double Deposit % for payment terms + */ + public $deposit_percent; + /** * @var int bank account ID */ @@ -266,6 +272,11 @@ class Commande extends CommonOrder */ public $expeditions; + /** + * @var string payment url + */ + public $online_payment_url; + /** * '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') @@ -302,8 +313,8 @@ class Commande extends CommonOrder 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'RefExt', 'enabled'=>1, 'visible'=>0, 'position'=>26), 'ref_int' =>array('type'=>'varchar(255)', 'label'=>'RefInt', 'enabled'=>1, 'visible'=>0, 'position'=>27), // deprecated 'ref_client' =>array('type'=>'varchar(255)', 'label'=>'RefCustomer', 'enabled'=>1, 'visible'=>-1, 'position'=>28), - 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>20), - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>1, 'visible'=>-1, 'position'=>25), + 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'$conf->societe->enabled', 'visible'=>-1, 'notnull'=>1, 'position'=>20), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>'$conf->projet->enabled', 'visible'=>-1, 'position'=>25), 'date_commande' =>array('type'=>'date', 'label'=>'Date', 'enabled'=>1, 'visible'=>1, 'position'=>60), 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>62), 'date_cloture' =>array('type'=>'datetime', 'label'=>'DateClosing', 'enabled'=>1, 'visible'=>-1, 'position'=>65), @@ -323,13 +334,14 @@ class Commande extends CommonOrder 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>155), 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'PDFTemplate', 'enabled'=>1, 'visible'=>0, 'position'=>160), //'facture' =>array('type'=>'tinyint(4)', 'label'=>'ParentInvoice', 'enabled'=>1, 'visible'=>-1, 'position'=>165), - 'fk_account' =>array('type'=>'integer', 'label'=>'BankAccount', 'enabled'=>1, 'visible'=>-1, 'position'=>170), + 'fk_account' =>array('type'=>'integer', 'label'=>'BankAccount', 'enabled'=>'$conf->banque->enabled', 'visible'=>-1, 'position'=>170), 'fk_currency' =>array('type'=>'varchar(3)', 'label'=>'MulticurrencyID', 'enabled'=>1, 'visible'=>-1, 'position'=>175), 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'position'=>180), + 'deposit_percent' =>array('type'=>'varchar(63)', 'label'=>'DepositPercent', 'enabled'=>1, 'visible'=>-1, 'position'=>181), 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>-1, 'position'=>185), 'date_livraison' =>array('type'=>'date', 'label'=>'DateDeliveryPlanned', 'enabled'=>1, 'visible'=>-1, 'position'=>190), 'fk_shipping_method' =>array('type'=>'integer', 'label'=>'ShippingMethod', 'enabled'=>1, 'visible'=>-1, 'position'=>195), - 'fk_warehouse' =>array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Fk warehouse', 'enabled'=>1, 'visible'=>-1, 'position'=>200), + 'fk_warehouse' =>array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Fk warehouse', 'enabled'=>'$conf->stock->enabled', 'visible'=>-1, 'position'=>200), 'fk_availability' =>array('type'=>'integer', 'label'=>'Availability', 'enabled'=>1, 'visible'=>-1, 'position'=>205), 'fk_input_reason' =>array('type'=>'integer', 'label'=>'InputReason', 'enabled'=>1, 'visible'=>-1, 'position'=>210), //'fk_delivery_address' =>array('type'=>'integer', 'label'=>'DeliveryAddress', 'enabled'=>1, 'visible'=>-1, 'position'=>215), @@ -495,7 +507,8 @@ class Commande extends CommonOrder $sql .= " SET ref = '".$this->db->escape($num)."',"; $sql .= " fk_statut = ".self::STATUS_VALIDATED.","; $sql .= " date_valid='".$this->db->idate($now)."',"; - $sql .= " fk_user_valid = ".((int) $user->id); + $sql .= " fk_user_valid = ".((int) $user->id).","; + $sql .= " fk_user_modif = ".((int) $user->id); $sql .= " WHERE rowid = ".((int) $this->id); dol_syslog(get_class($this)."::valid", LOG_DEBUG); @@ -626,7 +639,8 @@ class Commande extends CommonOrder $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."commande"; - $sql .= " SET fk_statut = ".self::STATUS_DRAFT; + $sql .= " SET fk_statut = ".self::STATUS_DRAFT.","; + $sql .= " fk_user_modif = ".((int) $user->id); $sql .= " WHERE rowid = ".((int) $this->id); if ($this->db->query($sql)) { @@ -701,7 +715,8 @@ class Commande extends CommonOrder $this->db->begin(); $sql = 'UPDATE '.MAIN_DB_PREFIX.'commande'; - $sql .= ' SET fk_statut='.self::STATUS_VALIDATED.', facture=0'; + $sql .= ' SET fk_statut='.self::STATUS_VALIDATED.', facture=0,'; + $sql .= " fk_user_modif = ".((int) $user->id); $sql .= " WHERE rowid = ".((int) $this->id); dol_syslog(get_class($this)."::set_reopen", LOG_DEBUG); @@ -762,7 +777,8 @@ class Commande extends CommonOrder $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; $sql .= ' SET fk_statut = '.self::STATUS_CLOSED.','; $sql .= ' fk_user_cloture = '.((int) $user->id).','; - $sql .= " date_cloture = '".$this->db->idate($now)."'"; + $sql .= " date_cloture = '".$this->db->idate($now)."',"; + $sql .= " fk_user_modif = ".((int) $user->id); $sql .= " WHERE rowid = ".((int) $this->id).' AND fk_statut > '.self::STATUS_DRAFT; if ($this->db->query($sql)) { @@ -810,7 +826,8 @@ class Commande extends CommonOrder $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."commande"; - $sql .= " SET fk_statut = ".self::STATUS_CANCELED; + $sql .= " SET fk_statut = ".self::STATUS_CANCELED.","; + $sql .= " fk_user_modif = ".((int) $user->id); $sql .= " WHERE rowid = ".((int) $this->id); $sql .= " AND fk_statut = ".self::STATUS_VALIDATED; @@ -929,7 +946,7 @@ class Commande extends CommonOrder $sql = "INSERT INTO ".MAIN_DB_PREFIX."commande ("; $sql .= " ref, fk_soc, date_creation, fk_user_author, fk_projet, date_commande, source, note_private, note_public, ref_ext, ref_client, ref_int"; - $sql .= ", model_pdf, fk_cond_reglement, fk_mode_reglement, fk_account, fk_availability, fk_input_reason, date_livraison, fk_delivery_address"; + $sql .= ", model_pdf, fk_cond_reglement, deposit_percent, fk_mode_reglement, fk_account, fk_availability, fk_input_reason, date_livraison, fk_delivery_address"; $sql .= ", fk_shipping_method"; $sql .= ", fk_warehouse"; $sql .= ", remise_absolue, remise_percent"; @@ -950,6 +967,7 @@ class Commande extends CommonOrder $sql .= ", ".($this->ref_int ? "'".$this->db->escape($this->ref_int)."'" : "null"); $sql .= ", '".$this->db->escape($this->model_pdf)."'"; $sql .= ", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) : "null"); + $sql .= ", ".(! empty($this->deposit_percent) ? "'".$this->db->escape($this->deposit_percent)."'" : "null"); $sql .= ", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) : "null"); $sql .= ", ".($this->fk_account > 0 ? ((int) $this->fk_account) : 'NULL'); $sql .= ", ".($this->availability_id > 0 ? ((int) $this->availability_id) : "null"); @@ -1055,7 +1073,7 @@ class Commande extends CommonOrder return -1; } // Defined the new fk_parent_line - if ($result > 0 && $line->product_type == 9) { + if ($result > 0) { $fk_parent_line = $result; } } @@ -1201,6 +1219,7 @@ class Commande extends CommonOrder if ($objsoc->fetch($socid) > 0) { $this->socid = $objsoc->id; $this->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0); + $this->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent : null); $this->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0); $this->fk_project = 0; $this->fk_delivery_address = 0; @@ -1343,6 +1362,7 @@ class Commande extends CommonOrder $this->socid = $object->socid; $this->fk_project = $object->fk_project; $this->cond_reglement_id = $object->cond_reglement_id; + $this->deposit_percent = $object->deposit_percent; $this->mode_reglement_id = $object->mode_reglement_id; $this->fk_account = $object->fk_account; $this->availability_id = $object->availability_id; @@ -1646,7 +1666,6 @@ class Commande extends CommonOrder // TODO Ne plus utiliser $this->line->price = $price; - $this->line->remise = $remise; if (is_array($array_options) && count($array_options) > 0) { $this->line->array_options = $array_options; @@ -1657,6 +1676,11 @@ class Commande extends CommonOrder // Reorder if child line if (!empty($fk_parent_line)) { $this->line_order(true, 'DESC'); + } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) { // Update all rank of all other lines + $linecount = count($this->lines); + for ($ii = $ranktouse; $ii <= $linecount; $ii++) { + $this->updateRangOfLine($this->lines[$ii - 1]->id, $ii + 1); + } } // Mise a jour informations denormalisees au niveau de la commande meme @@ -1794,8 +1818,8 @@ class Commande extends CommonOrder return -1; } - $sql = 'SELECT c.rowid, c.entity, c.date_creation, c.ref, c.fk_soc, c.fk_user_author, c.fk_user_valid, c.fk_statut'; - $sql .= ', c.amount_ht, c.total_ht, c.total_ttc, c.total_tva, c.localtax1 as total_localtax1, c.localtax2 as total_localtax2, c.fk_cond_reglement, c.fk_mode_reglement, c.fk_availability, c.fk_input_reason'; + $sql = 'SELECT c.rowid, c.entity, c.date_creation, c.ref, c.fk_soc, c.fk_user_author, c.fk_user_valid, c.fk_user_modif, c.fk_statut'; + $sql .= ', c.amount_ht, c.total_ht, c.total_ttc, c.total_tva, c.localtax1 as total_localtax1, c.localtax2 as total_localtax2, c.fk_cond_reglement, c.deposit_percent, c.fk_mode_reglement, c.fk_availability, c.fk_input_reason'; $sql .= ', c.fk_account'; $sql .= ', c.date_commande, c.date_valid, c.tms'; $sql .= ', c.date_livraison as delivery_date'; @@ -1859,6 +1883,7 @@ class Commande extends CommonOrder $this->user_author_id = $obj->fk_user_author; $this->user_valid = $obj->fk_user_valid; + $this->user_modification = $obj->fk_user_modif; $this->total_ht = $obj->total_ht; $this->total_tva = $obj->total_tva; $this->total_localtax1 = $obj->total_localtax1; @@ -1887,6 +1912,7 @@ class Commande extends CommonOrder $this->cond_reglement_code = $obj->cond_reglement_code; $this->cond_reglement = $obj->cond_reglement_libelle; $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc; + $this->deposit_percent = $obj->deposit_percent; $this->fk_account = $obj->fk_account; $this->availability_id = $obj->fk_availability; $this->availability_code = $obj->availability_code; @@ -1983,7 +2009,6 @@ class Commande extends CommonOrder $line->price = -$remise->amount_ht; $line->fk_product = 0; // Id produit predefini $line->qty = 1; - $line->remise = 0; $line->remise_percent = 0; $line->rang = -1; $line->info_bits = 2; @@ -2025,8 +2050,9 @@ class Commande extends CommonOrder */ public function fetch_lines($only_product = 0, $loadalsotranslation = 0) { - global $langs, $conf; // phpcs:enable + global $langs, $conf; + $this->lines = array(); $sql = 'SELECT l.rowid, l.fk_product, l.fk_parent_line, l.product_type, l.fk_commande, l.label as custom_label, l.description, l.price, l.qty, l.vat_src_code, l.tva_tx, l.ref_ext,'; @@ -2126,9 +2152,11 @@ class Commande extends CommonOrder // multilangs if (!empty($conf->global->MAIN_MULTILANGS) && !empty($objp->fk_product) && !empty($loadalsotranslation)) { - $line = new Product($this->db); - $line->fetch($objp->fk_product); - $line->getMultiLangs(); + $tmpproduct = new Product($this->db); + $tmpproduct->fetch($objp->fk_product); + $tmpproduct->getMultiLangs(); + + $line->multilangs = $tmpproduct->multilangs; } $this->lines[$i] = $line; @@ -3059,9 +3087,10 @@ class Commande extends CommonOrder * @param double $pu_ht_devise Amount in currency * @param int $notrigger disable line update trigger * @param string $ref_ext external reference + * @param integer $rang line rank * @return int < 0 if KO, > 0 if OK */ - public function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $price_base_type = 'HT', $info_bits = 0, $date_start = '', $date_end = '', $type = 0, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice = null, $pa_ht = 0, $label = '', $special_code = 0, $array_options = 0, $fk_unit = null, $pu_ht_devise = 0, $notrigger = 0, $ref_ext = '') + public function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $price_base_type = 'HT', $info_bits = 0, $date_start = '', $date_end = '', $type = 0, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice = null, $pa_ht = 0, $label = '', $special_code = 0, $array_options = 0, $fk_unit = null, $pu_ht_devise = 0, $notrigger = 0, $ref_ext = '', $rang = 0) { global $conf, $mysoc, $langs, $user; @@ -3186,6 +3215,7 @@ class Commande extends CommonOrder $line->oldline = $staticline; $this->line = $line; $this->line->context = $this->context; + $this->line->rang = $rang; // Reorder if fk_parent_line change if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) { @@ -3232,7 +3262,6 @@ class Commande extends CommonOrder // TODO deprecated $this->line->price = $price; - $this->line->remise = $remise; if (is_array($array_options) && count($array_options) > 0) { // We replace values in this->line->array_options only for entries defined into $array_options @@ -3322,6 +3351,7 @@ class Commande extends CommonOrder $sql .= " fk_user_valid=".(isset($this->user_valid) ? $this->user_valid : "null").","; $sql .= " fk_projet=".(isset($this->fk_project) ? $this->fk_project : "null").","; $sql .= " fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id : "null").","; + $sql .= " deposit_percent=".(! empty($this->deposit_percent) ? strval($this->deposit_percent) : "null").","; $sql .= " fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id : "null").","; $sql .= " date_livraison=".(strval($this->delivery_date) != '' ? "'".$this->db->idate($this->delivery_date)."'" : 'null').","; $sql .= " fk_shipping_method=".(isset($this->shipping_method_id) ? $this->shipping_method_id : "null").","; @@ -3663,11 +3693,12 @@ class Commande extends CommonOrder * @param int $notooltip 1=Disable tooltip * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking * @param int $addlinktonotes Add link to notes + * @param string $target attribute target for link * @return string String with URL */ - public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0) + public function getNomUrl($withpicto = 0, $option = '', $max = 0, $short = 0, $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0, $target = '') { - global $conf, $langs, $user; + global $conf, $langs, $user, $hookmanager; if (!empty($conf->dol_no_mouse_hover)) { $notooltip = 1; // Force disable tooltips @@ -3719,7 +3750,7 @@ class Commande extends CommonOrder $label .= '
    '.$langs->trans('AmountTTC').': '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency); } if (!empty($this->date)) { - $label .= '
    '.$langs->trans('Date').': '.dol_print_date($this->date, 'dayhour'); + $label .= '
    '.$langs->trans('Date').': '.dol_print_date($this->date, 'day'); } if (!empty($this->delivery_date)) { $label .= '
    '.$langs->trans('DeliveryDate').': '.dol_print_date($this->delivery_date, 'dayhour'); @@ -3734,6 +3765,11 @@ class Commande extends CommonOrder } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip"'; + + $target_value=array('_self', '_blank', '_parent', '_top'); + if (in_array($target, $target_value)) { + $linkclose .= ' target="'.dol_escape_htmltag($target).'"'; + } } $linkstart = 'initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } @@ -4012,6 +4057,23 @@ class Commande extends CommonOrder return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'commandedet', + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * Is the customer order delayed? * @@ -4341,9 +4403,6 @@ class OrderLine extends CommonOrderLine if (empty($this->rang)) { $this->rang = 0; } - if (empty($this->remise)) { - $this->remise = 0; - } if (empty($this->remise_percent)) { $this->remise_percent = 0; } @@ -4384,7 +4443,7 @@ class OrderLine extends CommonOrderLine $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'commandedet'; $sql .= ' (fk_commande, fk_parent_line, label, description, qty, ref_ext,'; $sql .= ' vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,'; - $sql .= ' fk_product, product_type, remise_percent, subprice, price, remise, fk_remise_except,'; + $sql .= ' fk_product, product_type, remise_percent, subprice, price, fk_remise_except,'; $sql .= ' special_code, rang, fk_product_fournisseur_price, buy_price_ht,'; $sql .= ' info_bits, total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, date_start, date_end,'; $sql .= ' fk_unit'; @@ -4407,7 +4466,6 @@ class OrderLine extends CommonOrderLine $sql .= " '".price2num($this->remise_percent)."',"; $sql .= " ".(price2num($this->subprice) !== '' ?price2num($this->subprice) : "null").","; $sql .= " ".($this->price != '' ? "'".price2num($this->price)."'" : "null").","; - $sql .= " '".price2num($this->remise)."',"; $sql .= ' '.(!empty($this->fk_remise_except) ? $this->fk_remise_except : "null").','; $sql .= ' '.((int) $this->special_code).','; $sql .= ' '.((int) $this->rang).','; @@ -4516,9 +4574,6 @@ class OrderLine extends CommonOrderLine if (empty($this->marge_tx)) { $this->marge_tx = 0; } - if (empty($this->remise)) { - $this->remise = 0; - } if (empty($this->remise_percent)) { $this->remise_percent = 0; } @@ -4610,7 +4665,7 @@ class OrderLine extends CommonOrderLine if (!$error && !$notrigger) { // Call trigger - $result = $this->call_trigger('LINEORDER_UPDATE', $user); + $result = $this->call_trigger('LINEORDER_MODIFY', $user); if ($result < 0) { $error++; } diff --git a/htdocs/commande/contact.php b/htdocs/commande/contact.php index a4d857a47fd..b89623fc3a0 100644 --- a/htdocs/commande/contact.php +++ b/htdocs/commande/contact.php @@ -91,13 +91,6 @@ if ($action == 'addcontact' && $user->rights->commande->creer) { setEventMessages($object->error, $object->errors, 'errors'); } } -/* -elseif ($action == 'setaddress' && $user->rights->commande->creer) -{ - $object->fetch($id); - $result=$object->setDeliveryAddress($_POST['fk_address']); - if ($result < 0) dol_print_error($db,$object->error); -}*/ /* diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 519e9c0e6a9..cdabf9f2a5a 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -40,6 +40,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +if (!empty($conf->margin->enabled)) { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmargin.class.php'; +} require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; @@ -187,6 +190,10 @@ $arrayfields = array( 'c.multicurrency_total_ttc'=>array('label'=>'MulticurrencyAmountTTC', 'checked'=>0, 'enabled'=>(empty($conf->multicurrency->enabled) ? 0 : 1), 'position'=>110), 'u.login'=>array('label'=>"Author", 'checked'=>1, 'position'=>115), 'sale_representative'=>array('label'=>"SaleRepresentativesOfThirdParty", 'checked'=>0, 'position'=>116), + 'total_pa' => array('label' => (getDolGlobalString('MARGIN_TYPE') == '1' ? 'BuyingPrice' : 'CostPrice'), 'checked' => 0, 'position' => 300, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous ? 0 : 1)), + 'total_margin' => array('label' => 'Margin', 'checked' => 0, 'position' => 301, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous ? 0 : 1)), + 'total_margin_rate' => array('label' => 'MarginRate', 'checked' => 0, 'position' => 302, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous || empty($conf->global->DISPLAY_MARGIN_RATES) ? 0 : 1)), + 'total_mark_rate' => array('label' => 'MarkRate', 'checked' => 0, 'position' => 303, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous || empty($conf->global->DISPLAY_MARK_RATES) ? 0 : 1)), 'c.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>120), 'c.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>125), 'c.date_cloture'=>array('label'=>"DateClosing", 'checked'=>0, 'position'=>130), @@ -194,6 +201,7 @@ $arrayfields = array( 'c.note_private'=>array('label'=>'NotePrivate', 'checked'=>0, 'enabled'=>(empty($conf->global->MAIN_LIST_ALLOW_PRIVATE_NOTES)), 'position'=>140), 'shippable'=>array('label'=>"Shippable", 'checked'=>1,'enabled'=>(!empty($conf->expedition->enabled)), 'position'=>990), 'c.facture'=>array('label'=>"Billed", 'checked'=>1, 'enabled'=>(empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)), 'position'=>995), + 'c.import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>999), 'c.fk_statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000) ); // Extra fields @@ -259,7 +267,7 @@ if (empty($reshook)) { $search_project = ''; $search_status = ''; $search_billed = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); $search_categ_cus = 0; $search_datecloture_start = ''; @@ -294,6 +302,352 @@ if (empty($reshook)) { $uploaddir = $conf->commande->multidir_output[$conf->entity]; $triggersendname = 'ORDER_SENTBYMAIL'; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + + if ($massaction == 'confirm_createbills') { // Create bills from orders. + $orders = GETPOST('toselect', 'array'); + $createbills_onebythird = GETPOST('createbills_onebythird', 'int'); + $validate_invoices = GETPOST('validate_invoices', 'int'); + + $errors = array(); + + $TFact = array(); + $TFactThird = array(); + $TFactThirdNbLines = array(); + + $nb_bills_created = 0; + $lastid= 0; + $lastref = ''; + + $db->begin(); + + foreach ($orders as $id_order) { + $cmd = new Commande($db); + if ($cmd->fetch($id_order) <= 0) { + continue; + } + $cmd->fetch_thirdparty(); + + $objecttmp = new Facture($db); + if (!empty($createbills_onebythird) && !empty($TFactThird[$cmd->socid])) { + // If option "one bill per third" is set, and an invoice for this thirdparty was already created, we re-use it. + $objecttmp = $TFactThird[$cmd->socid]; + } else { + // If we want one invoice per order or if there is no first invoice yet for this thirdparty. + $objecttmp->socid = $cmd->socid; + $objecttmp->thirdparty = $cmd->thirdparty; + + $objecttmp->type = $objecttmp::TYPE_STANDARD; + $objecttmp->cond_reglement_id = !empty($cmd->cond_reglement_id) ? $cmd->cond_reglement_id : $cmd->thirdparty->cond_reglement_id; + $objecttmp->mode_reglement_id = !empty($cmd->mode_reglement_id) ? $cmd->mode_reglement_id : $cmd->thirdparty->mode_reglement_id; + + $objecttmp->fk_project = $cmd->fk_project; + $objecttmp->multicurrency_code = $cmd->multicurrency_code; + if (empty($createbills_onebythird)) { + $objecttmp->ref_client = $cmd->ref_client; + } + + $datefacture = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); + if (empty($datefacture)) { + $datefacture = dol_now(); + } + + $objecttmp->date = $datefacture; + $objecttmp->origin = 'commande'; + $objecttmp->origin_id = $id_order; + + $objecttmp->array_options = $cmd->array_options; // Copy extrafields + + $res = $objecttmp->create($user); + + if ($res > 0) { + $nb_bills_created++; + $lastref = $objecttmp->ref; + $lastid = $objecttmp->id; + + $TFactThird[$cmd->socid] = $objecttmp; + $TFactThirdNbLines[$cmd->socid] = 0; //init nblines to have lines ordered by expedition and rang + } else { + $langs->load("errors"); + $errors[] = $cmd->ref.' : '.$langs->trans($objecttmp->errors[0]); + $error++; + } + } + + if ($objecttmp->id > 0) { + $res = $objecttmp->add_object_linked($objecttmp->origin, $id_order); + + if ($res == 0) { + $errors[] = $cmd->ref.' : '.$langs->trans($objecttmp->errors[0]); + $error++; + } + + if (!$error) { + $lines = $cmd->lines; + if (empty($lines) && method_exists($cmd, 'fetch_lines')) { + $cmd->fetch_lines(); + $lines = $cmd->lines; + } + + $fk_parent_line = 0; + $num = count($lines); + + for ($i = 0; $i < $num; $i++) { + $desc = ($lines[$i]->desc ? $lines[$i]->desc : ''); + // If we build one invoice for several orders, we must put the ref of order on the invoice line + if (!empty($createbills_onebythird)) { + $desc = dol_concatdesc($desc, $langs->trans("Order").' '.$cmd->ref.' - '.dol_print_date($cmd->date, 'day')); + } + + if ($lines[$i]->subprice < 0) { + // Negative line, we create a discount line + $discount = new DiscountAbsolute($db); + $discount->fk_soc = $objecttmp->socid; + $discount->amount_ht = abs($lines[$i]->total_ht); + $discount->amount_tva = abs($lines[$i]->total_tva); + $discount->amount_ttc = abs($lines[$i]->total_ttc); + $discount->tva_tx = $lines[$i]->tva_tx; + $discount->fk_user = $user->id; + $discount->description = $desc; + $discountid = $discount->create($user); + if ($discountid > 0) { + $result = $objecttmp->insert_discount($discountid); + //$result=$discount->link_to_invoice($lineid,$id); + } else { + setEventMessages($discount->error, $discount->errors, 'errors'); + $error++; + break; + } + } else { + // Positive line + $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0); + // Date start + $date_start = false; + if ($lines[$i]->date_debut_prevue) { + $date_start = $lines[$i]->date_debut_prevue; + } + if ($lines[$i]->date_debut_reel) { + $date_start = $lines[$i]->date_debut_reel; + } + if ($lines[$i]->date_start) { + $date_start = $lines[$i]->date_start; + } + //Date end + $date_end = false; + if ($lines[$i]->date_fin_prevue) { + $date_end = $lines[$i]->date_fin_prevue; + } + if ($lines[$i]->date_fin_reel) { + $date_end = $lines[$i]->date_fin_reel; + } + if ($lines[$i]->date_end) { + $date_end = $lines[$i]->date_end; + } + // Reset fk_parent_line for no child products and special product + if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) { + $fk_parent_line = 0; + } + + // Extrafields + if (method_exists($lines[$i], 'fetch_optionals')) { + $lines[$i]->fetch_optionals(); + $array_options = $lines[$i]->array_options; + } + + $objecttmp->context['createfromclone']; + + $rang = $lines[$i]->rang; + //there may already be rows from previous orders + if (!empty($createbills_onebythird)) + $rang = $TFactThirdNbLines[$cmd->socid]; + + $result = $objecttmp->addline( + $desc, + $lines[$i]->subprice, + $lines[$i]->qty, + $lines[$i]->tva_tx, + $lines[$i]->localtax1_tx, + $lines[$i]->localtax2_tx, + $lines[$i]->fk_product, + $lines[$i]->remise_percent, + $date_start, + $date_end, + 0, + $lines[$i]->info_bits, + $lines[$i]->fk_remise_except, + 'HT', + 0, + $product_type, + $rang, + $lines[$i]->special_code, + $objecttmp->origin, + $lines[$i]->rowid, + $fk_parent_line, + $lines[$i]->fk_fournprice, + $lines[$i]->pa_ht, + $lines[$i]->label, + $array_options, + 100, + 0, + $lines[$i]->fk_unit + ); + if ($result > 0) { + $lineid = $result; + if (!empty($createbills_onebythird)) //increment rang to keep order + $TFactThirdNbLines[$rcp->socid]++; + } else { + $lineid = 0; + $error++; + break; + } + // Defined the new fk_parent_line + if ($result > 0 && $lines[$i]->product_type == 9) { + $fk_parent_line = $result; + } + } + } + } + } + + //$cmd->classifyBilled($user); // Disabled. This behavior must be set or not using the workflow module. + + if (!empty($createbills_onebythird) && empty($TFactThird[$cmd->socid])) { + $TFactThird[$cmd->socid] = $objecttmp; + } else { + $TFact[$objecttmp->id] = $objecttmp; + } + } + + // Build doc with all invoices + $TAllFact = empty($createbills_onebythird) ? $TFact : $TFactThird; + $toselect = array(); + + if (!$error && $validate_invoices) { + $massaction = $action = 'builddoc'; + + foreach ($TAllFact as &$objecttmp) { + $result = $objecttmp->validate($user); + if ($result <= 0) { + $error++; + setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); + break; + } + + $id = $objecttmp->id; // For builddoc action + + // Builddoc + $donotredirect = 1; + $upload_dir = $conf->facture->dir_output; + $permissiontoadd = $user->rights->facture->creer; + + // Call action to build doc + $savobject = $object; + $object = $objecttmp; + include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; + $object = $savobject; + } + + $massaction = $action = 'confirm_createbills'; + } + + if (!$error) { + $db->commit(); + + if ($nb_bills_created == 1) { + $texttoshow = $langs->trans('BillXCreated', '{s1}'); + $texttoshow = str_replace('{s1}', ''.$lastref.'', $texttoshow); + setEventMessages($texttoshow, null, 'mesgs'); + } else { + setEventMessages($langs->trans('BillCreated', $nb_bills_created), null, 'mesgs'); + } + + // Make a redirect to avoid to bill twice if we make a refresh or back + $param = ''; + if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { + $param .= '&contextpage='.urlencode($contextpage); + } + if ($limit > 0 && $limit != $conf->liste_limit) { + $param .= '&limit='.urlencode($limit); + } + if ($sall) { + $param .= '&sall='.urlencode($sall); + } + if ($socid > 0) { + $param .= '&socid='.urlencode($socid); + } + if ($search_status != '') { + $param .= '&search_status='.urlencode($search_status); + } + if ($search_orderday) { + $param .= '&search_orderday='.urlencode($search_orderday); + } + if ($search_ordermonth) { + $param .= '&search_ordermonth='.urlencode($search_ordermonth); + } + if ($search_orderyear) { + $param .= '&search_orderyear='.urlencode($search_orderyear); + } + if ($search_deliveryday) { + $param .= '&search_deliveryday='.urlencode($search_deliveryday); + } + if ($search_deliverymonth) { + $param .= '&search_deliverymonth='.urlencode($search_deliverymonth); + } + if ($search_deliveryyear) { + $param .= '&search_deliveryyear='.urlencode($search_deliveryyear); + } + if ($search_ref) { + $param .= '&search_ref='.urlencode($search_ref); + } + if ($search_company) { + $param .= '&search_company='.urlencode($search_company); + } + if ($search_ref_customer) { + $param .= '&search_ref_customer='.urlencode($search_ref_customer); + } + if ($search_user > 0) { + $param .= '&search_user='.urlencode($search_user); + } + if ($search_sale > 0) { + $param .= '&search_sale='.urlencode($search_sale); + } + if ($search_total_ht != '') { + $param .= '&search_total_ht='.urlencode($search_total_ht); + } + if ($search_total_vat != '') { + $param .= '&search_total_vat='.urlencode($search_total_vat); + } + if ($search_total_ttc != '') { + $param .= '&search_total_ttc='.urlencode($search_total_ttc); + } + if ($search_project_ref >= 0) { + $param .= "&search_project_ref=".urlencode($search_project_ref); + } + if ($show_files) { + $param .= '&show_files='.urlencode($show_files); + } + if ($optioncss != '') { + $param .= '&optioncss='.urlencode($optioncss); + } + if ($billed != '') { + $param .= '&billed='.urlencode($billed); + } + + header("Location: ".$_SERVER['PHP_SELF'].'?'.$param); + exit; + } else { + $db->rollback(); + + $action = 'create'; + $_GET["origin"] = $_POST["origin"]; + $_GET["originid"] = $_POST["originid"]; + if (!empty($errors)) { + setEventMessages(null, $errors, 'errors'); + } else { + setEventMessages("Error", null, 'errors'); + } + $error++; + } + } } if ($action == 'validate' && $permissiontoadd) { if (GETPOST('confirm') == 'yes') { @@ -311,7 +665,7 @@ if ($action == 'validate' && $permissiontoadd) { if ($objecttmp->valid($user, $idwarehouse)) { setEventMessage($langs->trans('hasBeenValidated', $objecttmp->ref), 'mesgs'); } else { - setEventMessage($langs->trans('CantBeValidated'), 'errors'); + setEventMessage($objecttmp->error, $objecttmp->errors, 'errors'); $error++; } } else { @@ -407,6 +761,10 @@ $now = dol_now(); $form = new Form($db); $formother = new FormOther($db); $formfile = new FormFile($db); +$formmargin = null; +if (!empty($conf->margin->enabled)) { + $formmargin = new FormMargin($db); +} $companystatic = new Societe($db); $formcompany = new FormCompany($db); $projectstatic = new Project($db); @@ -429,8 +787,8 @@ $sql .= ' c.date_valid, c.date_commande, c.note_public, c.note_private, c.date_l $sql .= ' c.date_creation as date_creation, c.tms as date_update, c.date_cloture as date_cloture,'; $sql .= ' p.rowid as project_id, p.ref as project_ref, p.title as project_label,'; $sql .= ' u.login, u.lastname, u.firstname, u.email as user_email, u.statut as user_statut, u.entity, u.photo, u.office_phone, u.office_fax, u.user_mobile, u.job, u.gender,'; -$sql .= ' c.fk_cond_reglement,c.fk_mode_reglement,c.fk_shipping_method,'; -$sql .= ' c.fk_input_reason'; +$sql .= ' c.fk_cond_reglement,c.deposit_percent,c.fk_mode_reglement,c.fk_shipping_method,'; +$sql .= ' c.fk_input_reason, c.import_key'; if (($search_categ_cus > 0) || ($search_categ_cus == -2)) { $sql .= ", cc.fk_categorie, cc.fk_soc"; } @@ -657,12 +1015,12 @@ if ($resql) { if ($socid > 0) { $soc = new Societe($db); $soc->fetch($socid); - $title = $langs->trans('ListOfOrders').' - '.$soc->name; + $title = $langs->trans('CustomersOrders').' - '.$soc->name; if (empty($search_company)) { $search_company = $soc->name; } } else { - $title = $langs->trans('ListOfOrders'); + $title = $langs->trans('CustomersOrders'); } if (strval($search_status) == '0') { $title .= ' - '.$langs->trans('StatusOrderDraftShort'); @@ -963,7 +1321,7 @@ if ($resql) { $moreforfilter = ''; // If the user can view prospects other than his' - if ($user->rights->societe->client->voir || $socid) { + if ($user->rights->user->user->lire) { $langs->load("commercial"); $moreforfilter .= '
    '; $tmptitle = $langs->trans('ThirdPartiesOfSaleRepresentative'); @@ -1121,7 +1479,7 @@ if ($resql) { // Payment term if (!empty($arrayfields['c.fk_cond_reglement']['checked'])) { print '
    '; } // Payment mode @@ -1193,6 +1551,22 @@ if ($resql) { if (!empty($arrayfields['sale_representative']['checked'])) { print ''; } + if (!empty($arrayfields['total_pa']['checked'])) { + print ''; + } + if (!empty($arrayfields['total_margin']['checked'])) { + print ''; + } + if (!empty($arrayfields['total_margin_rate']['checked'])) { + print ''; + } + if (!empty($arrayfields['total_mark_rate']['checked'])) { + print ''; + } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; // Fields from hook @@ -1248,6 +1622,11 @@ if ($resql) { print $form->selectyesno('search_billed', $search_billed, 1, 0, 1, 1); print ''; } + // Import key + if (!empty($arrayfields['c.import_key']['checked'])) { + print ''; + } // Status if (!empty($arrayfields['c.fk_statut']['checked'])) { print ''; // Ref @@ -1462,11 +1879,6 @@ if ($resql) { print ''; if (!$i) { $totalarray['nbfield']++; @@ -1616,7 +2032,7 @@ if ($resql) { // Payment terms if (!empty($arrayfields['c.fk_cond_reglement']['checked'])) { print ''; if (!$i) { $totalarray['nbfield']++; @@ -1792,6 +2208,49 @@ if ($resql) { } } + // Total buying or cost price + if (!empty($arrayfields['total_pa']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Total margin + if (!empty($arrayfields['total_margin']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 'total_margin'; + } + $totalarray['val']['total_margin'] += $marginInfo['total_margin']; + } + // Total margin rate + if (!empty($arrayfields['total_margin_rate']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Total mark rate + if (!empty($arrayfields['total_mark_rate']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 'total_mark_rate'; + } + if ($i >= $last_num - 1) { + if (!empty($total_ht)) { + $totalarray['val']['total_mark_rate'] = price2num($total_margin * 100 / $total_ht, 'MT'); + } else { + $totalarray['val']['total_mark_rate'] = ''; + } + } + } + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook @@ -1831,8 +2290,8 @@ if ($resql) { // Note public if (!empty($arrayfields['c.note_public']['checked'])) { - print ''; if (!$i) { $totalarray['nbfield']++; @@ -1841,8 +2300,8 @@ if ($resql) { // Note private if (!empty($arrayfields['c.note_private']['checked'])) { - print ''; if (!$i) { $totalarray['nbfield']++; @@ -1959,6 +2418,13 @@ if ($resql) { $totalarray['nbfield']++; } } + // Import key + if (!empty($arrayfields['c.import_key']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } // Status if (!empty($arrayfields['c.fk_statut']['checked'])) { print ''; diff --git a/htdocs/commande/stats/index.php b/htdocs/commande/stats/index.php index 603627ee91e..3e33ddedf57 100644 --- a/htdocs/commande/stats/index.php +++ b/htdocs/commande/stats/index.php @@ -394,11 +394,11 @@ foreach ($data as $val) { print ''; print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; $oldyear = $year; } diff --git a/htdocs/commande/tpl/linkedobjectblock.tpl.php b/htdocs/commande/tpl/linkedobjectblock.tpl.php index 2a6140aaeed..8c1df906ab7 100644 --- a/htdocs/commande/tpl/linkedobjectblock.tpl.php +++ b/htdocs/commande/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -print "\n"; +print "\n"; global $user; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index 3942e7cb6dd..8f61261bc11 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -625,24 +625,24 @@ if (!empty($date_start) && !empty($date_stop)) { $param .= '&action=searchfiles'; /* - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - foreach ($listofchoices as $choice => $val) { - print ''; - } + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + foreach ($listofchoices as $choice => $val) { + print ''; + } - print ''; - print ''."\n"; - */ + print ''; + print ''."\n"; + */ print '
    '; diff --git a/htdocs/compta/ajaxpayment.php b/htdocs/compta/ajaxpayment.php index d22e1a0182a..0332a925f9d 100644 --- a/htdocs/compta/ajaxpayment.php +++ b/htdocs/compta/ajaxpayment.php @@ -47,28 +47,32 @@ $langs->load('compta'); //init var $invoice_type = GETPOST('invoice_type', 'int'); -$amountPayment = $_POST['amountPayment']; -$amounts = $_POST['amounts']; // from text inputs : invoice amount payment (check required) -$remains = $_POST['remains']; // from dolibarr's object (no need to check) -$currentInvId = $_POST['imgClicked']; // from DOM elements : imgId (equals invoice id) +$amountPayment = GETPOST('amountPayment'); +$amounts = GETPOST('amounts'); // from text inputs : invoice amount payment (check required) +$remains = GETPOST('remains'); // from dolibarr's object (no need to check) +$currentInvId = GETPOST('imgClicked'); // from DOM elements : imgId (equals invoice id) // Getting the posted keys=>values, sanitize the ones who are from text inputs $amountPayment = $amountPayment != '' ? (is_numeric(price2num($amountPayment)) ? price2num($amountPayment) : '') : ''; // keep void if not a valid entry // Clean checkamounts -foreach ($amounts as $key => $value) { - $value = price2num($value); - $amounts[$key] = $value; - if (empty($value)) { - unset($amounts[$key]); +if (is_array($amounts)) { + foreach ($amounts as $key => $value) { + $value = price2num($value); + $amounts[$key] = $value; + if (empty($value)) { + unset($amounts[$key]); + } } } // Clean remains -foreach ($remains as $key => $value) { - $value = price2num($value); - $remains[$key] = (($invoice_type) == 2 ?-1 : 1) * $value; - if (empty($value)) { - unset($remains[$key]); +if (is_array($remains)) { + foreach ($remains as $key => $value) { + $value = price2num($value); + $remains[$key] = (($invoice_type) == 2 ?-1 : 1) * $value; + if (empty($value)) { + unset($remains[$key]); + } } } diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index 421080951f2..fba2d05897c 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -32,14 +32,15 @@ */ require '../../main.inc.php'; + +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/bankcateg.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; - require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/tva/class/paymentvat.class.php'; @@ -54,6 +55,7 @@ require_once DOL_DOCUMENT_ROOT.'/don/class/paymentdonation.class.php'; require_once DOL_DOCUMENT_ROOT.'/expensereport/class/paymentexpensereport.class.php'; require_once DOL_DOCUMENT_ROOT.'/loan/class/loan.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/paiement/cheque/class/remisecheque.class.php'; // Load translation files required by the page $langs->loadLangs(array("banks", "bills", "categories", "companies", "margins", "salaries", "loan", "donations", "trips", "members", "compta", "accountancy")); @@ -99,6 +101,7 @@ $search_thirdparty_user = GETPOST("search_thirdparty", 'alpha') ?GETPOST("search $search_req_nb = GETPOST("req_nb", 'alpha'); $search_num_releve = GETPOST("search_num_releve", 'alpha'); $search_conciliated = GETPOST("search_conciliated", 'int'); +$search_fk_bordereau = GETPOST("search_fk_bordereau", 'int'); $optioncss = GETPOST('optioncss', 'alpha'); $toselect = GETPOST('toselect', 'array'); $num_releve = GETPOST("num_releve", "alpha"); @@ -157,20 +160,21 @@ $extrafields->fetch_name_optionals_label('banktransaction'); $search_array_options = $extrafields->getOptionalsFromPost('banktransaction', '', 'search_'); $arrayfields = array( - 'b.rowid'=>array('label'=>$langs->trans("Ref"), 'checked'=>1), - 'b.label'=>array('label'=>$langs->trans("Description"), 'checked'=>1), - 'b.dateo'=>array('label'=>$langs->trans("DateOperationShort"), 'checked'=>1), - 'b.datev'=>array('label'=>$langs->trans("DateValueShort"), 'checked'=>1), - 'type'=>array('label'=>$langs->trans("Type"), 'checked'=>1), - 'b.num_chq'=>array('label'=>$langs->trans("Numero"), 'checked'=>1), - 'bu.label'=>array('label'=>$langs->trans("ThirdParty").'/'.$langs->trans("User"), 'checked'=>1, 'position'=>500), - 'ba.ref'=>array('label'=>$langs->trans("BankAccount"), 'checked'=>(($id > 0 || !empty($ref)) ? 0 : 1), 'position'=>1000), - 'b.debit'=>array('label'=>$langs->trans("Debit"), 'checked'=>1, 'position'=>600), - 'b.credit'=>array('label'=>$langs->trans("Credit"), 'checked'=>1, 'position'=>605), - 'balancebefore'=>array('label'=>$langs->trans("BalanceBefore"), 'checked'=>0, 'position'=>1000), - 'balance'=>array('label'=>$langs->trans("Balance"), 'checked'=>1, 'position'=>1001), - 'b.num_releve'=>array('label'=>$langs->trans("AccountStatement"), 'checked'=>1, 'position'=>1010), - 'b.conciliated'=>array('label'=>$langs->trans("Conciliated"), 'enabled'=> $object->rappro, 'checked'=>($action == 'reconcile' ? 1 : 0), 'position'=>1020), + 'b.rowid'=>array('label'=>$langs->trans("Ref"), 'checked'=>1,'position'=>10), + 'b.label'=>array('label'=>$langs->trans("Description"), 'checked'=>1,'position'=>20), + 'b.dateo'=>array('label'=>$langs->trans("DateOperationShort"), 'checked'=>1,'position'=>30), + 'b.datev'=>array('label'=>$langs->trans("DateValueShort"), 'checked'=>1,'position'=>40), + 'type'=>array('label'=>$langs->trans("Type"), 'checked'=>1,'position'=>50), + 'b.num_chq'=>array('label'=>$langs->trans("Numero"), 'checked'=>1,'position'=>60), + 'bu.label'=>array('label'=>$langs->trans("ThirdParty").'/'.$langs->trans("User"), 'checked'=>1, 'position'=>70), + 'ba.ref'=>array('label'=>$langs->trans("BankAccount"), 'checked'=>(($id > 0 || !empty($ref)) ? 0 : 1), 'position'=>80), + 'b.debit'=>array('label'=>$langs->trans("Debit"), 'checked'=>1, 'position'=>90), + 'b.credit'=>array('label'=>$langs->trans("Credit"), 'checked'=>1, 'position'=>100), + 'balancebefore'=>array('label'=>$langs->trans("BalanceBefore"), 'checked'=>0, 'position'=>110), + 'balance'=>array('label'=>$langs->trans("Balance"), 'checked'=>1, 'position'=>120), + 'b.num_releve'=>array('label'=>$langs->trans("AccountStatement"), 'checked'=>1, 'position'=>130), + 'b.conciliated'=>array('label'=>$langs->trans("BankLineReconciled"), 'enabled'=> $object->rappro, 'checked'=>($action == 'reconcile' ? 1 : 0), 'position'=>140), + 'b.fk_bordereau'=>array('label'=>$langs->trans("ChequeReceipt"), 'checked'=>0, 'position'=>150), ); // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; @@ -178,7 +182,6 @@ 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'); - /* * Actions */ @@ -214,7 +217,8 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_thirdparty_user = ''; $search_num_releve = ''; $search_conciliated = ''; - $toselect = ''; + $search_fk_bordereau = ''; + $toselect = array(); $search_account = ""; if ($id > 0 || !empty($ref)) { @@ -390,8 +394,6 @@ if ($action == 'confirm_delete' && $confirm == 'yes' && !empty($user->rights->ba } } - - /* * View */ @@ -421,6 +423,7 @@ $paymentvariousstatic = new PaymentVarious($db); $paymentexpensereportstatic = new PaymentExpenseReport($db); $bankstatic = new Account($db); $banklinestatic = new AccountLine($db); +$bordereaustatic = new RemiseCheque($db); $now = dol_now(); @@ -465,6 +468,9 @@ if (!empty($search_num_releve)) { if ($search_conciliated != '' && $search_conciliated != '-1') { $param .= '&search_conciliated='.urlencode($search_conciliated); } +if ($search_fk_bordereau > 0) { + $param .= '$&search_fk_bordereau='.urlencode($search_fk_bordereau); +} if ($search_bid > 0) { $param .= '&search_bid='.urlencode($search_bid); } @@ -547,7 +553,7 @@ if ($id > 0 || !empty($ref)) { if ($user->rights->banque->consolidate) { $newparam = $param; $newparam = preg_replace('/search_conciliated=\d+/i', '', $newparam); - $buttonreconcile = ''.$titletoconciliatemanual.''; + $buttonreconcile = ''.$titletoconciliatemanual.''; } else { $buttonreconcile = ''.$titletoconciliatemanual.''; } @@ -557,7 +563,7 @@ if ($id > 0 || !empty($ref)) { if ($user->rights->banque->consolidate) { $newparam = $param; $newparam = preg_replace('/search_conciliated=\d+/i', '', $newparam); - $buttonreconcile .= ' '.$titletoconciliateauto.''; + $buttonreconcile .= ' '.$titletoconciliateauto.''; } else { $buttonreconcile .= ' '.$titletoconciliateauto.''; } @@ -568,8 +574,9 @@ if ($id > 0 || !empty($ref)) { llxHeader('', $langs->trans("BankTransactions"), '', '', 0, 0, array(), array(), $param); } + $sql = "SELECT b.rowid, b.dateo as do, b.datev as dv, b.amount, b.label, b.rappro as conciliated, b.num_releve, b.num_chq,"; -$sql .= " b.fk_account, b.fk_type,"; +$sql .= " b.fk_account, b.fk_type, b.fk_bordereau,"; $sql .= " ba.rowid as bankid, ba.ref as bankref"; // Add fields from extrafields if (!empty($extrafields->attributes[$object->table_element]['label'])) { @@ -621,6 +628,9 @@ if ($search_num_releve) { if ($search_conciliated != '' && $search_conciliated != '-1') { $sql .= " AND b.rappro = ".((int) $search_conciliated); } +if ($search_fk_bordereau > 0) { + $sql .= " AND b.fk_bordereau = " . ((int) $search_fk_bordereau); +} if ($search_thirdparty_user) { $sql.= " AND (b.rowid IN "; $sql.= " ( SELECT bu.fk_bank FROM ".MAIN_DB_PREFIX."bank_url AS bu"; @@ -737,6 +747,9 @@ if ($search_conciliated != '' && $search_conciliated != '-1') { if (!empty($search_num_releve)) { $mode_balance_ok = false; } +if (!empty($search_fk_bordereau)) { + $mode_balance_ok = false; +} $sql .= $db->plimit($limit + 1, $offset); //print $sql; @@ -983,21 +996,27 @@ if ($resql) { $moreforfilter = ''; $moreforfilter .= '
    '; - $moreforfilter .= $langs->trans('DateOperationShort').' '; + $moreforfilter .= $langs->trans('DateOperationShort'); $moreforfilter .= ($conf->browser->layout == 'phone' ? '
    ' : ' '); $moreforfilter .= '
    '; - $moreforfilter .= $form->selectDate($search_dt_start, 'search_start_dt', 0, 0, 1, "search_form", 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')).'
    '; - //$moreforfilter .= ' - '; - $moreforfilter .= '
    '.$form->selectDate($search_dt_end, 'search_end_dt', 0, 0, 1, "search_form", 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')).'
    '; + $moreforfilter .= $form->selectDate($search_dt_start, 'search_start_dt', 0, 0, 1, "search_form", 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + $moreforfilter .= '
    '; + $moreforfilter .= ($conf->browser->layout == 'phone' ? '' : ' '); + $moreforfilter .= '
    '; + $moreforfilter .= $form->selectDate($search_dt_end, 'search_end_dt', 0, 0, 1, "search_form", 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + $moreforfilter .= '
    '; $moreforfilter .= ''; $moreforfilter .= '
    '; - $moreforfilter .= $langs->trans('DateValueShort').' '; + $moreforfilter .= $langs->trans('DateValueShort'); $moreforfilter .= ($conf->browser->layout == 'phone' ? '
    ' : ' '); $moreforfilter .= '
    '; - $moreforfilter .= $form->selectDate($search_dv_start, 'search_start_dv', 0, 0, 1, "search_form", 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')).'
    '; - //$moreforfilter .= ' - '; - $moreforfilter .= '
    '.$form->selectDate($search_dv_end, 'search_end_dv', 0, 0, 1, "search_form", 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')).'
    '; + $moreforfilter .= $form->selectDate($search_dv_start, 'search_start_dv', 0, 0, 1, "search_form", 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + $moreforfilter .= '
    '; + $moreforfilter .= ($conf->browser->layout == 'phone' ? '' : ' '); + $moreforfilter .= '
    '; + $moreforfilter .= $form->selectDate($search_dv_end, 'search_end_dv', 0, 0, 1, "search_form", 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + $moreforfilter .= '
    '; $moreforfilter .= ''; if (!empty($conf->categorie->enabled)) { @@ -1061,34 +1080,40 @@ if ($resql) { $form->select_types_paiements(empty($search_type) ? '' : $search_type, 'search_type', '', 2, 1, 1, 0, 1, 'maxwidth100'); print ''; } + // Numero if (!empty($arrayfields['b.num_chq']['checked'])) { - // Numero print ''; } + // Checked if (!empty($arrayfields['bu.label']['checked'])) { print ''; } + // Ref if (!empty($arrayfields['ba.ref']['checked'])) { print ''; } + // Debit if (!empty($arrayfields['b.debit']['checked'])) { print ''; } + // Credit if (!empty($arrayfields['b.credit']['checked'])) { print ''; } + // Balance before if (!empty($arrayfields['balancebefore']['checked'])) { print ''; } + // Balance if (!empty($arrayfields['balance']['checked'])) { print ''; } + // Bordereau + if (!empty($arrayfields['b.fk_bordereau']['checked'])) { + print ''; + } + // Actions and select print ''; if (!$i) { $totalarray['nbfield']++; @@ -1491,7 +1526,7 @@ if ($resql) { // Payment type if (!empty($arrayfields['type']['checked'])) { - print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Action edit/delete and select print ''; // Tags-Categories - if ($conf->categorie->enabled) { + if (!empty($conf->categorie->enabled)) { print ''; print ''; + if ($conf->paymentbybanktransfer->enabled) { + print ''; + print ''; + } + print ''; + print ''; + print ''; print '
    '; + print ''; if ($action != 'editdemandreason' && $usercancreate) { @@ -2603,7 +2791,7 @@ if ($action == 'create') { } // Create contract - if ($conf->contrat->enabled && $object->statut == Propal::STATUS_SIGNED) { + if (!empty($conf->contrat->enabled) && $object->statut == Propal::STATUS_SIGNED) { $langs->load("contracts"); if ($usercancreatecontract) { diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index 2cc17987224..d28b5718c2f 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -1,7 +1,9 @@ - * Copyright (C) 2016 Laurent Destailleur - * Copyright (C) 2020 Thibault FOUCART +/* Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2016 Laurent Destailleur + * Copyright (C) 2020 Thibault FOUCART + * Copyright (C) 2022 ATM Consulting + * Copyright (C) 2022 OpenDSI * * 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 @@ -133,8 +135,13 @@ class Proposals extends DolibarrApi } // Add external contacts ids. - $this->propal->contacts_ids = $this->propal->liste_contact(-1, 'external', $contact_list); + $tmparray = $this->propal->liste_contact(-1, 'external', $contact_list); + if (is_array($tmparray)) { + $this->propal->contacts_ids = $tmparray; + } + $this->propal->fetchObjectLinked(); + return $this->_cleanObjectDatas($this->propal); } @@ -226,7 +233,10 @@ class Proposals extends DolibarrApi $proposal_static = new Propal($this->db); if ($proposal_static->fetch($obj->rowid)) { // Add external contacts ids - $proposal_static->contacts_ids = $proposal_static->liste_contact(-1, 'external', 1); + $tmparray = $proposal_static->liste_contact(-1, 'external', 1); + if (is_array($tmparray)) { + $proposal_static->contacts_ids = $tmparray; + } $obj_ret[] = $this->_cleanObjectDatas($proposal_static); } $i++; @@ -274,14 +284,17 @@ class Proposals extends DolibarrApi /** * Get lines of a commercial proposal * - * @param int $id Id of commercial proposal + * @param int $id Id of commercial proposal + * @param string $sqlfilters Other criteria to filter answers separated by a comma. d is the alias for proposal lines table, p is the alias for product table. "Syntax example "(p.ref:like:'SO-%') and (d.date_start:<:'20220101')" * * @url GET {id}/lines * * @return int */ - public function getLines($id) + public function getLines($id, $sqlfilters = '') { + $filters = ""; + if (!DolibarrApiAccess::$user->rights->propal->lire) { throw new RestException(401); } @@ -294,7 +307,16 @@ class Proposals extends DolibarrApi if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - $this->propal->getLinesArray(); + + if (!empty($sqlfilters)) { + if (!DolibarrApi::_checkFilters($sqlfilters)) { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $filters = " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $this->propal->getLinesArray($filters); $result = array(); foreach ($this->propal->lines as $line) { array_push($result, $this->_cleanObjectDatas($line)); @@ -308,7 +330,7 @@ class Proposals extends DolibarrApi * @param int $id Id of commercial proposal to update * @param array $request_data Commercial proposal line data * - * @url POST {id}/lines + * @url POST {id}/line * * @return int */ @@ -329,8 +351,8 @@ class Proposals extends DolibarrApi $request_data = (object) $request_data; - $request_data->desc = checkVal($request_data->desc, 'restricthtml'); - $request_data->label = checkVal($request_data->label); + $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml'); + $request_data->label = sanitizeVal($request_data->label); $updateRes = $this->propal->addline( $request_data->desc, @@ -368,6 +390,84 @@ class Proposals extends DolibarrApi } } + /** + * Add lines to given commercial proposal + * + * @param int $id Id of commercial proposal to update + * @param array $request_data Commercial proposal line data + * + * @url POST {id}/lines + * + * @return int + */ + public function postLines($id, $request_data = null) + { + if (!DolibarrApiAccess::$user->rights->propal->creer) { + throw new RestException(401); + } + + $result = $this->propal->fetch($id); + if (!$result) { + throw new RestException(404, 'Commercial Proposal not found'); + } + + if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $errors = []; + $this->db->begin(); + + foreach ($request_data as $TData) { + if (empty($TData[0])) $TData = array($TData); + + foreach ($TData as $lineData) { + $line = (object) $lineData; + + $updateRes = $this->propal->addline( + $line->desc, + $line->subprice, + $line->qty, + $line->tva_tx, + $line->localtax1_tx, + $line->localtax2_tx, + $line->fk_product, + $line->remise_percent, + 'HT', + 0, + $line->info_bits, + $line->product_type, + $line->rang, + $line->special_code, + $line->fk_parent_line, + $line->fk_fournprice, + $line->pa_ht, + $line->label, + $line->date_start, + $line->date_end, + $line->array_options, + $line->fk_unit, + $line->origin, + $line->origin_id, + $line->multicurrency_subprice, + $line->fk_remise_except + ); + + if ($updateRes < 0) { + $errors['lineLabel'] = $line->label; + $errors['msg'] = $this->propal->errors; + } + } + } + if (empty($errors)) { + $this->db->commit(); + return count($request_data); + } else { + $this->db->rollback(); + throw new RestException(400, implode(", ", $errors)); + } + } + /** * Update a line of given commercial proposal * @@ -396,8 +496,8 @@ class Proposals extends DolibarrApi $request_data = (object) $request_data; - $request_data->desc = checkVal($request_data->desc, 'restricthtml'); - $request_data->label = checkVal($request_data->label); + $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml'); + $request_data->label = sanitizeVal($request_data->label); $propalline = new PropaleLigne($this->db); $result = $propalline->fetch($lineid); @@ -427,7 +527,9 @@ class Proposals extends DolibarrApi isset($request_data->date_end) ? $request_data->date_end : $propalline->date_end, isset($request_data->array_options) ? $request_data->array_options : $propalline->array_options, isset($request_data->fk_unit) ? $request_data->fk_unit : $propalline->fk_unit, - isset($request_data->multicurrency_subprice) ? $request_data->multicurrency_subprice : $propalline->subprice + isset($request_data->multicurrency_subprice) ? $request_data->multicurrency_subprice : $propalline->subprice, + 0, + isset($request_data->rang) ? $request_data->rang : $propalline->rang ); if ($updateRes > 0) { @@ -551,7 +653,7 @@ class Proposals extends DolibarrApi throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - $contacts = $this->invoice->liste_contact(); + $contacts = $this->propal->liste_contact(); foreach ($contacts as $contact) { if ($contact['id'] == $contactid && $contact['code'] == $type) { diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index c18e0e7a6df..73e73fbe2f9 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -1,20 +1,23 @@ - * Copyright (C) 2004 Eric Seigne - * Copyright (C) 2004-2011 Laurent Destailleur - * Copyright (C) 2005 Marc Barilley - * Copyright (C) 2005-2013 Regis Houssin - * Copyright (C) 2006 Andre Cianfarani - * Copyright (C) 2008 Raphael Bertrand - * Copyright (C) 2010-2020 Juanjo Menent - * Copyright (C) 2010-2017 Philippe Grand - * Copyright (C) 2012-2014 Christophe Battarel - * Copyright (C) 2012 Cedric Salvador - * Copyright (C) 2013 Florian Henry - * Copyright (C) 2014-2015 Marcos García - * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2018-2021 Frédéric France - * Copyright (C) 2018 Ferran Marcet +/* Copyright (C) 2002-2004 Rodolphe Quiedeville + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2005 Marc Barilley + * Copyright (C) 2005-2013 Regis Houssin + * Copyright (C) 2006 Andre Cianfarani + * Copyright (C) 2008 Raphael Bertrand + * Copyright (C) 2010-2020 Juanjo Menent + * Copyright (C) 2010-2017 Philippe Grand + * Copyright (C) 2012-2014 Christophe Battarel + * Copyright (C) 2012 Cedric Salvador + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2014-2015 Marcos García + * Copyright (C) 2018 Nicolas ZABOURI + * Copyright (C) 2018-2021 Frédéric France + * Copyright (C) 2018 Ferran Marcet + * Copyright (C) 2022 ATM Consulting + * Copyright (C) 2022 OpenDSI + * Copyright (C) 2022 Gauthier VERDOL * * 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 @@ -203,6 +206,7 @@ class Propal extends CommonObject public $total; public $cond_reglement_code; + public $deposit_percent; public $mode_reglement_code; public $remise_percent; @@ -292,8 +296,8 @@ class Propal extends CommonObject 'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>20), 'ref_client' =>array('type'=>'varchar(255)', 'label'=>'RefCustomer', 'enabled'=>1, 'visible'=>-1, 'position'=>22), 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'RefExt', 'enabled'=>1, 'visible'=>0, 'position'=>40), - 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'position'=>23), - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>24), + 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'$conf->societe->enabled', 'visible'=>-1, 'position'=>23), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>'$conf->projet->enabled', 'visible'=>-1, 'position'=>24), 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>25), 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>55), 'datep' =>array('type'=>'date', 'label'=>'Date', 'enabled'=>1, 'visible'=>-1, 'position'=>60), @@ -313,16 +317,17 @@ class Propal extends CommonObject 'localtax1' =>array('type'=>'double(24,8)', 'label'=>'LocalTax1', 'enabled'=>1, 'visible'=>-1, 'position'=>135, 'isameasure'=>1), 'localtax2' =>array('type'=>'double(24,8)', 'label'=>'LocalTax2', 'enabled'=>1, 'visible'=>-1, 'position'=>140, 'isameasure'=>1), 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'TotalTTC', 'enabled'=>1, 'visible'=>-1, 'position'=>145, 'isameasure'=>1), - 'fk_account' =>array('type'=>'integer', 'label'=>'BankAccount', 'enabled'=>1, 'visible'=>-1, 'position'=>150), + 'fk_account' =>array('type'=>'integer', 'label'=>'BankAccount', 'enabled'=>'$conf->banque->enabled', 'visible'=>-1, 'position'=>150), 'fk_currency' =>array('type'=>'varchar(3)', 'label'=>'Currency', 'enabled'=>1, 'visible'=>-1, 'position'=>155), 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'position'=>160), + 'deposit_percent' =>array('type'=>'varchar(63)', 'label'=>'DepositPercent', 'enabled'=>1, 'visible'=>-1, 'position'=>161), 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'PaymentMode', 'enabled'=>1, 'visible'=>-1, 'position'=>165), 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>170), 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>175), 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'PDFTemplate', 'enabled'=>1, 'visible'=>0, 'position'=>180), 'date_livraison' =>array('type'=>'date', 'label'=>'DateDeliveryPlanned', 'enabled'=>1, 'visible'=>-1, 'position'=>185), 'fk_shipping_method' =>array('type'=>'integer', 'label'=>'ShippingMethod', 'enabled'=>1, 'visible'=>-1, 'position'=>190), - 'fk_warehouse' =>array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Fk warehouse', 'enabled'=>1, 'visible'=>-1, 'position'=>191), + 'fk_warehouse' =>array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Fk warehouse', 'enabled'=>'$conf->stock->enabled', 'visible'=>-1, 'position'=>191), 'fk_availability' =>array('type'=>'integer', 'label'=>'Availability', 'enabled'=>1, 'visible'=>-1, 'position'=>195), 'fk_delivery_address' =>array('type'=>'integer', 'label'=>'DeliveryAddress', 'enabled'=>1, 'visible'=>0, 'position'=>200), // deprecated 'fk_input_reason' =>array('type'=>'integer', 'label'=>'InputReason', 'enabled'=>1, 'visible'=>-1, 'position'=>205), @@ -485,7 +490,6 @@ class Propal extends CommonObject $line->subprice = -$remise->amount_ht; $line->fk_product = 0; // Id produit predefined $line->qty = 1; - $line->remise = 0; $line->remise_percent = 0; $line->rang = -1; $line->info_bits = 2; @@ -731,7 +735,6 @@ class Propal extends CommonObject // TODO deprecated $this->line->price = $price; - $this->line->remise = $remise; if (is_array($array_options) && count($array_options) > 0) { $this->line->array_options = $array_options; @@ -742,6 +745,11 @@ class Propal extends CommonObject // Reorder if child line if (!empty($fk_parent_line)) { $this->line_order(true, 'DESC'); + } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) { // Update all rank of all other lines + $linecount = count($this->lines); + for ($ii = $ranktouse; $ii <= $linecount; $ii++) { + $this->updateRangOfLine($this->lines[$ii - 1]->id, $ii + 1); + } } // Mise a jour informations denormalisees au niveau de la propale meme @@ -796,9 +804,10 @@ class Propal extends CommonObject * @param string $fk_unit Code of the unit to use. Null to use the default one * @param double $pu_ht_devise Unit price in currency * @param int $notrigger disable line update trigger + * @param integer $rang line rank * @return int 0 if OK, <0 if KO */ - public function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $desc = '', $price_base_type = 'HT', $info_bits = 0, $special_code = 0, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice = 0, $pa_ht = 0, $label = '', $type = 0, $date_start = '', $date_end = '', $array_options = 0, $fk_unit = null, $pu_ht_devise = 0, $notrigger = 0) + public function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $desc = '', $price_base_type = 'HT', $info_bits = 0, $special_code = 0, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice = 0, $pa_ht = 0, $label = '', $type = 0, $date_start = '', $date_end = '', $array_options = 0, $fk_unit = null, $pu_ht_devise = 0, $notrigger = 0, $rang = 0) { global $mysoc, $langs; @@ -884,6 +893,7 @@ class Propal extends CommonObject $line->oldline = $staticline; $this->line = $line; $this->line->context = $this->context; + $this->line->rang = $rang; // Reorder if fk_parent_line change if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) { @@ -924,7 +934,6 @@ class Propal extends CommonObject // TODO deprecated $this->line->price = $price; - $this->line->remise = $remise; if (is_array($array_options) && count($array_options) > 0) { // We replace values in this->line->array_options only for entries defined into $array_options @@ -1092,6 +1101,7 @@ class Propal extends CommonObject $sql .= ", model_pdf"; $sql .= ", fin_validite"; $sql .= ", fk_cond_reglement"; + $sql .= ", deposit_percent"; $sql .= ", fk_mode_reglement"; $sql .= ", fk_account"; $sql .= ", ref_client"; @@ -1125,6 +1135,7 @@ class Propal extends CommonObject $sql .= ", '".$this->db->escape($this->model_pdf)."'"; $sql .= ", ".($this->fin_validite != '' ? "'".$this->db->idate($this->fin_validite)."'" : "NULL"); $sql .= ", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) : 'NULL'); + $sql .= ", ".(! empty($this->deposit_percent) ? "'".$this->db->escape($this->deposit_percent)."'" : 'NULL'); $sql .= ", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) : 'NULL'); $sql .= ", ".($this->fk_account > 0 ? ((int) $this->fk_account) : 'NULL'); $sql .= ", '".$this->db->escape($this->ref_client)."'"; @@ -1254,7 +1265,7 @@ class Propal extends CommonObject break; } // Defined the new fk_parent_line - if ($result > 0 && $line->product_type == 9) { + if ($result > 0) { $fk_parent_line = $result; } } @@ -1324,11 +1335,12 @@ class Propal extends CommonObject * @param User $user User making the clone * @param int $socid Id of thirdparty * @param int $forceentity Entity id to force + * @param bool $update_prices [=false] Update prices if true * @return int New id of clone */ - public function createFromClone(User $user, $socid = 0, $forceentity = null) + public function createFromClone(User $user, $socid = 0, $forceentity = null, $update_prices = false) { - global $conf, $hookmanager; + global $conf, $hookmanager, $mysoc; dol_include_once('/projet/class/project.class.php'); @@ -1351,6 +1363,7 @@ class Propal extends CommonObject if ($objsoc->fetch($socid) > 0) { $object->socid = $objsoc->id; $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0); + $object->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent : null); $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0); $object->fk_delivery_address = ''; @@ -1375,6 +1388,55 @@ class Propal extends CommonObject $objsoc->fetch($object->socid); } + // update prices + if ($update_prices === true) { + if ($objsoc->id > 0 && !empty($object->lines)) { + if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { + // If price per customer + require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; + } + + foreach ($object->lines as $line) { + if ($line->fk_product > 0) { + $prod = new Product($this->db); + $res = $prod->fetch($line->fk_product); + if ($res > 0) { + $pu_ht = $prod->price; + $tva_tx = get_default_tva($mysoc, $objsoc, $prod->id); + $remise_percent = $objsoc->remise_percent; + + if (!empty($conf->global->PRODUIT_MULTIPRICES) && $objsoc->price_level > 0) { + $pu_ht = $prod->multiprices[$objsoc->price_level]; + if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) { // using this option is a bug. kept for backward compatibility + if (isset($prod->multiprices_tva_tx[$objsoc->price_level])) { + $tva_tx = $prod->multiprices_tva_tx[$objsoc->price_level]; + } + } + } elseif (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) { + $prodcustprice = new Productcustomerprice($this->db); + $filter = array('t.fk_product' => $prod->id, 't.fk_soc' => $objsoc->id); + $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); + if ($result) { + // If there is some prices specific to the customer + if (count($prodcustprice->lines) > 0) { + $pu_ht = price($prodcustprice->lines[0]->price); + $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx.' ('.$prodcustprice->lines[0]->default_vat_code.' )' : $prodcustprice->lines[0]->tva_tx); + if ($prodcustprice->lines[0]->default_vat_code && !preg_match('/\(.*\)/', $tva_tx)) { + $tva_tx .= ' ('.$prodcustprice->lines[0]->default_vat_code.')'; + } + } + } + } + + $line->subprice = $pu_ht; + $line->tva_tx = $tva_tx; + $line->remise_percent = $remise_percent; + } + } + } + } + } + $object->id = 0; $object->ref = ''; $object->entity = (!empty($forceentity) ? $forceentity : $object->entity); @@ -1479,7 +1541,7 @@ class Propal extends CommonObject $sql .= ", c.label as statut_label"; $sql .= ", ca.code as availability_code, ca.label as availability"; $sql .= ", dr.code as demand_reason_code, dr.label as demand_reason"; - $sql .= ", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc"; + $sql .= ", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc, p.deposit_percent"; $sql .= ", cp.code as mode_reglement_code, cp.libelle as mode_reglement"; $sql .= " FROM ".MAIN_DB_PREFIX."propal as p"; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_propalst as c ON p.fk_statut = c.id'; @@ -1563,6 +1625,7 @@ class Propal extends CommonObject $this->cond_reglement_code = $obj->cond_reglement_code; $this->cond_reglement = $obj->cond_reglement; $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc; + $this->deposit_percent = $obj->deposit_percent; $this->extraparams = (array) json_decode($obj->extraparams, true); @@ -1672,6 +1735,7 @@ class Propal extends CommonObject $sql .= " fk_user_valid=".(isset($this->user_valid) ? $this->user_valid : "null").","; $sql .= " fk_projet=".(isset($this->fk_project) ? $this->fk_project : "null").","; $sql .= " fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id : "null").","; + $sql .= " deposit_percent=".(! empty($this->deposit_percent) ? "'".$this->db->escape($this->deposit_percent)."'" : "null").","; $sql .= " fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id : "null").","; $sql .= " fk_input_reason=".(isset($this->demand_reason_id) ? $this->demand_reason_id : "null").","; $sql .= " note_private=".(isset($this->note_private) ? "'".$this->db->escape($this->note_private)."'" : "null").","; @@ -1724,15 +1788,17 @@ class Propal extends CommonObject /** * Load array lines * - * @param int $only_product Return only physical products - * @param int $loadalsotranslation Return translation for products + * @param int $only_product Return only physical products + * @param int $loadalsotranslation Return translation for products + * @param string $filters Filter on other fields * - * @return int <0 if KO, >0 if OK + * @return int <0 if KO, >0 if OK */ - public function fetch_lines($only_product = 0, $loadalsotranslation = 0) + public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $filters = '') { - global $langs, $conf; // phpcs:enable + global $langs, $conf; + $this->lines = array(); $sql = 'SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,'; @@ -1748,6 +1814,9 @@ class Propal extends CommonObject if ($only_product) { $sql .= ' AND p.fk_product_type = 0'; } + if ($filters) { + $sql .= $filters; + } $sql .= ' ORDER by d.rang'; dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG); @@ -1830,14 +1899,15 @@ class Propal extends CommonObject // multilangs if (!empty($conf->global->MAIN_MULTILANGS) && !empty($objp->fk_product) && !empty($loadalsotranslation)) { - $line = new Product($this->db); - $line->fetch($objp->fk_product); - $line->getMultiLangs(); + $tmpproduct = new Product($this->db); + $tmpproduct->fetch($objp->fk_product); + $tmpproduct->getMultiLangs(); + + $line->multilangs = $tmpproduct->multilangs; } $this->lines[$i] = $line; - //dol_syslog("1 ".$line->fk_product); - //print "xx $i ".$this->lines[$i]->fk_product; + $i++; } @@ -3573,7 +3643,7 @@ class Propal extends CommonObject */ public function getNomUrl($withpicto = 0, $option = '', $get_params = '', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1) { - global $langs, $conf, $user; + global $langs, $conf, $user, $hookmanager; if (!empty($conf->dol_no_mouse_hover)) { $notooltip = 1; // Force disable tooltips @@ -3694,17 +3764,27 @@ class Propal extends CommonObject } } + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } /** * Retrieve an array of proposal lines + * @param string $filters Filter on other fields * * @return int >0 if OK, <0 if KO */ - public function getLinesArray() + public function getLinesArray($filters = '') { - return $this->fetch_lines(); + return $this->fetch_lines(0, 0, $filters); } /** @@ -3756,8 +3836,24 @@ class Propal extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } -} + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'propaldet' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } +} /** * Class to manage commercial proposal lines @@ -3897,6 +3993,7 @@ class PropaleLigne extends CommonObjectLine public $multicurrency_total_tva; public $multicurrency_total_ttc; + /** * Class line Contructor * @@ -4036,9 +4133,6 @@ class PropaleLigne extends CommonObjectLine if (empty($this->rang)) { $this->rang = 0; } - if (empty($this->remise)) { - $this->remise = 0; - } if (empty($this->remise_percent) || !is_numeric($this->remise_percent)) { $this->remise_percent = 0; } @@ -4268,9 +4362,6 @@ class PropaleLigne extends CommonObjectLine if (empty($this->price)) { $this->price = 0; // TODO A virer } - if (empty($this->remise)) { - $this->remise = 0; // TODO A virer - } if (empty($this->remise_percent)) { $this->remise_percent = 0; } @@ -4361,7 +4452,7 @@ class PropaleLigne extends CommonObjectLine if (!$error && !$notrigger) { // Call trigger - $result = $this->call_trigger('LINEPROPAL_UPDATE', $user); + $result = $this->call_trigger('LINEPROPAL_MODIFY', $user); if ($result < 0) { $this->db->rollback(); return -1; diff --git a/htdocs/comm/propal/contact.php b/htdocs/comm/propal/contact.php index fedf6a6233d..989dcfe7098 100644 --- a/htdocs/comm/propal/contact.php +++ b/htdocs/comm/propal/contact.php @@ -107,12 +107,6 @@ if ($action == 'addcontact' && $user->rights->propale->creer) { dol_print_error($db); } } -/* -elseif ($action == 'setaddress' && $user->rights->propale->creer) -{ - $result=$object->setDeliveryAddress($_POST['fk_address']); - if ($result < 0) dol_print_error($db,$object->error); -}*/ /* diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index e0eb8a23e3e..103ef815e48 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -42,6 +42,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formpropal.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +if (!empty($conf->margin->enabled)) { + require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmargin.class.php'; +} require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; @@ -120,6 +123,15 @@ $search_fk_input_reason = GETPOST("search_fk_input_reason", 'int'); $search_fk_mode_reglement = GETPOST("search_fk_mode_reglement", 'int'); $search_btn = GETPOST('button_search', 'alpha'); $search_remove_btn = GETPOST('button_removefilter', 'alpha'); +$search_date_signature_startday = GETPOST('search_date_signature_startday', 'int'); +$search_date_signature_startmonth = GETPOST('search_date_signature_startmonth', 'int'); +$search_date_signature_startyear = GETPOST('search_date_signature_startyear', 'int'); +$search_date_signature_endday = GETPOST('search_date_signature_endday', 'int'); +$search_date_signature_endmonth = GETPOST('search_date_signature_endmonth', 'int'); +$search_date_signature_endyear = GETPOST('search_date_signature_endyear', 'int'); +$search_date_signature_start = dol_mktime(0, 0, 0, $search_date_signature_startmonth, $search_date_signature_startday, $search_date_signature_startyear); +$search_date_signature_end = dol_mktime(23, 59, 59, $search_date_signature_endmonth, $search_date_signature_endday, $search_date_signature_endyear); + $search_status = GETPOST('search_status', 'alpha'); $optioncss = GETPOST('optioncss', 'alpha'); @@ -204,6 +216,7 @@ $arrayfields = array( 'p.date'=>array('label'=>"DatePropal", 'checked'=>1), 'p.fin_validite'=>array('label'=>"DateEnd", 'checked'=>1), 'p.date_livraison'=>array('label'=>"DeliveryDate", 'checked'=>0), + 'p.date_signature'=>array('label'=>"DateSigning", 'checked'=>0), 'ava.rowid'=>array('label'=>"AvailabilityPeriod", 'checked'=>0), 'p.fk_shipping_method'=>array('label'=>"SendingMethod", 'checked'=>0, 'enabled'=>!empty($conf->expedition->enabled)), 'p.fk_input_reason'=>array('label'=>"Origin", 'checked'=>0, 'enabled'=>1), @@ -223,6 +236,10 @@ $arrayfields = array( 'p.multicurrency_total_invoiced'=>array('label'=>'MulticurrencyAmountInvoicedTTC', 'checked'=>0, 'enabled'=>!empty($conf->multicurrency->enabled) && !empty($conf->global->PROPOSAL_SHOW_INVOICED_AMOUNT)), 'u.login'=>array('label'=>"Author", 'checked'=>1, 'position'=>10), 'sale_representative'=>array('label'=>"SaleRepresentativesOfThirdParty", 'checked'=>-1), + 'total_pa' => array('label' => (getDolGlobalString('MARGIN_TYPE') == '1' ? 'BuyingPrice' : 'CostPrice'), 'checked' => 0, 'position' => 300, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous ? 0 : 1)), + 'total_margin' => array('label' => 'Margin', 'checked' => 0, 'position' => 301, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous ? 0 : 1)), + 'total_margin_rate' => array('label' => 'MarginRate', 'checked' => 0, 'position' => 302, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous || empty($conf->global->DISPLAY_MARGIN_RATES) ? 0 : 1)), + 'total_mark_rate' => array('label' => 'MarkRate', 'checked' => 0, 'position' => 303, 'enabled' => (empty($conf->margin->enabled) || !$user->rights->margins->liretous || empty($conf->global->DISPLAY_MARK_RATES) ? 0 : 1)), 'p.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500), 'p.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500), 'p.date_cloture'=>array('label'=>"DateClosing", 'checked'=>0, 'position'=>500), @@ -323,13 +340,21 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_availability = ''; $search_status = ''; $object_statut = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); $search_categ_cus = 0; $search_fk_cond_reglement = ''; $search_fk_shipping_method = ''; $search_fk_input_reason = ''; $search_fk_mode_reglement = ''; + $search_date_signature_startday = ''; + $search_date_signature_startmonth = ''; + $search_date_signature_startyear = ''; + $search_date_signature_endday = ''; + $search_date_signature_endmonth = ''; + $search_date_signature_endyear = ''; + $search_date_signature_start = ''; + $search_date_signature_end = ''; } if ($object_statut != '') { $search_status = $object_statut; @@ -352,14 +377,14 @@ if ($action == 'validate' && $permissiontovalidate) { if ($tmpproposal->fetch($checked) > 0) { if ($tmpproposal->statut == $tmpproposal::STATUS_DRAFT) { if ($tmpproposal->valid($user) > 0) { - setEventMessage($langs->trans('hasBeenValidated', $tmpproposal->ref), 'mesgs'); + setEventMessages($langs->trans('hasBeenValidated', $tmpproposal->ref), null, 'mesgs'); } else { - setEventMessage($langs->trans('CantBeValidated'), 'errors'); + setEventMessages($tmpproposal->error, $tmpproposal->errors, 'errors'); $error++; } } else { $langs->load("errors"); - setEventMessage($langs->trans('ErrorIsNotADraft', $tmpproposal->ref), 'errors'); + setEventMessages($langs->trans('ErrorIsNotADraft', $tmpproposal->ref), null, 'errors'); $error++; } } else { @@ -385,13 +410,13 @@ if ($action == "sign" && $permissiontoclose) { if ($tmpproposal->statut == $tmpproposal::STATUS_VALIDATED) { $tmpproposal->statut = $tmpproposal::STATUS_SIGNED; if ($tmpproposal->closeProposal($user, $tmpproposal::STATUS_SIGNED) >= 0) { - setEventMessage($tmpproposal->ref." ".$langs->trans('Signed'), 'mesgs'); + setEventMessages($tmpproposal->ref." ".$langs->trans('Signed'), null, 'mesgs'); } else { setEventMessages($tmpproposal->error, $tmpproposal->errors, 'errors'); $error++; } } else { - setEventMessage($tmpproposal->ref." ".$langs->trans('CantBeSign'), 'errors'); + setEventMessage($langs->trans('MustBeValidatedToBeSigned', $tmpproposal->ref), 'errors'); $error++; } } else { @@ -487,6 +512,10 @@ $form = new Form($db); $formother = new FormOther($db); $formfile = new FormFile($db); $formpropal = new FormPropal($db); +$formmargin = null; +if (!empty($conf->margin->enabled)) { + $formmargin = new FormMargin($db); +} $companystatic = new Societe($db); $projectstatic = new Project($db); $formcompany = new FormCompany($db); @@ -506,8 +535,9 @@ $sql .= " state.code_departement as state_code, state.nom as state_name,"; $sql .= ' p.rowid, p.entity as propal_entity, p.note_private, p.total_ht, p.total_tva, p.total_ttc, p.localtax1, p.localtax2, p.ref, p.ref_client, p.fk_statut as status, p.fk_user_author, p.datep as dp, p.fin_validite as dfv,p.date_livraison as ddelivery,'; $sql .= ' p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc,'; $sql .= ' p.datec as date_creation, p.tms as date_update, p.date_cloture as date_cloture,'; +$sql .= ' p.date_signature as dsignature,'; $sql .= ' p.note_public, p.note_private,'; -$sql .= ' p.fk_cond_reglement,p.fk_mode_reglement,p.fk_shipping_method,p.fk_input_reason,'; +$sql .= ' p.fk_cond_reglement,p.deposit_percent,p.fk_mode_reglement,p.fk_shipping_method,p.fk_input_reason,'; $sql .= " pr.rowid as project_id, pr.ref as project_ref, pr.title as project_label,"; $sql .= ' u.login, u.lastname, u.firstname, u.email as user_email, u.statut as user_statut, u.entity as user_entity, u.photo, u.office_phone, u.office_fax, u.user_mobile, u.job, u.gender'; if (empty($user->rights->societe->client->voir) && !$socid) { @@ -690,6 +720,12 @@ if ($search_sale > 0) { if ($search_user > 0) { $sql .= " AND c.fk_c_type_contact = tc.rowid AND tc.element='propal' AND tc.source='internal' AND c.element_id = p.rowid AND c.fk_socpeople = ".((int) $search_user); } +if ($search_date_signature_start) { + $sql .= " AND p.date_signature >= '".$db->idate($search_date_signature_start)."'"; +} +if ($search_date_signature_end) { + $sql .= " AND p.date_signature <= '".$db->idate($search_date_signature_end)."'"; +} // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; @@ -729,12 +765,12 @@ if ($resql) { if ($socid > 0) { $soc = new Societe($db); $soc->fetch($socid); - $title = $langs->trans('ListOfProposals').' - '.$soc->name; + $title = $langs->trans('Proposals').' - '.$soc->name; if (empty($search_societe)) { $search_societe = $soc->name; } } else { - $title = $langs->trans('ListOfProposals'); + $title = $langs->trans('Proposals'); } $num = $db->num_rows($resql); @@ -906,6 +942,24 @@ if ($resql) { if ($search_country) { $param .= '&search_country='.urlencode($search_country); } + if ($search_date_signature_startday) { + $param .= '&search_date_signature_startday='.urlencode($search_date_signature_startday); + } + if ($search_date_signature_startmonth) { + $param .= '&search_date_signature_startmonth='.urlencode($search_date_signature_startmonth); + } + if ($search_date_signature_startyear) { + $param .= '&search_date_signature_startyear='.urlencode($search_date_signature_startyear); + } + if ($search_date_signature_endday) { + $param .= '&search_date_signature_endday='.urlencode($search_date_signature_endday); + } + if ($search_date_signature_endmonth) { + $param .= '&search_date_signature_endmonth='.urlencode($search_date_signature_endmonth); + } + if ($search_date_signature_endyear) { + $param .= '&search_date_signature_endyear='.urlencode($search_date_signature_endyear); + } // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; @@ -989,7 +1043,7 @@ if ($resql) { $moreforfilter = ''; // If the user can view prospects other than his' - if ($user->rights->societe->client->voir || $socid) { + if ($user->rights->user->user->lire) { $langs->load("commercial"); $moreforfilter .= '
    '; $tmptitle = $langs->trans('ThirdPartiesOfSaleRepresentative'); @@ -997,9 +1051,9 @@ if ($resql) { $moreforfilter .= '
    '; } // If the user can view prospects other than his' - if ($user->rights->societe->client->voir || $socid) { + if ($user->rights->user->user->lire) { $moreforfilter .= '
    '; - $tmptitle = $langs->trans('LinkedToSpecificUsers'); + $tmptitle = $langs->trans('LinkedToSpecificUsers'); $moreforfilter .= img_picto($tmptitle, 'user', 'class="pictofixedwidth"').$form->select_dolusers($search_user, 'search_user', $tmptitle, '', 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth250 widthcentpercentminusx'); $moreforfilter .= '
    '; } @@ -1137,6 +1191,17 @@ if ($resql) { print ''; print ''; } + // Date Signature + if (!empty($arrayfields['p.date_signature']['checked'])) { + print '
    '; + } // Availability if (!empty($arrayfields['ava.rowid']['checked'])) { print ''; } // Payment mode @@ -1245,6 +1310,22 @@ if ($resql) { if (!empty($arrayfields['sale_representative']['checked'])) { print ''; } + if (!empty($arrayfields['total_pa']['checked'])) { + print ''; + } + if (!empty($arrayfields['total_margin']['checked'])) { + print ''; + } + if (!empty($arrayfields['total_margin_rate']['checked'])) { + print ''; + } + if (!empty($arrayfields['total_mark_rate']['checked'])) { + print ''; + } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; @@ -1334,7 +1415,10 @@ if ($resql) { print_liste_field_titre($arrayfields['p.fin_validite']['label'], $_SERVER["PHP_SELF"], 'dfv', '', $param, 'align="center"', $sortfield, $sortorder); } if (!empty($arrayfields['p.date_livraison']['checked'])) { - print_liste_field_titre($arrayfields['p.date_livraison']['label'], $_SERVER["PHP_SELF"], 'ddelivery', '', $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre($arrayfields['p.date_livraison']['label'], $_SERVER["PHP_SELF"], 'p.date_livraison', '', $param, 'align="center"', $sortfield, $sortorder); + } + if (!empty($arrayfields['p.date_signature']['checked'])) { + print_liste_field_titre($arrayfields['p.date_signature']['label'], $_SERVER["PHP_SELF"], 'p.date_signature', '', $param, 'align="center"', $sortfield, $sortorder); } if (!empty($arrayfields['ava.rowid']['checked'])) { print_liste_field_titre($arrayfields['ava.rowid']['label'], $_SERVER["PHP_SELF"], 'availability', '', $param, '', $sortfield, $sortorder); @@ -1393,6 +1477,18 @@ if ($resql) { if (!empty($arrayfields['sale_representative']['checked'])) { print_liste_field_titre($arrayfields['sale_representative']['label'], $_SERVER["PHP_SELF"], "", "", "$param", '', $sortfield, $sortorder); } + if (!empty($arrayfields['total_pa']['checked'])) { + print_liste_field_titre($arrayfields['total_pa']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } + if (!empty($arrayfields['total_margin']['checked'])) { + print_liste_field_titre($arrayfields['total_margin']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } + if (!empty($arrayfields['total_margin_rate']['checked'])) { + print_liste_field_titre($arrayfields['total_margin_rate']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } + if (!empty($arrayfields['total_mark_rate']['checked'])) { + print_liste_field_titre($arrayfields['total_mark_rate']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } $totalarray = array( 'nbfield' => 0, 'val' => array( @@ -1438,7 +1534,21 @@ if ($resql) { $i = 0; $typenArray = null; - while ($i < min($num, $limit)) { + $with_margin_info = false; + if (!empty($conf->margin->enabled) && ( + !empty($arrayfields['total_pa']['checked']) + || !empty($arrayfields['total_margin']['checked']) + || !empty($arrayfields['total_margin_rate']['checked']) + || !empty($arrayfields['total_mark_rate']['checked']) + ) + ) { + $with_margin_info = true; + } + $total_ht = 0; + $total_margin = 0; + + $last_num = min($num, $limit); + while ($i < $last_num) { $obj = $db->fetch_object($resql); $objectstatic->id = $obj->rowid; @@ -1488,6 +1598,14 @@ if ($resql) { } } + $marginInfo = array(); + if ($with_margin_info === true) { + $objectstatic->fetch_lines(); + $marginInfo = $formmargin->getMarginInfosArray($objectstatic); + $total_ht += $obj->total_ht; + $total_margin += $marginInfo['total_margin']; + } + print ''; if (!empty($arrayfields['p.ref']['checked'])) { @@ -1659,6 +1777,18 @@ if ($resql) { $totalarray['nbfield']++; } } + // Date Signature + if (!empty($arrayfields['p.date_signature']['checked'])) { + if ($obj->dsignature) { + print ''; + } else { + print ''; + } + if (!$i) { + $totalarray['nbfield']++; + } + } // Availability if (!empty($arrayfields['ava.rowid']['checked'])) { print ''; if (!$i) { $totalarray['nbfield']++; @@ -1888,6 +2018,49 @@ if ($resql) { } } + // Total buying or cost price + if (!empty($arrayfields['total_pa']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Total margin + if (!empty($arrayfields['total_margin']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 'total_margin'; + } + $totalarray['val']['total_margin'] = $total_margin; + } + // Total margin rate + if (!empty($arrayfields['total_margin_rate']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Total mark rate + if (!empty($arrayfields['total_mark_rate']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + if (!$i) { + $totalarray['pos'][$totalarray['nbfield']] = 'total_mark_rate'; + } + if ($i >= $last_num - 1) { + if (!empty($total_ht)) { + $totalarray['val']['total_mark_rate'] = price2num($total_margin * 100 / $total_ht, 'MT'); + } else { + $totalarray['val']['total_mark_rate'] = ''; + } + } + } + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook @@ -1924,7 +2097,7 @@ if ($resql) { // Note public if (!empty($arrayfields['p.note_public']['checked'])) { print ''; if (!$i) { $totalarray['nbfield']++; @@ -1933,7 +2106,7 @@ if ($resql) { // Note private if (!empty($arrayfields['p.note_private']['checked'])) { print ''; if (!$i) { $totalarray['nbfield']++; @@ -1960,7 +2133,7 @@ if ($resql) { $totalarray['nbfield']++; } - print "\n"; + print ''."\n"; $i++; } @@ -1968,6 +2141,17 @@ if ($resql) { // Show total line include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; + // If no record found + if ($num == 0) { + $colspan = 1; + foreach ($arrayfields as $key => $val) { + if (!empty($val['checked'])) { + $colspan++; + } + } + print ''; + } + $db->free($resql); $parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql); diff --git a/htdocs/comm/propal/stats/index.php b/htdocs/comm/propal/stats/index.php index 0a182e6dcbe..576285594b4 100644 --- a/htdocs/comm/propal/stats/index.php +++ b/htdocs/comm/propal/stats/index.php @@ -335,11 +335,11 @@ foreach ($data as $val) { print ''; print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; $oldyear = $year; } diff --git a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php index adc9de9339e..613f06a6feb 100644 --- a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php +++ b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php @@ -30,7 +30,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/comm/prospect/index.php b/htdocs/comm/prospect/index.php index 1e1caa796b5..0bcf2662a44 100644 --- a/htdocs/comm/prospect/index.php +++ b/htdocs/comm/prospect/index.php @@ -77,7 +77,7 @@ if (!empty($conf->propal->enabled)) { * */ -$sql = "SELECT count(*) as cc, st.libelle, st.picto, st.id"; +$sql = "SELECT count(*) as cc, st.libelle as stcomm, st.picto, st.id"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."c_stcomm as st "; if (empty($user->rights->societe->client->voir) && !$socid) { diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 9322100f732..f36b4bb0b9e 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -160,7 +160,7 @@ if ($action == 'setremise' && ($user->rights->societe->creer || $user->rights->f $amount_ht = price2num(GETPOST('amount_ht', 'alpha')); $desc = GETPOST('desc', 'alpha'); $tva_tx = GETPOST('tva_tx', 'alpha'); - $discount_type = !empty($_POST['discount_type']) ?GETPOST('discount_type', 'alpha') : 0; + $discount_type = GETPOSTISSET('discount_type') ? GETPOST('discount_type', 'alpha') : 0; if ($amount_ht > 0) { $error = 0; @@ -284,11 +284,11 @@ if ($socid > 0) { } print ''; - print ''; + print ''; if (!empty($user->fk_soc)) { // No need to show this for external users print ''; - print ''; + print ''; } } @@ -314,11 +314,11 @@ if ($socid > 0) { } print ''; - print ''; + print ''; if (!empty($user->fk_soc)) { // No need to show this for external users print ''; - print ''; + print ''; } } @@ -353,7 +353,7 @@ if ($socid > 0) { print ''; } print ''; - print ''; print ''; print ''; - print ''; + print ''; if (preg_match('/\(CREDIT_NOTE\)/', $obj->description)) { print ''; } - print ''; - print ''; + print ''; + print ''; if (!empty($conf->multicurrency->enabled)) { - print ''; + print ''; } print ''; - print ''; + print ''; if (!empty($conf->multicurrency->enabled)) { - print ''; + print ''; } print ''; - print ''; + print ''; if (preg_match('/\(CREDIT_NOTE\)/', $obj->description)) { print ''; } - print ''; - print ''; + print ''; + print ''; if (!empty($conf->multicurrency->enabled)) { - print ''; + print ''; } print ''; - print ''; + print ''; if (!empty($conf->multicurrency->enabled)) { - print ''; + print ''; } print ''; - // Terms of the settlement + // Terms of payment print ''; // Payment mode @@ -1759,10 +1824,10 @@ if ($action == 'create' && $usercancreate) { // Template to use by default print ''; print '"; @@ -1771,7 +1836,7 @@ if ($action == 'create' && $usercancreate) { print ''; print ''; print ''; } @@ -1864,11 +1929,13 @@ if ($action == 'create' && $usercancreate) { $title = $langs->trans('ProductsAndServices'); print load_fiche_titre($title); + print '
    '; print '
    '; print $langs->trans('Source'); print ''; + print '
    '; + print $form->selectDate($search_date_signature_start ? $search_date_signature_start : -1, 'search_date_signature_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
    '; + print '
    '; + print $form->selectDate($search_date_signature_end ? $search_date_signature_end : -1, 'search_date_signature_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
    '; + print '
    '; @@ -1159,7 +1224,7 @@ if ($resql) { // Payment term if (!empty($arrayfields['p.fk_cond_reglement']['checked'])) { print ''; - $form->select_conditions_paiements($search_fk_cond_reglement, 'search_fk_cond_reglement', -1, 1, 1); + $form->select_conditions_paiements($search_fk_cond_reglement, 'search_fk_cond_reglement', 1, 1, 1); print ''; + print ''; + print ''; + print ''; + print '
    '.dol_print_date($db->jdate($obj->dsignature), 'day'); + print ' '; @@ -1691,7 +1821,7 @@ if ($resql) { // Payment terms if (!empty($arrayfields['p.fk_cond_reglement']['checked'])) { print ''; - $form->form_conditions_reglement($_SERVER['PHP_SELF'], $obj->fk_cond_reglement, 'none'); + $form->form_conditions_reglement($_SERVER['PHP_SELF'], $obj->fk_cond_reglement, 'none', 0, '', 1, $obj->deposit_percent); print ''.price($marginInfo['pa_total']).''.price($marginInfo['total_margin']).''.(($marginInfo['total_margin_rate'] == '') ? '' : price($marginInfo['total_margin_rate'], null, null, null, null, 2).'%').''.(($marginInfo['total_mark_rate'] == '') ? '' : price($marginInfo['total_mark_rate'], null, null, null, null, 2).'%').''; - print dol_escape_htmltag($obj->note_public); + print dol_string_nohtmltag($obj->note_public); print ''; - print dol_escape_htmltag($obj->note_private); + print dol_string_nohtmltag($obj->note_private); print '
    '.$langs->trans("NoRecordFound").'
    0 ? '&userid='.$userid : '').'">'.$year.''.$val['nb'].''.round($val['nb_diff']).'%'.(isset($val['nb_diff']) ? round($val['nb_diff']): "0").'%'.price(price2num($val['total'], 'MT'), 1).''.round($val['total_diff']).'%'.(isset($val['total_diff']) ? round($val['total_diff']) : "0").'%'.price(price2num($val['avg'], 'MT'), 1).''.round($val['avg_diff']).'%'.(isset($val['avg_diff']) ? round($val['avg_diff']) : "0").'%
    '.$langs->trans("CustomerAbsoluteDiscountAllUsers").''.$remise_all.' '.$langs->trans("Currency".$conf->currency).' '.$langs->trans("HT").'
    '.price($remise_all, 1, $langs, 1, -1, -1, $conf->currency).' '.$langs->trans("HT").'
    '.$langs->trans("CustomerAbsoluteDiscountMy").''.$remise_user.' '.$langs->trans("Currency".$conf->currency).' '.$langs->trans("HT").'
    '.price($remise_user, 1, $langs, 1, -1, -1, $conf->currency).' '.$langs->trans("HT").'
    '.$langs->trans("SupplierAbsoluteDiscountAllUsers").''.$remise_all.' '.$langs->trans("Currency".$conf->currency).' '.$langs->trans("HT").'
    '.price($remise_all, 1, $langs, 1, -1, -1, $conf->currency).' '.$langs->trans("HT").'
    '.$langs->trans("SupplierAbsoluteDiscountMy").''.$remise_user.' '.$langs->trans("Currency".$conf->currency).' '.$langs->trans("HT").'
    '.price($remise_user, 1, $langs, 1, -1, -1, $conf->currency).' '.$langs->trans("HT").'
    '.$langs->trans("AmountHT").''; + print ''; print ' '.$langs->trans("Currency".$conf->currency).'
    '.$langs->trans("VAT").''; @@ -382,7 +382,7 @@ if ($socid > 0) { print '
    '; - if ($_GET['action'] == 'remove') { + if ($action == 'remove') { print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&remid='.GETPOST('remid'), $langs->trans('RemoveDiscount'), $langs->trans('ConfirmRemoveDiscount'), 'confirm_remove', '', 0, 1); } @@ -445,7 +445,7 @@ if ($socid > 0) { $obj = $db->fetch_object($resql); print '
    '.dol_print_date($db->jdate($obj->dc), 'dayhour').''.dol_print_date($db->jdate($obj->dc), 'dayhour', 'tzuserrel').''; $facturestatic->id = $obj->fk_facture_source; @@ -472,15 +472,15 @@ if ($socid > 0) { print $obj->description; print ''.$langs->trans("NotConsumed").''.price($obj->amount_ht).''.$langs->trans("NotConsumed").''.price($obj->amount_ht).''.price($obj->multicurrency_amount_ht).''.price($obj->multicurrency_amount_ht).''.vatrate($obj->tva_tx.($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : ''), true).''.price($obj->amount_ttc).''.price($obj->amount_ttc).''.price($obj->multicurrency_amount_ttc).''.price($obj->multicurrency_amount_ttc).''; print ''.img_object($langs->trans("ShowUser"), 'user').' '.$obj->login.''; @@ -583,7 +583,7 @@ if ($socid > 0) { $obj = $db->fetch_object($resql); print '
    '.dol_print_date($db->jdate($obj->dc), 'dayhour').''.dol_print_date($db->jdate($obj->dc), 'dayhour', 'tzuserrel').''; $facturefournstatic->id = $obj->fk_invoice_supplier_source; @@ -610,15 +610,15 @@ if ($socid > 0) { print $obj->description; print ''.$langs->trans("NotConsumed").''.price($obj->amount_ht).''.$langs->trans("NotConsumed").''.price($obj->amount_ht).''.price($obj->multicurrency_amount_ht).''.price($obj->multicurrency_amount_ht).''.vatrate($obj->tva_tx.($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : ''), true).''.price($obj->amount_ttc).''.price($obj->amount_ttc).''.price($obj->multicurrency_amount_ttc).''.price($obj->multicurrency_amount_ttc).''; print ''.img_object($langs->trans("ShowUser"), 'user').' '.$obj->login.''; @@ -766,7 +766,8 @@ if ($socid > 0) { $tab_sqlobjOrder[] = $db->jdate($sqlobj->dc); } $db->free($resql2); - array_multisort($tab_sqlobjOrder, SORT_DESC, $tab_sqlobj); + $array1_sort_order = SORT_DESC; + array_multisort($tab_sqlobjOrder, $array1_sort_order, $tab_sqlobj); $num = count($tab_sqlobj); if ($num > 0) { @@ -926,7 +927,8 @@ if ($socid > 0) { $tab_sqlobjOrder[] = $db->jdate($sqlobj->dc); } $db->free($resql2); - array_multisort($tab_sqlobjOrder, SORT_DESC, $tab_sqlobj); + $array1_sort_order = SORT_DESC; + array_multisort($tab_sqlobjOrder, $array1_sort_order, $tab_sqlobj); $num = count($tab_sqlobj); if ($num > 0) { diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 20bc5462d5e..c0aae93dff9 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -13,6 +13,7 @@ * Copyright (C) 2014 Ferran Marcet * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2018-2021 Frédéric France + * Copyright (C) 2022 Gauthier VERDOL * * 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 @@ -81,6 +82,7 @@ $contactid = GETPOST('contactid', 'int'); $projectid = GETPOST('projectid', 'int'); $origin = GETPOST('origin', 'alpha'); $originid = (GETPOST('originid', 'int') ? GETPOST('originid', 'int') : GETPOST('origin_id', 'int')); // For backward compatibility +$rank = (GETPOST('rank', 'int') > 0) ? GETPOST('rank', 'int') : -1; // PDF $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); @@ -270,6 +272,7 @@ if (empty($reshook)) { $object->ref_client = GETPOST('ref_client', 'alpha'); $object->model_pdf = GETPOST('model'); $object->cond_reglement_id = GETPOST('cond_reglement_id'); + $object->deposit_percent = GETPOST('cond_reglement_id_deposit_percent', 'alpha'); $object->mode_reglement_id = GETPOST('mode_reglement_id'); $object->fk_account = GETPOST('fk_account', 'int'); $object->availability_id = GETPOST('availability_id'); @@ -421,7 +424,7 @@ if (empty($reshook)) { } // Defined the new fk_parent_line - if ($result > 0 && $lines[$i]->product_type == 9) { + if ($result > 0) { $fk_parent_line = $result; } } @@ -533,7 +536,6 @@ if (empty($reshook)) { } } } elseif ($action == 'setdate' && $usercancreate) { - // print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; $date = dol_mktime(0, 0, 0, GETPOST('order_month', 'int'), GETPOST('order_day', 'int'), GETPOST('order_year', 'int')); $result = $object->set_date($user, $date); @@ -541,7 +543,6 @@ if (empty($reshook)) { setEventMessages($object->error, $object->errors, 'errors'); } } elseif ($action == 'setdate_livraison' && $usercancreate) { - // print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; $date_delivery = dol_mktime(GETPOST('liv_hour', 'int'), GETPOST('liv_min', 'int'), 0, GETPOST('liv_month', 'int'), GETPOST('liv_day', 'int'), GETPOST('liv_year', 'int')); $object->fetch($id); @@ -571,7 +572,7 @@ if (empty($reshook)) { setEventMessages($object->error, $object->errors, 'errors'); } } elseif ($action == 'setconditions' && $usercancreate) { - $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int')); + $result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'), GETPOST('cond_reglement_id_deposit_percent', 'alpha')); if ($result < 0) { dol_print_error($db, $object->error); } else { @@ -628,6 +629,13 @@ if (empty($reshook)) { foreach ($object->lines as $line) { $result = $object->updateline($line->id, $line->desc, $line->subprice, $line->qty, $line->remise_percent, $vat_rate, $localtax1_rate, $localtax2_rate, 'HT', $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); } + } elseif ($action == 'addline' && GETPOST('submitforalllines', 'alpha') && GETPOST('remiseforalllines', 'alpha') !== '' && $usercancreate) { + // Define remise_percent + $remise_percent = (GETPOST('remiseforalllines') ? GETPOST('remiseforalllines') : 0); + $remise_percent = str_replace('*', '', $remise_percent); + foreach ($object->lines as $line) { + $result = $object->updateline($line->id, $line->desc, $line->subprice, $line->qty, $remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->date_start, $line->date_end, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->fk_unit, $line->multicurrency_subprice); + } } elseif ($action == 'addline' && $usercancreate) { // Add a new line $langs->load('errors'); $error = 0; @@ -941,7 +949,7 @@ if (empty($reshook)) { setEventMessages($mesg, null, 'errors'); } else { // Insert line - $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, - 1, 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_options, $fk_unit, '', 0, $pu_ht_devise); + $result = $object->addline($desc, $pu_ht, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idprod, $remise_percent, $info_bits, 0, $price_base_type, $pu_ttc, $date_start, $date_end, $type, min($rank, count($object->lines) + 1), 0, GETPOST('fk_parent_line'), $fournprice, $buyingprice, $label, $array_options, $fk_unit, '', 0, $pu_ht_devise); if ($result > 0) { $ret = $object->fetch($object->id); // Reload to get new records @@ -1169,28 +1177,76 @@ if (empty($reshook)) { } if (!$error) { + $locationTarget = ''; + $db->begin(); $result = $object->valid($user, $idwarehouse); if ($result >= 0) { - // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { - $newlang = GETPOST('lang_id', 'aZ09'); - } - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) { - $newlang = $object->thirdparty->default_lang; - } - if (!empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $model = $object->model_pdf; - $ret = $object->fetch($id); // Reload to get new records + $error = 0; + $deposit = null; - $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + $deposit_percent_from_payment_terms = getDictionaryValue('c_payment_term', 'deposit_percent', $object->cond_reglement_id); + + if ( + GETPOST('generate_deposit', 'alpha') == 'on' && ! empty($deposit_percent_from_payment_terms) + && ! empty($conf->facture->enabled) && ! empty($user->rights->facture->creer) + ) { + require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; + + $date = dol_mktime(0, 0, 0, GETPOST('datefmonth', 'int'), GETPOST('datefday', 'int'), GETPOST('datefyear', 'int')); + $forceFields = array(); + + if (GETPOSTISSET('date_pointoftax')) { + $forceFields['date_pointoftax'] = dol_mktime(0, 0, 0, GETPOST('date_pointoftaxmonth', 'int'), GETPOST('date_pointoftaxday', 'int'), GETPOST('date_pointoftaxyear', 'int')); + } + + $deposit = Facture::createDepositFromOrigin($object, $date, GETPOST('cond_reglement_id', 'int'), $user, 0, GETPOST('validate_generated_deposit', 'alpha') == 'on', $forceFields); + + if ($deposit) { + setEventMessage('DepositGenerated'); + $locationTarget = DOL_URL_ROOT . '/compta/facture/card.php?id=' . $deposit->id; + } else { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } + } + + // Define output language + if (! $error) { + $db->commit(); + + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); + } + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) { + $newlang = $object->thirdparty->default_lang; + } + if (!empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model = $object->model_pdf; + $ret = $object->fetch($id); // Reload to get new records + + $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + + if ($deposit) { + $deposit->fetch($deposit->id); // Reload to get new records + $deposit->generateDocument($deposit->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + } + + if ($locationTarget) { + header('Location: ' . $locationTarget); + exit; + } + } else { + $db->rollback(); } } else { + $db->rollback(); setEventMessages($object->error, $object->errors, 'errors'); } } @@ -1453,6 +1509,10 @@ if ($action == 'create' && $usercancreate) { $currency_code = $conf->currency; + $cond_reglement_id = GETPOST('cond_reglement_id', 'int'); + $deposit_percent = GETPOST('cond_reglement_id_deposit_percent', 'alpha'); + $mode_reglement_id = GETPOST('mode_reglement_id', 'int'); + if (!empty($origin) && !empty($originid)) { // Parse element/subelement (ex: project_task) $element = $subelement = $origin; @@ -1468,6 +1528,9 @@ if ($action == 'create' && $usercancreate) { if (!$cond_reglement_id) { $cond_reglement_id = $soc->cond_reglement_id; } + if (!$deposit_percent) { + $deposit_percent = $soc->deposit_percent; + } if (!$mode_reglement_id) { $mode_reglement_id = $soc->mode_reglement_id; } @@ -1508,6 +1571,7 @@ if ($action == 'create' && $usercancreate) { $soc = $objectsrc->thirdparty; $cond_reglement_id = (!empty($objectsrc->cond_reglement_id) ? $objectsrc->cond_reglement_id : (!empty($soc->cond_reglement_id) ? $soc->cond_reglement_id : 0)); // TODO maybe add default value option + $deposit_percent = (!empty($objectsrc->deposit_percent) ? $objectsrc->deposit_percent : (!empty($soc->deposit_percent) ? $soc->deposit_percent : null)); $mode_reglement_id = (!empty($objectsrc->mode_reglement_id) ? $objectsrc->mode_reglement_id : (!empty($soc->mode_reglement_id) ? $soc->mode_reglement_id : 0)); $fk_account = (!empty($objectsrc->fk_account) ? $objectsrc->fk_account : (!empty($soc->fk_account) ? $soc->fk_account : 0)); $availability_id = (!empty($objectsrc->availability_id) ? $objectsrc->availability_id : 0); @@ -1540,6 +1604,7 @@ if ($action == 'create' && $usercancreate) { } } else { $cond_reglement_id = $soc->cond_reglement_id; + $deposit_percent = $soc->deposit_percent; $mode_reglement_id = $soc->mode_reglement_id; $fk_account = $soc->fk_account; $availability_id = 0; @@ -1668,10 +1733,10 @@ if ($action == 'create' && $usercancreate) { $form->selectAvailabilityDelay($availability_id, 'availability_id', '', 1, 'maxwidth200 widthcentpercentminusx'); print '
    '.$langs->trans('PaymentConditionsShort').''; print img_picto('', 'payment', 'class="pictofixedwidth"'); - $form->select_conditions_paiements($cond_reglement_id, 'cond_reglement_id', - 1, 1, 0, 'maxwidth200 widthcentpercentminusx'); + $form->select_conditions_paiements($cond_reglement_id, 'cond_reglement_id', 1, 1, 0, 'maxwidth200 widthcentpercentminusx', $deposit_percent); print '
    '.$langs->trans('DefaultModel').''; - print img_picto('', 'pdf', 'class="pictofixedwidth"'); include_once DOL_DOCUMENT_ROOT.'/core/modules/commande/modules_commande.php'; $liste = ModelePDFCommandes::liste_modeles($db); $preselected = $conf->global->COMMANDE_ADDON_PDF; + print img_picto('', 'pdf', 'class="pictofixedwidth"'); print $form->selectarray('model', $liste, $preselected, 0, 0, 0, '', 0, 0, 0, '', 'maxwidth200 widthcentpercentminusx', 1); print "
    '.$form->editfieldkey("Currency", 'multicurrency_code', '', $object, 0).''; - print $form->selectMultiCurrency($currency_code, 'multicurrency_code'); + print img_picto('', 'currency', 'class="pictofixedwidth"').$form->selectMultiCurrency($currency_code, 'multicurrency_code', 0, '', false, 'maxwidth200 widthcentpercentminusx'); print '
    '; $objectsrc->printOriginLinesList('', $selectedLines); print '
    '; + print ''; } print ''; @@ -1958,6 +2025,111 @@ if ($action == 'create' && $usercancreate) { if ($nbMandated > 0 ) $text .= '
    '.$langs->trans("mandatoryPeriodNeedTobeSetMsgValidate").'
    '; + $deposit_percent_from_payment_terms = getDictionaryValue('c_payment_term', 'deposit_percent', $object->cond_reglement_id); + + if (! empty($deposit_percent_from_payment_terms) && ! empty($conf->facture->enabled) && ! empty($user->rights->facture->creer)) { + require_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php'; + + $object->fetchObjectLinked(); + + $eligibleForDepositGeneration = true; + + if (array_key_exists('facture', $object->linkedObjects)) { + foreach ($object->linkedObjects['facture'] as $invoice) { + if ($invoice->type == Facture::TYPE_DEPOSIT) { + $eligibleForDepositGeneration = false; + break; + } + } + } + + if ($eligibleForDepositGeneration && array_key_exists('propal', $object->linkedObjects)) { + foreach ($object->linkedObjects['propal'] as $proposal) { + $proposal->fetchObjectLinked(); + + if (array_key_exists('facture', $proposal->linkedObjects)) { + foreach ($proposal->linkedObjects['facture'] as $invoice) { + if ($invoice->type == Facture::TYPE_DEPOSIT) { + $eligibleForDepositGeneration = false; + break 2; + } + } + } + } + } + + + if ($eligibleForDepositGeneration) { + $formquestion[] = array( + 'type' => 'checkbox', + 'tdclass' => '', + 'name' => 'generate_deposit', + 'label' => $form->textwithpicto($langs->trans('GenerateDeposit', $object->deposit_percent), $langs->trans('DepositGenerationPermittedByThePaymentTermsSelected')) + ); + + $formquestion[] = array( + 'type' => 'date', + 'tdclass' => 'fieldrequired showonlyifgeneratedeposit', + 'name' => 'datef', + 'label' => $langs->trans('DateInvoice'), + 'value' => dol_now(), + 'datenow' => true + ); + + if (! empty($conf->global->INVOICE_POINTOFTAX_DATE)) { + $formquestion[] = array( + 'type' => 'date', + 'tdclass' => 'fieldrequired showonlyifgeneratedeposit', + 'name' => 'date_pointoftax', + 'label' => $langs->trans('DatePointOfTax'), + 'value' => dol_now(), + 'datenow' => true + ); + } + + ob_start(); + $form->select_conditions_paiements(0, 'cond_reglement_id', -1, 0, 0, 'minwidth200'); + $paymentTermsSelect = ob_get_clean(); + + $formquestion[] = array( + 'type' => 'other', + 'tdclass' => 'fieldrequired showonlyifgeneratedeposit', + 'name' => 'cond_reglement_id', + 'label' => $langs->trans('PaymentTerm'), + 'value' => $paymentTermsSelect + ); + + $formquestion[] = array( + 'type' => 'checkbox', + 'tdclass' => 'showonlyifgeneratedeposit', + 'name' => 'validate_generated_deposit', + 'label' => $langs->trans('ValidateGeneratedDeposit') + ); + + $formquestion[] = array( + 'type' => 'onecolumn', + 'value' => ' + + ' + ); + } + } + if (!$error) { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateOrder'), $text, 'confirm_validate', $formquestion, 0, 1, 220); } @@ -2041,7 +2213,7 @@ if ($action == 'create' && $usercancreate) { if ($action == 'clone') { // Create an array for form $formquestion = array( - array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client = 2 OR s.client=3)')) + array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client = 2 OR s.client=3)', '', 0, 0, null, 0, 'maxwidth300')) ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneOrder', $object->ref), 'confirm_clone', $formquestion, 'yes', 1); } @@ -2261,9 +2433,9 @@ if ($action == 'create' && $usercancreate) { print $form->editfieldkey("PaymentConditionsShort", 'conditions', '', $object, $editenable); print '
    '; if ($action == 'editconditions') { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id', 1); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id', 1, '', 1, $object->deposit_percent); } else { - $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'none', 1); + $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'none', 1, '', 1, $object->deposit_percent); } print ''; - $form->select_conditions_paiements($search_fk_cond_reglement, 'search_fk_cond_reglement', -1, 1, 1); + $form->select_conditions_paiements($search_fk_cond_reglement, 'search_fk_cond_reglement', 1, 1, 1); print ''; + print ''; + print ''; + print ''; + print ''; + print ''; @@ -1354,6 +1733,18 @@ if ($resql) { if (!empty($arrayfields['sale_representative']['checked'])) { print_liste_field_titre($arrayfields['sale_representative']['label'], $_SERVER["PHP_SELF"], "", "", "$param", '', $sortfield, $sortorder); } + if (!empty($arrayfields['total_pa']['checked'])) { + print_liste_field_titre($arrayfields['total_pa']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } + if (!empty($arrayfields['total_margin']['checked'])) { + print_liste_field_titre($arrayfields['total_margin']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } + if (!empty($arrayfields['total_margin_rate']['checked'])) { + print_liste_field_titre($arrayfields['total_margin_rate']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } + if (!empty($arrayfields['total_mark_rate']['checked'])) { + print_liste_field_titre($arrayfields['total_mark_rate']['label'], $_SERVER['PHP_SELF'], '', '', $param, 'class="right"', $sortfield, $sortorder); + } $totalarray = array( 'nbfield' => 0, @@ -1397,6 +1788,9 @@ if ($resql) { if (!empty($arrayfields['c.facture']['checked'])) { print_liste_field_titre($arrayfields['c.facture']['label'], $_SERVER["PHP_SELF"], 'c.facture', '', $param, '', $sortfield, $sortorder, 'center '); } + if (!empty($arrayfields['c.import_key']['checked'])) { + print_liste_field_titre($arrayfields['c.import_key']['label'], $_SERVER["PHP_SELF"], "c.import_key", "", $param, '', $sortfield, $sortorder, 'center '); + } if (!empty($arrayfields['c.fk_statut']['checked'])) { print_liste_field_titre($arrayfields['c.fk_statut']['label'], $_SERVER["PHP_SELF"], "c.fk_statut", "", $param, '', $sortfield, $sortorder, 'center '); } @@ -1413,7 +1807,22 @@ if ($resql) { $generic_product = new Product($db); $userstatic = new User($db); $i = 0; - while ($i < min($num, $limit)) { + + $with_margin_info = false; + if (!empty($conf->margin->enabled) && ( + !empty($arrayfields['total_pa']['checked']) + || !empty($arrayfields['total_margin']['checked']) + || !empty($arrayfields['total_margin_rate']['checked']) + || !empty($arrayfields['total_mark_rate']['checked']) + ) + ) { + $with_margin_info = true; + } + $total_ht = 0; + $total_margin = 0; + + $last_num = min($num, $limit); + while ($i < $last_num) { $obj = $db->fetch_object($resql); $notshippable = 0; @@ -1455,6 +1864,14 @@ if ($resql) { $projectstatic->ref = $obj->project_ref; $projectstatic->title = $obj->project_label; + $marginInfo = array(); + if ($with_margin_info === true) { + $generic_commande->fetch_lines(); + $marginInfo = $formmargin->getMarginInfosArray($generic_commande); + $total_ht += $obj->total_ht; + $total_margin += $marginInfo['total_margin']; + } + print '
    '; print $generic_commande->getNomUrl(1, ($search_status != 2 ? 0 : $obj->fk_statut), 0, 0, 0, 1, 1); - // Warning late icon and note - if ($generic_commande->hasDelay()) { - print img_picto($langs->trans("Late").' : '.$generic_commande->showDelay(), "warning"); - } - $filename = dol_sanitizeFileName($obj->ref); $filedir = $conf->commande->multidir_output[$conf->entity].'/'.dol_sanitizeFileName($obj->ref); $urlsource = $_SERVER['PHP_SELF'].'?id='.$obj->rowid; @@ -1590,6 +2002,10 @@ if ($resql) { if (!empty($arrayfields['c.date_commande']['checked'])) { print ''; print dol_print_date($db->jdate($obj->date_commande), 'day'); + // Warning late icon and note + if ($generic_commande->hasDelay()) { + print img_picto($langs->trans("Late").' : '.$generic_commande->showDelay(), "warning"); + } print ''; - $form->form_conditions_reglement($_SERVER['PHP_SELF'], $obj->fk_cond_reglement, 'none'); + $form->form_conditions_reglement($_SERVER['PHP_SELF'], $obj->fk_cond_reglement, 'none', 0, '', 1, $obj->deposit_percent); print ''.price($marginInfo['pa_total']).''.price($marginInfo['total_margin']).''.(($marginInfo['total_margin_rate'] == '') ? '' : price($marginInfo['total_margin_rate'], null, null, null, null, 2).'%').''.(($marginInfo['total_mark_rate'] == '') ? '' : price($marginInfo['total_mark_rate'], null, null, null, null, 2).'%').''; - print dol_escape_htmltag($obj->note_public); + print ''; + print dol_string_nohtmltag($obj->note_public); print ''; - print dol_escape_htmltag($obj->note_private); + print ''; + print dol_string_nohtmltag($obj->note_private); print ''.$obj->import_key.''.$generic_commande->LibStatut($obj->fk_statut, $obj->billed, 5, 1).'
    0 ? '&userid='.$userid : '').'">'.$year.''.$val['nb'].''.round($val['nb_diff']).'%'.(isset($val['nb_diff']) ? round($val['nb_diff']): "0").'%'.price(price2num($val['total'], 'MT'), 1).''.round($val['total_diff']).'%'.(isset($val['total_diff']) ? round($val['total_diff']) : "0").'%'.price(price2num($val['avg'], 'MT'), 1).''.round($val['avg_diff']).'%'.(isset($val['avg_diff']) ? round($val['avg_diff']) : "0").'%
    '; $form->select_comptes($search_account, 'search_account', 0, '', 1, ($id > 0 || !empty($ref) ? ' disabled="disabled"' : ''), 0, 'maxwidth100'); print ''; print ''; print ''; print ''; print ''; $htmltext = $langs->trans("BalanceVisibilityDependsOnSortAndFilters", $langs->transnoentitiesnoconv("DateValue")); print $form->textwithpicto('', $htmltext, 1); print ''; $htmltext = $langs->trans("BalanceVisibilityDependsOnSortAndFilters", $langs->transnoentitiesnoconv("DateValue")); @@ -1105,6 +1130,11 @@ if ($resql) { print $form->selectyesno('search_conciliated', $search_conciliated, 1, false, 1, 1); print ''; $searchpicto = $form->showFilterAndCheckAddButtons($massactionbutton ? 1 : 0, 'checkforselect', 1); @@ -1156,6 +1186,10 @@ if ($resql) { if (!empty($arrayfields['b.conciliated']['checked'])) { print_liste_field_titre($arrayfields['b.conciliated']['label'], $_SERVER['PHP_SELF'], 'b.rappro', '', $param, '', $sortfield, $sortorder, "center "); } + if (!empty($arrayfields['b.fk_bordereau']['checked'])) { + print_liste_field_titre($arrayfields['b.fk_bordereau']['label'], $_SERVER['PHP_SELF'], 'b.fk_bordereau', '', $param, '', $sortfield, $sortorder, "center "); + } + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields @@ -1342,14 +1376,15 @@ if ($resql) { $labeltoshow = $langs->trans($reg[1]); } else { if ($objp->label == '(payment_salary)') { - $labeltoshow = dol_trunc($langs->trans("SalaryPayment", 40)); + $labeltoshow = $langs->trans("SalaryPayment"); } else { $labeltoshow = dol_escape_htmltag($objp->label); $titletoshow = $objp->label; } } - print ''; - print $labeltoshow; // Already escaped + + + print ''; // Add info about links after description $cachebankaccount = array(); @@ -1358,70 +1393,70 @@ if ($resql) { if ($links[$key]['type'] == 'withdraw') { $banktransferstatic->id = $links[$key]['url_id']; $banktransferstatic->ref = $links[$key]['label']; - print ' '.$banktransferstatic->getNomUrl(0); + print $banktransferstatic->getNomUrl(0).' '; } elseif ($links[$key]['type'] == 'payment') { $paymentstatic->id = $links[$key]['url_id']; $paymentstatic->ref = $links[$key]['url_id']; // FIXME This is id, not ref of payment $paymentstatic->date = $db->jdate($objp->do); - print ' '.$paymentstatic->getNomUrl(2); + print $paymentstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'payment_supplier') { $paymentsupplierstatic->id = $links[$key]['url_id']; $paymentsupplierstatic->ref = $links[$key]['url_id']; // FIXME This is id, not ref of payment - print ' '.$paymentsupplierstatic->getNomUrl(2); + print $paymentsupplierstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'payment_sc') { $paymentscstatic->id = $links[$key]['url_id']; $paymentscstatic->ref = $links[$key]['url_id']; $paymentscstatic->label = $links[$key]['label']; - print ' '.$paymentscstatic->getNomUrl(2); + print $paymentscstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'payment_vat') { $paymentvatstatic->id = $links[$key]['url_id']; $paymentvatstatic->ref = $links[$key]['url_id']; - print ' '.$paymentvatstatic->getNomUrl(2); + print $paymentvatstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'payment_salary') { $paymentsalstatic->id = $links[$key]['url_id']; $paymentsalstatic->ref = $links[$key]['url_id']; $paymentsalstatic->label = $links[$key]['label']; - print ' '.$paymentsalstatic->getNomUrl(2); + print $paymentsalstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'payment_loan') { print ''; print ' '.img_object($langs->trans('ShowPayment'), 'payment').' '; - print ''; + print ' '; } elseif ($links[$key]['type'] == 'payment_donation') { $paymentdonationstatic->id = $links[$key]['url_id']; $paymentdonationstatic->ref = $links[$key]['url_id']; - print ' '.$paymentdonationstatic->getNomUrl(2); + print $paymentdonationstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'payment_expensereport') { $paymentexpensereportstatic->id = $links[$key]['url_id']; $paymentexpensereportstatic->ref = $links[$key]['url_id']; - print ' '.$paymentexpensereportstatic->getNomUrl(2); + print $paymentexpensereportstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'payment_various') { $paymentvariousstatic->id = $links[$key]['url_id']; $paymentvariousstatic->ref = $links[$key]['url_id']; - print ' '.$paymentvariousstatic->getNomUrl(2); + print $paymentvariousstatic->getNomUrl(2).' '; } elseif ($links[$key]['type'] == 'banktransfert') { // Do not show link to transfer since there is no transfer card (avoid confusion). Can already be accessed from transaction detail. if ($objp->amount > 0) { $banklinestatic->fetch($links[$key]['url_id']); $bankstatic->id = $banklinestatic->fk_account; $bankstatic->label = $banklinestatic->bank_account_ref; - print ' ('.$langs->trans("TransferFrom").' '; + print $langs->trans("TransferFrom").' '; print $bankstatic->getNomUrl(1, 'transactions'); print ' '.$langs->trans("toward").' '; $bankstatic->id = $objp->bankid; $bankstatic->label = $objp->bankref; print $bankstatic->getNomUrl(1, ''); - print ')'; + print ' - '; } else { $bankstatic->id = $objp->bankid; $bankstatic->label = $objp->bankref; - print ' ('.$langs->trans("TransferFrom").' '; + print $langs->trans("TransferFrom").' '; print $bankstatic->getNomUrl(1, ''); print ' '.$langs->trans("toward").' '; $banklinestatic->fetch($links[$key]['url_id']); $bankstatic->id = $banklinestatic->fk_account; $bankstatic->label = $banklinestatic->bank_account_ref; print $bankstatic->getNomUrl(1, 'transactions'); - print ')'; + print ' - '; } //var_dump($links); } elseif ($links[$key]['type'] == 'company') { @@ -1433,22 +1468,22 @@ if ($resql) { // Information is already shown using the payment_salary link. No need of this link. } else { // Show link with label $links[$key]['label'] - if (!empty($objp->label) && !empty($links[$key]['label'])) { - print ' - '; - } print ''; if (preg_match('/^\((.*)\)$/i', $links[$key]['label'], $reg)) { // Label generique car entre parentheses. On l'affiche en le traduisant if ($reg[1] == 'paiement') { $reg[1] = 'Payment'; } - print ' '.$langs->trans($reg[1]); + print $langs->trans($reg[1]); } else { - print ' '.$links[$key]['label']; + print $links[$key]['label']; } - print ''; + print ''.($labeltoshow ? ' - ' : ''); } } + + print $labeltoshow; // Already escaped + print ''; + print ''; $labeltype = ($langs->trans("PaymentTypeShort".$objp->fk_type) != "PaymentTypeShort".$objp->fk_type) ? $langs->trans("PaymentTypeShort".$objp->fk_type) : $langs->getLabelFromKey($db, $objp->fk_type, 'c_paiement', 'code', 'libelle', '', 1); if ($labeltype == 'SOLD') { print ' '; //$langs->trans("InitialBankBalance"); @@ -1517,9 +1552,9 @@ if ($resql) { print ''; $companylinked_id = 0; - $userlinked_id = 0; + $userlinked_id = 0; - //payment line type to define user display and user or company linked + //payment line type to define user display and user or company linked foreach ($links as $key => $value) { if ($links[$key]['type'] == 'payment_sc') { $type_link = 'payment_sc'; @@ -1666,6 +1701,16 @@ if ($resql) { } } + if (!empty($arrayfields['b.fk_bordereau']['checked'])) { + $bordereaustatic->fetch($objp->fk_bordereau); + print ''; + print $bordereaustatic->getNomUrl(); + print ''; // Transaction reconciliated or edit link diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 5c91a9f504d..ce373bbf5b5 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -7,6 +7,7 @@ * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2016 Marcos García * Copyright (C) 2018 Frédéric France + * Copyright (C) 2022 Charlene Benke * * 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 @@ -125,6 +126,7 @@ if (empty($reshook)) { $object->bic = trim(GETPOST("bic")); $object->iban = trim(GETPOST("iban")); $object->domiciliation = trim(GETPOST("domiciliation", "nohtml")); + $object->pti_in_ctti = empty(GETPOST("pti_in_ctti")) ? 0 : 1; $object->proprio = trim(GETPOST("proprio", 'alphanohtml')); $object->owner_address = trim(GETPOST("owner_address", 'nohtml')); @@ -225,6 +227,7 @@ if (empty($reshook)) { $object->bic = trim(GETPOST("bic")); $object->iban = trim(GETPOST("iban")); $object->domiciliation = trim(GETPOST("domiciliation", "nohtml")); + $object->pti_in_ctti = empty(GETPOST("pti_in_ctti")) ? 0 : 1; $object->proprio = trim(GETPOST("proprio", 'alphanohtml')); $object->owner_address = trim(GETPOST("owner_address", 'nohtml')); @@ -284,7 +287,7 @@ if (empty($reshook)) { $categories = GETPOST('categories', 'array'); $object->setCategories($categories); - $_GET["id"] = $_POST["id"]; // Force chargement page en mode visu + $_GET["id"] = GETPOST("id", 'int'); // Force chargement page en mode visu } else { $error++; setEventMessages($object->error, $object->errors, 'errors'); @@ -434,7 +437,7 @@ if ($action == 'create') { print '
    '.$langs->trans("Categories").''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_ACCOUNT, '', 'parent', 64, 0, 1); @@ -538,6 +541,13 @@ if ($action == 'create') { print '
    '.$langs->trans($bickey).'
    '.$langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformation").' '; + print img_picto($langs->trans("SEPAXMLPlacePaymentTypeInformationInCreditTransfertransactionInformationHelp"), 'info'); + print '
    '.$langs->trans("BankAccountDomiciliation").''; print '
    '; @@ -716,11 +719,11 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie if (!empty($conf->use_javascript_ajax)) { print img_picto("Auto fill", 'rightarrow', "class='AutoFillAmout' data-rowname='".$namef."' data-value='".($sign * $multicurrency_remaintopay)."'"); } - print ''; + print ''; print ''; } else { - print ''; - print ''; + print ''; + print ''; } } print "
    '."\n"; // Date payment print ''; // Payment type (VIR, LIQ, ...) diff --git a/htdocs/compta/paiement/cheque/card.php b/htdocs/compta/paiement/cheque/card.php index c109acedf7e..8c859e6e689 100644 --- a/htdocs/compta/paiement/cheque/card.php +++ b/htdocs/compta/paiement/cheque/card.php @@ -83,8 +83,7 @@ $usercandelete = $user->rights->banque->cheque; if ($action == 'setdate' && $user->rights->banque->cheque) { $result = $object->fetch(GETPOST('id', 'int')); if ($result > 0) { - //print "x ".$_POST['liv_month'].", ".$_POST['liv_day'].", ".$_POST['liv_year']; - $date = dol_mktime(0, 0, 0, $_POST['datecreate_month'], $_POST['datecreate_day'], $_POST['datecreate_year']); + $date = dol_mktime(0, 0, 0, GETPOST('datecreate_month', 'int'), GETPOST('datecreate_day', 'int'), GETPOST('datecreate_year', 'int')); $result = $object->set_date($user, $date); if ($result < 0) { @@ -124,7 +123,7 @@ if ($action == 'setref' && $user->rights->banque->cheque) { } if ($action == 'create' && GETPOST("accountid", "int") > 0 && $user->rights->banque->cheque) { - if (is_array($_POST['toRemise'])) { + if (is_array(GETPOST('toRemise'))) { $result = $object->create($user, GETPOST("accountid", "int"), 0, GETPOST('toRemise')); if ($result > 0) { if ($object->statut == 1) { // If statut is validated, we build doc diff --git a/htdocs/compta/paiement/cheque/class/remisecheque.class.php b/htdocs/compta/paiement/cheque/class/remisecheque.class.php index 6b1053240c8..3fb82f05cb9 100644 --- a/htdocs/compta/paiement/cheque/class/remisecheque.class.php +++ b/htdocs/compta/paiement/cheque/class/remisecheque.class.php @@ -200,8 +200,9 @@ class RemiseCheque extends CommonObject } } + $lines = array(); + if ($this->id > 0 && $this->errno == 0) { - $lines = array(); $sql = "SELECT b.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."bank as b"; $sql .= " WHERE b.fk_type = 'CHQ'"; @@ -730,7 +731,7 @@ class RemiseCheque extends CommonObject $bankline = new AccountLine($db); $bankline->fetch($bank_id); - /* Conciliation is allowed because when check is returned, a new line is created onto bank transaction log. + /* Reconciliation is allowed because when check is returned, a new line is created onto bank transaction log. if ($bankline->rappro) { $this->error='ActionRefusedLineAlreadyConciliated'; @@ -739,7 +740,7 @@ class RemiseCheque extends CommonObject $this->db->begin(); - // Not conciliated, we can delete it + // Not reconciled, we can delete it //$bankline->delete($user); // We delete $bankaccount = $payment->fk_account; diff --git a/htdocs/compta/paiement/cheque/list.php b/htdocs/compta/paiement/cheque/list.php index d12caf36bbe..1c3abfe87bd 100644 --- a/htdocs/compta/paiement/cheque/list.php +++ b/htdocs/compta/paiement/cheque/list.php @@ -172,7 +172,7 @@ if ($resql) { print ''; } print ''; - $formother->select_year($year ? $year : -1, 'year', 1, 20, 5); + print $formother->selectyear($year ? $year : -1, 'year', 1, 20, 5); print ''; print ''; + print ''; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/compta/paiement/rapport.php b/htdocs/compta/paiement/rapport.php index cf02c2aeb74..326be7144a8 100644 --- a/htdocs/compta/paiement/rapport.php +++ b/htdocs/compta/paiement/rapport.php @@ -102,7 +102,7 @@ $syear = GETPOST("reyear") ?GETPOST("reyear") : date("Y", time()); print $formother->select_month($cmonth, 'remonth'); -print $formother->select_year($syear, 'reyear'); +print $formother->selectyear($syear, 'reyear'); print ''; print ''; diff --git a/htdocs/compta/paiement_charge.php b/htdocs/compta/paiement_charge.php index 6ed84de293c..db48b2767f2 100644 --- a/htdocs/compta/paiement_charge.php +++ b/htdocs/compta/paiement_charge.php @@ -83,7 +83,7 @@ if ($action == 'add_payment' || ($action == 'confirm_paiement' && $confirm == 'y foreach ($_POST as $key => $value) { if (substr($key, 0, 7) == 'amount_') { $other_chid = substr($key, 7); - $amounts[$other_chid] = price2num($_POST[$key]); + $amounts[$other_chid] = price2num(GETPOST($key)); } } @@ -198,7 +198,7 @@ if ($action == 'create') { if ($resql) { $obj = $db->fetch_object($resql); $sumpaid = $obj->total; - $db->free(); + $db->free($resql); } /*print ''; print '';*/ @@ -291,7 +291,7 @@ if ($action == 'create') { print "\n"; $total += $objp->total; $total_ttc += $objp->total_ttc; - $totalrecu += $objp->am; + $totalrecu += $objp->amount; $i++; } if ($i > 1) { diff --git a/htdocs/compta/paiement_vat.php b/htdocs/compta/paiement_vat.php index 28bc838c296..645fd36bc2a 100644 --- a/htdocs/compta/paiement_vat.php +++ b/htdocs/compta/paiement_vat.php @@ -194,7 +194,7 @@ if ($action == 'create') { if ($resql) { $obj = $db->fetch_object($resql); $sumpaid = $obj->total; - $db->free(); + $db->free($resql); } /*print ''; print '';*/ @@ -290,7 +290,7 @@ if ($action == 'create') { print "\n"; $total += $objp->total; $total_ttc += $objp->total_ttc; - $totalrecu += $objp->am; + $totalrecu += $objp->amount; $i++; } if ($i > 1) { diff --git a/htdocs/compta/prelevement/card.php b/htdocs/compta/prelevement/card.php index a076299b4cd..469985679c9 100644 --- a/htdocs/compta/prelevement/card.php +++ b/htdocs/compta/prelevement/card.php @@ -191,7 +191,7 @@ if ($id > 0 || $ref) { print ''; + print ' '.$langs->trans("By").' '.$muser->getNomUrl(-1).''; print ''; @@ -237,7 +237,9 @@ if ($id > 0 || $ref) { if ($object->type == 'bank-transfer') { $modulepart = 'paymentbybanktransfer'; } - print ''.$relativepath.''; + print ''.$relativepath; + print img_picto('', 'download', 'class="paddingleft"'); + print ''; print ''; // Other attributes @@ -309,20 +311,22 @@ if ($id > 0 || $ref) { // Actions if ($action != 'settransmitted' && $action != 'setcredited') { print "\n".'
    '."\n"; + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if (empty($object->date_trans)) { + if ($object->type == 'bank-transfer') print dolGetButtonAction($langs->trans("SetToStatusSent"), '', 'default', 'card.php?action=settransmitted&token='.newToken().'&id='.$object->id, '', $user->rights->paymentbybanktransfer->send); + else print dolGetButtonAction($langs->trans("SetToStatusSent"), '', 'default', 'card.php?action=settransmitted&token='.newToken().'&id='.$object->id, '', $user->rights->prelevement->bons->send); + } - if (empty($object->date_trans)) { - if ($object->type == 'bank-transfer') print dolGetButtonAction($langs->trans("SetToStatusSent"), '', 'default', 'card.php?action=settransmitted&token='.newToken().'&id='.$object->id, '', $user->rights->paymentbybanktransfer->send); - else print dolGetButtonAction($langs->trans("SetToStatusSent"), '', 'default', 'card.php?action=settransmitted&token='.newToken().'&id='.$object->id, '', $user->rights->prelevement->bons->send); + if (!empty($object->date_trans) && $object->date_credit == 0) { + if ($object->type == 'bank-transfer') print dolGetButtonAction($langs->trans("ClassDebited"), '', 'default', 'card.php?action=setcredited&token='.newToken().'&id='.$object->id, '', $user->rights->paymentbybanktransfer->debit); + else print dolGetButtonAction($langs->trans("ClassCredited"), '', 'default', 'card.php?action=setcredited&token='.newToken().'&id='.$object->id, '', $user->rights->prelevement->bons->credit); + } + + if ($object->type == 'bank-transfer') print dolGetButtonAction($langs->trans("Delete"), '', 'delete', 'card.php?action=delete&token='.newToken().'&id='.$object->id, '', $user->rights->paymentbybanktransfer->create); + else print dolGetButtonAction($langs->trans("Delete"), '', 'delete', 'card.php?action=delete&token='.newToken().'&id='.$object->id, '', $user->rights->prelevement->bons->creer); } - - if (!empty($object->date_trans) && $object->date_credit == 0) { - if ($object->type == 'bank-transfer') print dolGetButtonAction($langs->trans("ClassDebited"), '', 'default', 'card.php?action=setcredited&token='.newToken().'&id='.$object->id, '', $user->rights->paymentbybanktransfer->debit); - else print dolGetButtonAction($langs->trans("ClassCredited"), '', 'default', 'card.php?action=setcredited&token='.newToken().'&id='.$object->id, '', $user->rights->prelevement->bons->credit); - } - - if ($object->type == 'bank-transfer') print dolGetButtonAction($langs->trans("Delete"), '', 'delete', 'card.php?action=delete&token='.newToken().'&id='.$object->id, '', $user->rights->paymentbybanktransfer->create); - else print dolGetButtonAction($langs->trans("Delete"), '', 'delete', 'card.php?action=delete&token='.newToken().'&id='.$object->id, '', $user->rights->prelevement->bons->creer); - print '
    '; } diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index fcf13fe8c0e..d60002f479d 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -64,6 +64,7 @@ class BonPrelevement extends CommonObject public $emetteur_numero_compte; public $emetteur_code_banque; public $emetteur_number_key; + public $sepa_xml_pti_in_ctti; public $emetteur_iban; public $emetteur_bic; @@ -77,6 +78,8 @@ class BonPrelevement extends CommonObject public $statut; // 0-Wait, 1-Trans, 2-Done public $labelStatus = array(); + public $factures = array(); + public $invoice_in_error = array(); public $thirdparty_in_error = array(); @@ -107,6 +110,7 @@ class BonPrelevement extends CommonObject $this->emetteur_numero_compte = ""; $this->emetteur_code_banque = ""; $this->emetteur_number_key = ""; + $this->sepa_xml_pti_in_ctti = false; $this->emetteur_iban = ""; $this->emetteur_bic = ""; @@ -392,10 +396,10 @@ class BonPrelevement extends CommonObject $amounts[$fac->id] = $facs[$i][1]; $amountsperthirdparty[$fac->socid][$fac->id] = $facs[$i][1]; - $totalpaye = $fac->getSommePaiement(); + $totalpaid = $fac->getSommePaiement(); $totalcreditnotes = $fac->getSumCreditNotesUsed(); $totaldeposits = $fac->getSumDepositsUsed(); - $alreadypayed = $totalpaye + $totalcreditnotes + $totaldeposits; + $alreadypayed = $totalpaid + $totalcreditnotes + $totaldeposits; // @TODO Move this after creation of payment if (price2num($alreadypayed + $facs[$i][1], 'MT') == $fac->total_ttc) { @@ -911,6 +915,7 @@ class BonPrelevement extends CommonObject $this->db->begin(); $now = dol_now(); + $ref = ''; /* * Process order generation @@ -1044,10 +1049,11 @@ class BonPrelevement extends CommonObject } $account = new Account($this->db); if ($account->fetch($id) > 0) { - $this->emetteur_code_banque = $account->code_banque; + $this->emetteur_code_banque = $account->code_banque; $this->emetteur_code_guichet = $account->code_guichet; $this->emetteur_numero_compte = $account->number; - $this->emetteur_number_key = $account->cle_rib; + $this->emetteur_number_key = $account->cle_rib; + $this->sepa_xml_pti_in_ctti = (bool) $account->pti_in_ctti; $this->emetteur_iban = $account->iban; $this->emetteur_bic = $account->bic; @@ -1063,8 +1069,8 @@ class BonPrelevement extends CommonObject // This also set the property $this->total with amount that is included into file $result = $this->generate($format, $executiondate, $type); if ($result < 0) { - /*var_dump($this->error); - var_dump($this->invoice_in_error); */ + //var_dump($this->error); + //var_dump($this->invoice_in_error); $error++; } } @@ -1240,13 +1246,6 @@ class BonPrelevement extends CommonObject } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('myobjectdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } else { $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } @@ -1266,7 +1265,7 @@ class BonPrelevement extends CommonObject global $action, $hookmanager; $hookmanager->initHooks(array('banktransferdao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; @@ -1834,7 +1833,7 @@ class BonPrelevement extends CommonObject $DtOfSgntr = dol_print_date($row_datec, '%Y-%m-%d'); if ($type != 'bank-transfer') { - // SEPA Paiement Information of buyer for Direct debit + // SEPA Paiement Information of buyer for Direct Debit $XML_DEBITOR = ''; $XML_DEBITOR .= ' '.$CrLf; $XML_DEBITOR .= ' '.$CrLf; @@ -1887,6 +1886,24 @@ class BonPrelevement extends CommonObject // Add EndToEndId. Must be a unique ID for each payment (for example by including bank, buyer or seller, date, checksum) $XML_CREDITOR .= ' '.(($conf->global->PRELEVEMENT_END_TO_END != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('CT-'.dol_trunc($row_idfac.'-'.$row_ref, 20, 'right', 'UTF-8', 1)).'-'.$Rowing).''.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters $XML_CREDITOR .= ' '.$CrLf; + if (!empty($this->sepa_xml_pti_in_ctti)) { + $XML_CREDITOR .= ' ' . $CrLf; + + // Can be 'NORM' for normal or 'HIGH' for high priority level + if (!empty($conf->global->PAYMENTBYBANKTRANSFER_FORCE_HIGH_PRIORITY)) { + $instrprty = 'HIGH'; + } else { + $instrprty = 'NORM'; + } + $XML_CREDITOR .= ' '.$instrprty.'' . $CrLf; + $XML_CREDITOR .= ' ' . $CrLf; + $XML_CREDITOR .= ' SEPA' . $CrLf; + $XML_CREDITOR .= ' ' . $CrLf; + $XML_CREDITOR .= ' ' . $CrLf; + $XML_CREDITOR .= ' CORE' . $CrLf; + $XML_CREDITOR .= ' ' . $CrLf; + $XML_CREDITOR .= ' ' . $CrLf; + } $XML_CREDITOR .= ' '.$CrLf; $XML_CREDITOR .= ' '.round($row_somme, 2).''.$CrLf; $XML_CREDITOR .= ' '.$CrLf; @@ -2037,6 +2054,7 @@ class BonPrelevement extends CommonObject $this->emetteur_code_guichet = $account->code_guichet; $this->emetteur_numero_compte = $account->number; $this->emetteur_number_key = $account->cle_rib; + $this->sepa_xml_pti_in_ctti = (bool) $account->pti_in_ctti; $this->emetteur_iban = $account->iban; $this->emetteur_bic = $account->bic; @@ -2060,7 +2078,7 @@ class BonPrelevement extends CommonObject $RefBon = $obj->ref; if ($type != 'bank-transfer') { - // SEPA Paiement Information of my company for Direct debit + // SEPA Paiement Information of my company for Direct Debit $XML_SEPA_INFO = ''; $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.('DD/'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; @@ -2131,17 +2149,17 @@ class BonPrelevement extends CommonObject //$XML_SEPA_INFO .= ' False'.$CrLf; $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; $XML_SEPA_INFO .= ' '.$total.''.$CrLf; - /* - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' SEPA'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' TRF'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' SECU'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - */ + if (!empty($this->sepa_xml_pti_in_ctti) && !empty($format)) { // @TODO Using $format (FRST ou RCUR) in a section for a Credit Transfer looks strange. + $XML_SEPA_INFO .= ' ' . $CrLf; + $XML_SEPA_INFO .= ' ' . $CrLf; + $XML_SEPA_INFO .= ' SEPA' . $CrLf; + $XML_SEPA_INFO .= ' ' . $CrLf; + $XML_SEPA_INFO .= ' ' . $CrLf; + $XML_SEPA_INFO .= ' CORE' . $CrLf; + $XML_SEPA_INFO .= ' ' . $CrLf; + $XML_SEPA_INFO .= ' ' . $format . '' . $CrLf; + $XML_SEPA_INFO .= ' ' . $CrLf; + } $XML_SEPA_INFO .= ' '.dol_print_date($dateTime_ETAD, 'dayrfc').''.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale)))).''.$CrLf; diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php index 35c49df8d1e..0722450a610 100644 --- a/htdocs/compta/prelevement/factures.php +++ b/htdocs/compta/prelevement/factures.php @@ -102,7 +102,7 @@ if ($id > 0 || $ref) { //print ''; print ''; - print ''; + print ''; if ($object->date_trans <> 0) { $muser = new User($db); @@ -110,7 +110,7 @@ if ($id > 0 || $ref) { print ''; + print ' '.$langs->trans("By").' '.$muser->getNomUrl(-1).''; print ''; @@ -156,7 +156,9 @@ if ($id > 0 || $ref) { if ($object->type == 'bank-transfer') { $modulepart = 'paymentbybanktransfer'; } - print ''.$relativepath.''; + print ''.$relativepath; + print img_picto('', 'download', 'class="paddingleft"'); + print ''; print '
    '.$form->editfieldkey("Date", 'datep', $object->date, $object, $user->rights->facture->paiement).''; -print $form->editfieldval("Date", 'datep', $object->date, $object, $user->rights->facture->paiement, 'datehourpicker', '', null, $langs->trans('PaymentDateUpdateSucceeded')); +print $form->editfieldval("Date", 'datep', $object->date, $object, $user->rights->facture->paiement, 'datehourpicker', '', null, $langs->trans('PaymentDateUpdateSucceeded'), '', 0, '', 'id', 'tzuser'); print '
    '; $form->select_comptes($search_account, 'search_account', 0, '', 1); diff --git a/htdocs/compta/paiement/class/paiement.class.php b/htdocs/compta/paiement/class/paiement.class.php index edab2922efb..f63d58db933 100644 --- a/htdocs/compta/paiement/class/paiement.class.php +++ b/htdocs/compta/paiement/class/paiement.class.php @@ -79,8 +79,8 @@ class Paiement extends CommonObject public $pos_change = 0; // Excess received in TakePOS cash payment public $author; - public $paiementid; // Type of payment. Id saved into fields fk_paiement on llx_paiement - public $paiementcode; // Code of payment. + public $paiementid; // ID of mode of payment. Is saved into fields fk_paiement on llx_paiement = id of llx_c_paiement + public $paiementcode; // Code of mode of payment. /** * @var string Type of payment label @@ -109,6 +109,16 @@ class Paiement extends CommonObject */ public $ext_payment_id; + /** + * @var string Id of prelevement + */ + public $id_prelevement; + + /** + * @var string num_prelevement + */ + public $num_prelevement; + /** * @var string Name of external payment mode */ @@ -340,6 +350,7 @@ class Paiement extends CommonObject if (is_numeric($amount) && $amount <> 0) { $amount = price2num($amount); $sql = "INSERT INTO ".MAIN_DB_PREFIX."paiement_facture (fk_facture, fk_paiement, amount, multicurrency_amount)"; + // TODO Add multicurrency_code and multicurrency_tx $sql .= " VALUES (".((int) $facid).", ".((int) $this->id).", ".((float) $amount).", ".((float) $this->multicurrency_amounts[$key]).")"; dol_syslog(get_class($this).'::create Amount line '.$key.' insert paiement_facture', LOG_DEBUG); @@ -418,7 +429,8 @@ class Paiement extends CommonObject } if ($error) { - setEventMessages($discount->error, $discount->errors, 'errors'); + $this->error = $discount->error; + $this->errors = $discount->errors; $error++; } } @@ -459,7 +471,8 @@ class Paiement extends CommonObject $result = $invoice->generateDocument($invoice->model_pdf, $outputlangs, $hidedetails, $hidedesc, $hideref); if ($result < 0) { - setEventMessages($invoice->error, $invoice->errors, 'errors'); + $this->error = $invoice->error; + $this->errors = $invoice->errors; $error++; } } @@ -620,16 +633,19 @@ class Paiement extends CommonObject return -1; } - $this->db->begin(); - $this->fk_account = $accountid; + dol_syslog("addPaymentToBank ".$user->id.", ".$mode.", ".$label.", ".$this->fk_account.", ".$emetteur_nom.", ".$emetteur_banque); + include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; - - dol_syslog("$user->id, $mode, $label, $this->fk_account, $emetteur_nom, $emetteur_banque"); - $acc = new Account($this->db); $result = $acc->fetch($this->fk_account); + if ($result < 0) { + $error++; + return -1; + } + + $this->db->begin(); $totalamount = $this->amount; $totalamount_main_currency = null; @@ -1196,7 +1212,7 @@ class Paiement extends CommonObject */ public function getNomUrl($withpicto = 0, $option = '', $mode = 'withlistofinvoices', $notooltip = 0, $morecss = '') { - global $conf, $langs; + global $conf, $langs, $hookmanager; if (!empty($conf->dol_no_mouse_hover)) { $notooltip = 1; // Force disable tooltips @@ -1216,6 +1232,9 @@ class Paiement extends CommonObject $label .= dol_print_date($dateofpayment, 'dayhour', 'tzuser'); } } + if ($this->amount) { + $label .= '
    '.$langs->trans("Amount").': '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency); + } if ($mode == 'withlistofinvoices') { $arraybill = $this->getBillsArray(); if (is_array($arraybill) && count($arraybill) > 0) { @@ -1254,7 +1273,15 @@ class Paiement extends CommonObject $result .= ($this->ref ? $this->ref : $this->id); } $result .= $linkend; - + global $action; + $hookmanager->initHooks(array($this->element . 'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } return $result; } diff --git a/htdocs/compta/paiement/list.php b/htdocs/compta/paiement/list.php index 3732e76b880..3d0698118ff 100644 --- a/htdocs/compta/paiement/list.php +++ b/htdocs/compta/paiement/list.php @@ -148,7 +148,7 @@ if (empty($reshook)) { $search_company = ''; $search_status = ''; $option = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } } @@ -528,7 +528,7 @@ while ($i < min($num, $limit)) { // Date if (!empty($arrayfields['p.datep']['checked'])) { $dateformatforpayment = 'dayhour'; - print '
    '.dol_print_date($db->jdate($objp->datep), $dateformatforpayment).''.dol_print_date($db->jdate($objp->datep), $dateformatforpayment, 'tzuser').'
    '.$langs->trans("AlreadyPaid").''.price($sumpaid,0,$outputlangs,1,-1,-1,$conf->currency).'
    '.$langs->trans("RemainderToPay").''.price($total-$sumpaid,0,$outputlangs,1,-1,-1,$conf->currency).'
    '.$langs->trans("AlreadyPaid").''.price($sumpaid,0,$outputlangs,1,-1,-1,$conf->currency).'
    '.$langs->trans("RemainderToPay").''.price($total-$sumpaid,0,$outputlangs,1,-1,-1,$conf->currency).'
    '.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).'
    '.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print '
    '.$langs->trans("Ref").''.$object->getNomUrl(1).'
    '.$langs->trans("Date").''.dol_print_date($object->datec, 'day').'
    '.$langs->trans("Amount").''.price($object->amount).'
    '.$langs->trans("Amount").''.price($object->amount).'
    '.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).'
    '.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print '
    '; print ''; diff --git a/htdocs/compta/prelevement/fiche-rejet.php b/htdocs/compta/prelevement/fiche-rejet.php index 5622d97deda..93d621a0665 100644 --- a/htdocs/compta/prelevement/fiche-rejet.php +++ b/htdocs/compta/prelevement/fiche-rejet.php @@ -97,7 +97,7 @@ if ($id > 0 || $ref) { //print '
    '.$langs->trans("Ref").''.$object->getNomUrl(1).'
    '.$langs->trans("Date").''.dol_print_date($object->datec, 'day').'
    '.$langs->trans("Amount").''.price($object->amount).'
    '.$langs->trans("Amount").''.price($object->amount).'
    '.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).'
    '.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print '
    '; print ''; @@ -207,7 +209,7 @@ if ($resql) { print"\n\n"; print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table - print ''; + print '
    '; print ''; print ''; print ''; diff --git a/htdocs/compta/prelevement/fiche-stat.php b/htdocs/compta/prelevement/fiche-stat.php index df0ae6270ad..ca698854234 100644 --- a/htdocs/compta/prelevement/fiche-stat.php +++ b/htdocs/compta/prelevement/fiche-stat.php @@ -91,7 +91,7 @@ if ($id > 0 || $ref) { //print ''; print ''; - print ''; + print ''; if ($object->date_trans <> 0) { $muser = new User($db); @@ -99,7 +99,7 @@ if ($id > 0 || $ref) { print ''; + print ' '.$langs->trans("By").' '.$muser->getNomUrl(-1).''; print ''; @@ -145,7 +145,9 @@ if ($id > 0 || $ref) { if ($object->type == 'bank-transfer') { $modulepart = 'paymentbybanktransfer'; } - print ''.$relativepath.''; + print ''.$relativepath; + print img_picto('', 'download', 'class="paddingleft"'); + print ''; print '
    '.$langs->trans("Line").''.$langs->trans("ThirdParty").''.$langs->trans("Amount").''.$langs->trans("Reason").''.$langs->trans("ToBill").''.$langs->trans("Invoice").'
    '.$langs->trans("Ref").''.$object->getNomUrl(1).'
    '.$langs->trans("Date").''.dol_print_date($object->datec, 'day').'
    '.$langs->trans("Amount").''.price($object->amount).'
    '.$langs->trans("Amount").''.price($object->amount).'
    '.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).'
    '.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print '
    '; print '
    '; @@ -173,7 +175,8 @@ if ($id > 0 || $ref) { print load_fiche_titre($langs->trans("StatisticsByLineStatus"), '', ''); print"\n\n"; - print ''; + print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table + print '
    '; print ''; print ''; @@ -184,10 +187,13 @@ if ($id > 0 || $ref) { print $line->LibStatut($row[1], 1); - print ''; - print ''; + + print '
    '.$langs->trans("Status").''.$langs->trans("Amount").'%
    '; - print price($row[0]); + print ''; + print ''; + print price($row[0]); + print ''; if ($object->amount) { print round($row[0] / $object->amount * 100, 2)." %"; } @@ -200,6 +206,8 @@ if ($id > 0 || $ref) { } print "
    "; + print ""; + $db->free($resql); } else { print $db->error().' '.$sql; diff --git a/htdocs/compta/prelevement/stats.php b/htdocs/compta/prelevement/stats.php index 9c30db6e08a..8ee4c854600 100644 --- a/htdocs/compta/prelevement/stats.php +++ b/htdocs/compta/prelevement/stats.php @@ -143,7 +143,8 @@ if ($resql) { print price($total); print '
     
    "; - $db->free(); + + $db->free($resql); } else { dol_print_error($db); } diff --git a/htdocs/compta/recap-compta.php b/htdocs/compta/recap-compta.php index d98a6aab251..8b2bf351094 100644 --- a/htdocs/compta/recap-compta.php +++ b/htdocs/compta/recap-compta.php @@ -158,7 +158,7 @@ if ($id > 0) { print $fac->error."
    "; continue; } - $totalpaye = $fac->getSommePaiement(); + $totalpaid = $fac->getSommePaiement(); $userstatic->id = $objf->userid; $userstatic->login = $objf->login; @@ -168,7 +168,7 @@ if ($id > 0) { 'date' => $fac->date, 'datefieldforsort' => $fac->date.'-'.$fac->ref, 'link' => $fac->getNomUrl(1), - 'status' => $fac->getLibStatut(2, $totalpaye), + 'status' => $fac->getLibStatut(2, $totalpaid), 'amount' => $fac->total_ttc, 'author' => $userstatic->getLoginUrl(1) ); diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php index f43f4e6ddfa..900f1a179e9 100644 --- a/htdocs/compta/sociales/card.php +++ b/htdocs/compta/sociales/card.php @@ -62,6 +62,9 @@ $label = GETPOST('label', 'alpha'); $actioncode = GETPOST('actioncode'); $fk_user = GETPOST('userid', 'int'); +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('taxcard', 'globalcard')); + // Initialize technical objects $object = new ChargeSociales($db); $extrafields = new ExtraFields($db); @@ -97,7 +100,7 @@ $result = restrictedArea($user, 'tax', $object->id, 'chargesociales', 'charges') * Actions */ -$parameters = array(); +$parameters = array('socid' => $socid); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); @@ -163,8 +166,8 @@ if ($action == 'setbankaccount' && $user->rights->tax->charges->creer) { // Delete social contribution if ($action == 'confirm_delete' && $confirm == 'yes') { $object->fetch($id); - $totalpaye = $object->getSommePaiement(); - if (empty($totalpaye)) { + $totalpaid = $object->getSommePaiement(); + if (empty($totalpaid)) { $result = $object->delete($user); if ($result > 0) { header("Location: list.php"); @@ -446,10 +449,12 @@ if ($id > 0) { $object = new ChargeSociales($db); $result = $object->fetch($id); + $formconfirm = ''; + if ($result > 0) { $head = tax_prepare_head($object); - $totalpaye = $object->getSommePaiement(); + $totalpaid = $object->getSommePaiement(); // Clone confirmation if ($action === 'clone') { @@ -464,25 +469,36 @@ if ($id > 0) { $formquestion[] = array('type' => 'text', 'name' => 'amount', 'label' => $langs->trans("Amount"), 'value' => price($object->amount), 'morecss' => 'width100'); } - print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneTax', $object->ref), 'confirm_clone', $formquestion, 'yes', 1, 280); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneTax', $object->ref), 'confirm_clone', $formquestion, 'yes', 1, 280); } if ($action == 'paid') { $text = $langs->trans('ConfirmPaySocialContribution'); - print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans('PaySocialContribution'), $text, "confirm_paid", '', '', 2); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans('PaySocialContribution'), $text, "confirm_paid", '', '', 2); } // Confirmation of the removal of the Social Contribution if ($action == 'delete') { $text = $langs->trans('ConfirmDeleteSocialContribution'); - print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('DeleteSocialContribution'), $text, 'confirm_delete', '', '', 2); + $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('DeleteSocialContribution'), $text, 'confirm_delete', '', '', 2); } if ($action == 'edit') { print "
    id&action=update\" method=\"post\">"; print ''; } + // Call Hook formConfirm + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + $formconfirm .= $hookmanager->resPrint; + } elseif ($reshook > 0) { + $formconfirm = $hookmanager->resPrint; + } + + // Print form confirm + print $formconfirm; print dol_get_fiche_head($head, 'card', $langs->trans("SocialContribution"), -1, 'bill'); @@ -535,11 +551,11 @@ if ($id > 0) { $morehtmlref .= ''; $morehtmlref .= ''; $morehtmlref .= ''; - $morehtmlref .= $formproject->select_projects(0, $object->fk_project, 'fk_project', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); + $morehtmlref .= $formproject->select_projects(0, $object->fk_project, 'fk_project', 0, 0, 1, 0, 1, 0, 0, '', 1); $morehtmlref .= ''; $morehtmlref .= '
    '; } else { - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, 0, $object->fk_project, 'none', 0, 0, 0, 1); } } else { if (!empty($object->fk_project)) { @@ -560,7 +576,7 @@ if ($id > 0) { $linkback = ''.$langs->trans("BackToList").''; - $object->totalpaye = $totalpaye; // To give a chance to dol_banner_tab to use already paid amount to show correct status + $object->totalpaid = $totalpaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlright); @@ -674,7 +690,7 @@ if ($id > 0) { //print $sql; $resql = $db->query($sql); if ($resql) { - $totalpaye = 0; + $totalpaid = 0; $num = $db->num_rows($resql); $i = 0; @@ -732,7 +748,7 @@ if ($id > 0) { } print '
    '.price($objp->amount)."
    '.$langs->trans("AlreadyPaid").' :'.price($totalpaye)."
    '.$langs->trans("AlreadyPaid").' :'.price($totalpaid)."
    '.$langs->trans("AmountExpected").' :'.price($object->amount)."
    '.$langs->trans("RemainderToPay")." :
    '; + print ''."\n"; + $i++; } // Show total line include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; -print '
    '; +print '
    '; dol_print_object_info($object); print '
    '; diff --git a/htdocs/compta/sociales/list.php b/htdocs/compta/sociales/list.php index 8d63e52256e..082a485f817 100644 --- a/htdocs/compta/sociales/list.php +++ b/htdocs/compta/sociales/list.php @@ -713,16 +713,35 @@ while ($i < min($num, $limit)) { $totalarray['nbfield']++; } - print '
    '; -print '
    '; -print ''; +// If no record found +if ($num == 0) { + $colspan = 1; + foreach ($arrayfields as $key => $val) { + if (!empty($val['checked'])) { + $colspan++; + } + } + print ''.$langs->trans("NoRecordFound").''; +} + +$db->free($resql); + +$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql); +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; + +print ''."\n"; +print '
    '."\n"; + +print ''."\n"; // End of page llxFooter(); diff --git a/htdocs/compta/sociales/note.php b/htdocs/compta/sociales/note.php new file mode 100644 index 00000000000..0447d3168b1 --- /dev/null +++ b/htdocs/compta/sociales/note.php @@ -0,0 +1,137 @@ + + * + * 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 . + */ + +/** + * \file htdocs/compta/sociales/note.php + * \ingroup tax + * \brief Tab for notes on Taxes + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/sociales/class/chargesociales.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/tax.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +if (!empty($conf->projet->enabled)) { + include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +} + +// Load translation files required by the page +$langs->loadLangs(array('compta', 'bills')); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); + +$object = new ChargeSociales($db); +if ($id > 0) { + $object->fetch($id); +} + +// Security check +$socid = GETPOST('socid', 'int'); +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'tax', $object->id, 'chargesociales', 'charges'); + +$permissiontoread = $user->rights->tax->charges->lire; +$permissiontoadd = $user->rights->tax->charges->creer; +$permissionnote = $user->rights->tax->charges->creer; // Used by the include of actions_setnotes.inc.php + + +/* + * Actions + */ + +$parameters = array(); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} +if (empty($reshook)) { + include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not include_once +} + + +/* + * View + */ + +$form = new Form($db); + +$title = $langs->trans("SocialContribution").' - '.$langs->trans("Note"); +$help_url = 'EN:Module_Taxes_and_social_contributions|FR:Module Taxes et dividendes|ES:Módulo Impuestos y cargas sociales (IVA, impuestos)'; +llxHeader('', $title, $help_url); + +if ($id > 0 || !empty($ref)) { + $object->fetch_thirdparty(); + + $head = tax_prepare_head($object); + + print dol_get_fiche_head($head, 'note', $langs->trans("SocialContribution"), -1, $object->picto); + + $morehtmlref = '
    '; + // Label of social contribution + $morehtmlref .= $form->editfieldkey("Label", 'lib', $object->label, $object, $user->rights->tax->charges->creer, 'string', '', 0, 1); + $morehtmlref .= $form->editfieldval("Label", 'lib', $object->label, $object, $user->rights->tax->charges->creer, 'string', '', null, null, '', 1); + // Project + if (!empty($conf->projet->enabled)) { + $langs->load("projects"); + $morehtmlref .= '
    '.$langs->trans('Project').' : '; + if (!empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.dol_escape_htmltag($proj->title); + } + } else { + $morehtmlref .= ''; + } + } + $morehtmlref .= '
    '; + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + //$object->totalpaid = $totalpaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status + + $morehtmlright = ''; + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlright); + + + print '
    '; + print '
    '; + + + $cssclass = "titlefield"; + include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; + + print '
    '; + + print dol_get_fiche_end(); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/compta/sociales/payments.php b/htdocs/compta/sociales/payments.php index 77230bac407..d2646d241ea 100644 --- a/htdocs/compta/sociales/payments.php +++ b/htdocs/compta/sociales/payments.php @@ -80,7 +80,7 @@ $result = restrictedArea($user, 'tax', '', 'chargesociales', 'charges'); // 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 $search_sc_type = ''; - //$toselect = ''; + //$toselect = array(); //$search_array_options = array(); } @@ -137,7 +137,7 @@ print ''; $sql = "SELECT c.id, c.libelle as type_label,"; $sql .= " cs.rowid, cs.libelle as label_sc, cs.fk_type as type, cs.periode, cs.date_ech, cs.amount as total, cs.paye,"; -$sql .= " pc.rowid as pid, pc.datep, pc.amount as totalpaye, pc.num_paiement as num_payment, pc.fk_bank,"; +$sql .= " pc.rowid as pid, pc.datep, pc.amount as totalpaid, pc.num_paiement as num_payment, pc.fk_bank,"; $sql .= " pct.code as payment_code,"; $sql .= " u.rowid uid, u.lastname, u.firstname, u.email, u.login, u.admin,"; $sql .= " ba.rowid as bid, ba.ref as bref, ba.number as bnumber, ba.account_number, ba.fk_accountancy_journal, ba.label as blabel, ba.iban_prefix as iban, ba.bic, ba.currency_code, ba.clos"; @@ -253,7 +253,7 @@ if (!$resql) { $i = 0; $total = 0; $totalnb = 0; -$totalpaye = 0; +$totalpaid = 0; while ($i < min($num, $limit)) { $obj = $db->fetch_object($resql); @@ -346,8 +346,8 @@ while ($i < min($num, $limit)) { // Paid print ''; - if ($obj->totalpaye) { - print ''.price($obj->totalpaye).''; + if ($obj->totalpaid) { + print ''.price($obj->totalpaid).''; } print ''; @@ -357,7 +357,7 @@ while ($i < min($num, $limit)) { $total = $total + $obj->total; $totalnb = $totalnb + $obj->nb; - $totalpaye = $totalpaye + $obj->totalpaye; + $totalpaid = $totalpaid + $obj->totalpaid; $i++; } @@ -373,7 +373,7 @@ if (!empty($conf->banque->enabled)) { print ''; print ''; } -print ''.price($totalpaye).""; +print ''.price($totalpaid).""; print ''; print ""; diff --git a/htdocs/compta/stats/casoc.php b/htdocs/compta/stats/casoc.php index 0bef7ff555a..1df7ae4db62 100644 --- a/htdocs/compta/stats/casoc.php +++ b/htdocs/compta/stats/casoc.php @@ -179,6 +179,7 @@ $allparams = array_merge($commonparams, $headerparams, $tableparams); $headerparams = array_merge($commonparams, $headerparams); $tableparams = array_merge($commonparams, $tableparams); +$paramslink=""; foreach ($allparams as $key => $value) { $paramslink .= '&'.$key.'='.$value; } @@ -202,6 +203,9 @@ if ($modecompta == "BOOKKEEPINGCOLLECTED") { $modecompta = "RECETTES-DEPENSES"; } +$exportlink=""; +$namelink=""; + // Show report header if ($modecompta == "CREANCES-DETTES") { $name = $langs->trans("Turnover").', '.$langs->trans("ByThirdParties"); diff --git a/htdocs/compta/stats/index.php b/htdocs/compta/stats/index.php index e7ec8c61db7..b99002fe609 100644 --- a/htdocs/compta/stats/index.php +++ b/htdocs/compta/stats/index.php @@ -144,6 +144,8 @@ llxHeader(); $form = new Form($db); +$exportlink=""; +$namelink=""; // Affiche en-tete du rapport if ($modecompta == "CREANCES-DETTES") { $name = $langs->trans("Turnover"); @@ -254,6 +256,11 @@ $sql .= " ORDER BY dm"; $minyearmonth = $maxyearmonth = 0; +$cum = array(); +$cum_ht = array(); +$total_ht = array(); +$total = array(); + $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); @@ -395,6 +402,12 @@ for ($mois = 1 + $nb_mois_decalage; $mois <= 12 + $nb_mois_decalage; $mois++) { $case = dol_print_date(dol_mktime(1, 1, 1, $mois_modulo, 1, $annee_decalage), "%Y-%m"); $caseprev = dol_print_date(dol_mktime(1, 1, 1, $mois_modulo, 1, $annee_decalage - 1), "%Y-%m"); + $total_ht[$annee]=0; + $total[$annee]=0; + $cum_ht[$case]=0; + $cum[$case]=0; + + if ($annee >= $year_start) { // We ignore $annee < $year_start, we loop on it to be able to make delta, nothing is output. if ($modecompta == 'CREANCES-DETTES') { // Value turnover of month w/o VAT diff --git a/htdocs/compta/tva/card.php b/htdocs/compta/tva/card.php index 3a34d71c11d..e40b9b9b409 100644 --- a/htdocs/compta/tva/card.php +++ b/htdocs/compta/tva/card.php @@ -273,9 +273,9 @@ if ($action == 'add' && !$cancel) { if ($action == 'confirm_delete' && $confirm == 'yes') { $result = $object->fetch($id); - $totalpaye = $object->getSommePaiement(); + $totalpaid = $object->getSommePaiement(); - if (empty($totalpaye)) { + if (empty($totalpaid)) { $db->begin(); $ret = $object->delete($user); @@ -468,7 +468,7 @@ if ($action == 'create') { } else { $label = $langs->trans("VATPayment"); } - print ''.$langs->trans("Label").''; + print ''.$langs->trans("Label").''; print ''.$form->textwithpicto($langs->trans("PeriodEndDate"), $langs->trans("LastDayTaxIsRelatedTo")).''; print $form->selectDate((GETPOST("datevmonth", 'int') ? $datev : -1), "datev", '', '', '', 'add', 1, 1); @@ -540,7 +540,7 @@ if ($action == 'create') { if ($id > 0) { $head = vat_prepare_head($object); - $totalpaye = $object->getSommePaiement(); + $totalpaid = $object->getSommePaiement(); // Clone confirmation if ($action === 'clone') { @@ -580,7 +580,7 @@ if ($id > 0) { $linkback = ''.$langs->trans("BackToList").''; - $object->totalpaye = $totalpaye; // To give a chance to dol_banner_tab to use already paid amount to show correct status + $object->totalpaid = $totalpaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', ''); @@ -683,7 +683,7 @@ if ($id > 0) { //print $sql; $resql = $db->query($sql); if ($resql) { - $totalpaye = 0; + $totalpaid = 0; $num = $db->num_rows($resql); $i = 0; @@ -735,7 +735,7 @@ if ($id > 0) { } print ''.price($objp->amount)."\n"; print ""; - $totalpaye += $objp->amount; + $totalpaid += $objp->amount; $i++; } } else { @@ -744,10 +744,10 @@ if ($id > 0) { print ''; } - print ''.$langs->trans("AlreadyPaid")." :".price($totalpaye)."\n"; + print ''.$langs->trans("AlreadyPaid")." :".price($totalpaid)."\n"; print ''.$langs->trans("AmountExpected")." :".price($object->amount)."\n"; - $resteapayer = $object->amount - $totalpaye; + $resteapayer = $object->amount - $totalpaid; $cssforamountpaymentcomplete = 'amountpaymentcomplete'; print ''.$langs->trans("RemainderToPay")." :"; @@ -810,7 +810,7 @@ if ($id > 0) { print '"; } - if (!empty($user->rights->tax->charges->supprimer) && empty($totalpaye)) { + if (!empty($user->rights->tax->charges->supprimer) && empty($totalpaid)) { print ''; } else { print ''; @@ -853,7 +853,7 @@ if ($id > 0) { /* $MAXEVENT = 10; - $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-list-alt imgforviewmode', dol_buildpath('/mymodule/myobject_agenda.php', 1).'?id='.$object->id); + $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', dol_buildpath('/mymodule/myobject_agenda.php', 1).'?id='.$object->id); // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; diff --git a/htdocs/compta/tva/class/paymentvat.class.php b/htdocs/compta/tva/class/paymentvat.class.php index 8eaf141b06c..b7500fffaa0 100644 --- a/htdocs/compta/tva/class/paymentvat.class.php +++ b/htdocs/compta/tva/class/paymentvat.class.php @@ -96,6 +96,28 @@ class PaymentVAT extends CommonObject */ public $fk_user_modif; + /** + * @var int ID + */ + public $chid; + + /** + * @var string lib + * @deprecated + * @see $label + */ + public $lib; + + /** + * @var integer|string datepaye + */ + public $datepaye; + + /** + * @var integer|string paiementtype + */ + public $paiementtype; + /** * Constructor * diff --git a/htdocs/compta/tva/class/tva.class.php b/htdocs/compta/tva/class/tva.class.php index 30682fa15b4..f54ed42fb06 100644 --- a/htdocs/compta/tva/class/tva.class.php +++ b/htdocs/compta/tva/class/tva.class.php @@ -49,6 +49,12 @@ class Tva extends CommonObject */ public $picto = 'payment'; + /** + * @deprecated + * @see $amount + */ + public $total; + public $tms; public $datep; public $datev; @@ -56,6 +62,11 @@ class Tva extends CommonObject public $type_payment; public $num_payment; + /** + * @var integer|string totalpaid + */ + public $totalpaid; + /** * @var string label */ @@ -81,6 +92,11 @@ class Tva extends CommonObject */ public $fk_user_modif; + /** + * @var integer|string paiementtype + */ + public $paiementtype; + const STATUS_UNPAID = 0; const STATUS_PAID = 1; diff --git a/htdocs/compta/tva/document.php b/htdocs/compta/tva/document.php index a0573cf2812..22b3f988a70 100644 --- a/htdocs/compta/tva/document.php +++ b/htdocs/compta/tva/document.php @@ -125,8 +125,9 @@ if ($object->id) { $linkback = ''.$langs->trans("BackToList").''; - $object->totalpaye = $totalpaye; // To give a chance to dol_banner_tab to use already paid amount to show correct status + $object->totalpaid = $totalpaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status + $morehtmlright = ''; dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', $morehtmlref, '', 0, '', $morehtmlright); print '
    '; diff --git a/htdocs/compta/tva/index.php b/htdocs/compta/tva/index.php index fed0cf209c1..16b24361160 100644 --- a/htdocs/compta/tva/index.php +++ b/htdocs/compta/tva/index.php @@ -255,7 +255,7 @@ if ($refresh === true) { //var_dump($m); $total = 0; $subtotalcoll = 0; - $subtotalpaye = 0; + $subtotalpaid = 0; $subtotal = 0; $i = 0; $mcursor = 0; @@ -481,7 +481,7 @@ if ($refresh === true) { print '' . price(price2num($x_paye_sum, 'MT')) . ''; $subtotalcoll = $subtotalcoll + $x_coll_sum; - $subtotalpaye = $subtotalpaye + $x_paye_sum; + $subtotalpaid = $subtotalpaid + $x_paye_sum; $diff = $x_coll_sum - $x_paye_sum; $total = $total + $diff; @@ -498,12 +498,12 @@ if ($refresh === true) { print ''; print '' . $langs->trans("SubTotal") . ':'; print '' . price(price2num($subtotalcoll, 'MT')) . ''; - print '' . price(price2num($subtotalpaye, 'MT')) . ''; + print '' . price(price2num($subtotalpaid, 'MT')) . ''; print '' . price(price2num($subtotal, 'MT')) . ''; print ' '; $i = 0; $subtotalcoll = 0; - $subtotalpaye = 0; + $subtotalpaid = 0; $subtotal = 0; } } diff --git a/htdocs/compta/tva/list.php b/htdocs/compta/tva/list.php index f1731420852..5f76b2e9190 100644 --- a/htdocs/compta/tva/list.php +++ b/htdocs/compta/tva/list.php @@ -190,8 +190,8 @@ $sql .= $db->order($sortfield, $sortorder); $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + $resql = $db->query($sql); + $nbtotalofrecords = $db->num_rows($resql); // if total resultset is smaller then paging size (filtering), goto and load page 0 if (($page * $limit) > $nbtotalofrecords) { @@ -202,15 +202,15 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { $sql .= $db->plimit($limit + 1, $offset); -$result = $db->query($sql); -if (!$result) { +$resql = $db->query($sql); +if (!$resql) { dol_print_error($db); llxFooter(); $db->close(); exit; } -$num = $db->num_rows($result); +$num = $db->num_rows($resql); $param = ''; if (!empty($contextpage) && $contextpage != $_SERVER['PHP_SELF']) { @@ -429,7 +429,7 @@ print ''; $i = 0; $totalarray = array(); while ($i < min($num, $limit)) { - $obj = $db->fetch_object($result); + $obj = $db->fetch_object($resql); $tva_static->id = $obj->rowid; $tva_static->ref = $obj->rowid; @@ -549,11 +549,27 @@ $totalarray['nbfield']++; // Show total line include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; -print ''; -print '
    '; -print ''; +// If no record found +if ($num == 0) { + $colspan = 1; + foreach ($arrayfields as $key => $val) { + if (!empty($val['checked'])) { + $colspan++; + } + } + print ''.$langs->trans("NoRecordFound").''; +} -$db->free($result); +$db->free($resql); + +$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql); +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; + +print ''."\n"; +print '
    '."\n"; + +print ''."\n"; // End of page llxFooter(); diff --git a/htdocs/compta/tva/payments.php b/htdocs/compta/tva/payments.php index cf91df3a775..0279acdeaa4 100644 --- a/htdocs/compta/tva/payments.php +++ b/htdocs/compta/tva/payments.php @@ -5,7 +5,7 @@ * Copyright (C) 2011-2016 Alexandre Spangaro * Copyright (C) 2011-2014 Juanjo Menent * Copyright (C) 2015 Jean-François Ferry - * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Gauthier VERDOL * * 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 @@ -141,7 +141,7 @@ if (!empty($conf->tax->enabled) && $user->rights->tax->charges->lire) { $sql = "SELECT tva.rowid, tva.label as label, b.fk_account, ptva.fk_bank"; $sql .= ", tva.datev"; $sql .= ", tva.amount as total,"; - $sql .= " ptva.rowid as pid, ptva.datep, ptva.amount as totalpaye, ptva.num_paiement as num_payment,"; + $sql .= " ptva.rowid as pid, ptva.datep, ptva.amount as totalpaid, ptva.num_paiement as num_payment,"; $sql .= " pct.code as payment_code"; $sql .= " FROM ".MAIN_DB_PREFIX."tva as tva,"; $sql .= " ".MAIN_DB_PREFIX."payment_vat as ptva"; @@ -175,11 +175,15 @@ if (!empty($conf->tax->enabled) && $user->rights->tax->charges->lire) { $i = 0; $total = 0; $totalnb = 0; - $totalpaye = 0; + $totalpaid = 0; while ($i < min($num, $limit)) { $obj = $db->fetch_object($resql); + $tva->id = $obj->rowid; + $tva->ref = $obj->rowid; + $tva->label = $obj->label; + $payment_vat_static->id = $obj->pid; $payment_vat_static->ref = $obj->pid; @@ -190,31 +194,32 @@ if (!empty($conf->tax->enabled) && $user->rights->tax->charges->lire) { // VAT print ''; - $tva->id = $obj->rowid; - $tva->ref = $obj->rowid; - $tva->label = $obj->label; print $tva->getNomUrl(1, '20'); print ''; // Label - print ''.$obj->label.''; + print ''.dol_escape_htmltag($obj->label).''; // Date - $date = $obj->datev; - print ''.dol_print_date($date, 'day').''; + $date = $db->jdate($obj->datev); + print ''.dol_print_date($date, 'day').''; // Date payment - print ''.dol_print_date($db->jdate($obj->datep), 'day').''; + $datep = $db->jdate($obj->datep); + print ''.dol_print_date($datep, 'day').''; // Type payment - print ''; + $labelpaymenttype = ''; if ($obj->payment_code) { - print $langs->trans("PaymentTypeShort".$obj->payment_code).' '; + $labelpaymenttype = $langs->trans("PaymentTypeShort".$obj->payment_code).' '; } + + print ''; + print dol_escape_htmltag($labelpaymenttype); print ''; // Chq number - print ''.$obj->num_payment.''; + print ''.dol_escape_htmltag($obj->num_payment).''; if (!empty($conf->banque->enabled)) { // Bank transaction @@ -231,21 +236,20 @@ if (!empty($conf->tax->enabled) && $user->rights->tax->charges->lire) { print ''; } - // Type - //print ''.$obj->type_label.''; // Expected to pay print ''.price($obj->total).''; + // Paid print ''; - if ($obj->totalpaye) { - print price($obj->totalpaye); + if ($obj->totalpaid) { + print price($obj->totalpaid); } print ''; print ''; $total = $total + $obj->total; $totalnb = $totalnb + $obj->nb; - $totalpaye = $totalpaye + $obj->totalpaye; + $totalpaid = $totalpaid + $obj->totalpaid; $i++; } @@ -260,7 +264,7 @@ if (!empty($conf->tax->enabled) && $user->rights->tax->charges->lire) { } print ' '; print ' '; - print ''.price($totalpaye).""; + print ''.price($totalpaid).""; print ""; } else { dol_print_error($db); diff --git a/htdocs/compta/tva/quadri_detail.php b/htdocs/compta/tva/quadri_detail.php index 4b44959bc1a..15c45d6055b 100644 --- a/htdocs/compta/tva/quadri_detail.php +++ b/htdocs/compta/tva/quadri_detail.php @@ -6,7 +6,7 @@ * Copyright (C) 2014 Ferran Marcet * Copyright (C) 2018-2021 Frédéric France * Copyright (C) 2019 Eric Seigne - * Copyright (C) 2021 Open-Dsi + * Copyright (C) 2021-2022 Open-Dsi * * 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 @@ -47,7 +47,7 @@ $langs->loadLangs(array("other", "compta", "banks", "bills", "companies", "produ $refresh = (GETPOSTISSET('submit') || GETPOSTISSET('vat_rate_show') || GETPOSTISSET('invoice_type')) ? true : false; $invoice_type = GETPOSTISSET('invoice_type') ? GETPOST('invoice_type', 'alpha') : ''; -$vat_rate_show = GETPOSTISSET('vat_rate_show') ? GETPOST('vat_rate_show', 'int') : -1; +$vat_rate_show = GETPOSTISSET('vat_rate_show') ? GETPOST('vat_rate_show', 'alphanohtml') : -1; include DOL_DOCUMENT_ROOT.'/compta/tva/initdatesforvat.inc.php'; @@ -409,7 +409,7 @@ if (!is_array($x_coll) || !is_array($x_paye)) { print ''; print $langs->trans('Rate') . ' : ' . vatrate($rate) . '%'; print ' - ' . img_picto('', 'chevron-down', 'class="paddingrightonly"') . $langs->trans('VATReportShowByRateDetails') . ''; @@ -643,7 +643,7 @@ if (!is_array($x_coll) || !is_array($x_paye)) { print ''; print $langs->trans('Rate') . ' : ' . vatrate($rate) . '%'; print ' - ' . img_picto('', 'chevron-down', 'class="paddingrightonly"') . $langs->trans('VATReportShowByRateDetails') . ''; diff --git a/htdocs/conf/conf.php.example b/htdocs/conf/conf.php.example index 44f0d63d69f..487576ed058 100644 --- a/htdocs/conf/conf.php.example +++ b/htdocs/conf/conf.php.example @@ -321,6 +321,15 @@ $dolibarr_cron_allow_cli='0'; // // $php_session_save_handler=''; +// force_install_lockinstall +// If this value is set to a value, it forces the creation of a file install.lock once an upgrade process into a new version end. +// The value is the octal value of permission to set on created file. +// The file install.lock prevents the use of the migration process another time. You will have to delete it manually for +// next upgrade. +// Default value: '0' +// Example: '444'; +// $force_install_lockinstall='440'; + //################## diff --git a/htdocs/contact/agenda.php b/htdocs/contact/agenda.php index 0eed6ba6219..98b6ccea3b1 100644 --- a/htdocs/contact/agenda.php +++ b/htdocs/contact/agenda.php @@ -251,17 +251,17 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { $objthirdparty = $object->thirdparty; $out = ''; - $permok = $user->rights->agenda->myactions->create; - if ((!empty($objthirdparty->id) || !empty($objcon->id)) && $permok) { - if (is_object($objthirdparty) && get_class($objthirdparty) == 'Societe') { - $out .= '&originid='.$objthirdparty->id.($objthirdparty->id > 0 ? '&socid='.$objthirdparty->id : ''); - } - $out .= (!empty($objcon->id) ? '&contactid='.$objcon->id : '').'&origin=contact&originid='.$object->id.'&percentage=-1&backtopage='.urlencode($_SERVER['PHP_SELF'].($objcon->id > 0 ? '?id='.$objcon->id : '')); - $out .= '&datep='.urlencode(dol_print_date(dol_now(), 'dayhourlog')); - } - $newcardbutton = ''; if (!empty($conf->agenda->enabled)) { + $permok = $user->rights->agenda->myactions->create; + if ((!empty($objthirdparty->id) || !empty($objcon->id)) && $permok) { + if (is_object($objthirdparty) && get_class($objthirdparty) == 'Societe') { + $out .= '&originid='.$objthirdparty->id.($objthirdparty->id > 0 ? '&socid='.$objthirdparty->id : ''); + } + $out .= (!empty($objcon->id) ? '&contactid='.$objcon->id : '').'&origin=contact&originid='.$object->id.'&percentage=-1&backtopage='.urlencode($_SERVER['PHP_SELF'].($objcon->id > 0 ? '?id='.$objcon->id : '')); + $out .= '&datep='.urlencode(dol_print_date(dol_now(), 'dayhourlog')); + } + if (!empty($user->rights->agenda->myactions->create) || !empty($user->rights->agenda->allactions->create)) { $newcardbutton .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create'.$out); } diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index 229bfc0530b..cd12fd12150 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -40,6 +40,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; @@ -235,6 +236,9 @@ if (empty($reshook)) { $object->birthday = dol_mktime(0, 0, 0, GETPOST("birthdaymonth", 'int'), GETPOST("birthdayday", 'int'), GETPOST("birthdayyear", 'int')); $object->birthday_alert = GETPOST("birthday_alert", 'alpha'); + //Default language + $object->default_lang = GETPOST('default_lang'); + // Fill array 'array_options' with data from add form $ret = $extrafields->setOptionalsFromPost(null, $object); if ($ret < 0) { @@ -316,8 +320,9 @@ if (empty($reshook)) { $result = $object->delete(); // TODO Add $user as first param if ($result > 0) { - if ($backtopage) { - header("Location: ".$backtopage); + setEventMessages("RecordDeleted", null, 'mesgs'); + if ($backurlforlist) { + header("Location: ".$backurlforlist); exit; } else { header("Location: ".DOL_URL_ROOT.'/contact/list.php'); @@ -436,6 +441,9 @@ if (empty($reshook)) { $object->roles = GETPOST("roles", 'array'); // Note GETPOSTISSET("role") is null when combo is empty + //Default language + $object->default_lang = GETPOST('default_lang'); + // Fill array 'array_options' with data from add form $ret = $extrafields->setOptionalsFromPost(null, $object, '@GETPOSTISSET'); if ($ret < 0) { @@ -556,6 +564,7 @@ if (empty($reshook)) { */ $form = new Form($db); +$formadmin = new FormAdmin($db); $formcompany = new FormCompany($db); $title = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("Contacts") : $langs->trans("ContactsAddresses")); @@ -624,7 +633,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { */ $object->canvas = $canvas; - $object->state_id = GETPOST("state_id"); + $object->state_id = GETPOST("state_id", "int"); // We set country_id, country_code and label for the selected country $object->country_id = GETPOST("country_id") ? GETPOST("country_id", "int") : (empty($objsoc->country_id) ? $mysoc->country_id : $objsoc->country_id); @@ -634,7 +643,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { $object->country = $tmparray['label']; } - $title = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("AddContact") : $langs->trans("AddContactAddress")); + $title = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("NewContact") : $langs->trans("NewContactAddress")); $linkback = ''; print load_fiche_titre($title, $linkback, 'address'); @@ -697,7 +706,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''; } else { print ''; - print img_picto('', 'company').$form->select_company($socid, 'socid', '', 'SelectThirdParty'); + print img_picto('', 'company').$form->select_company($socid, 'socid', '', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300 maxwidth500 widthcentpercentminusxx'); print ''; } } @@ -856,7 +865,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if (!empty($value['icon'])) { print ''; } - print ''; + print ''; print ''; print ''; } elseif (!empty($object->socialnetworks[$key])) { @@ -871,6 +880,15 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print $form->selectarray('priv', $selectarray, (GETPOST("priv", 'alpha') ?GETPOST("priv", 'alpha') : $object->priv), 0); print ''; + //Default language + if (!empty($conf->global->MAIN_MULTILANGS)) { + print ''.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0).''."\n"; + print $formadmin->select_language(GETPOST('default_lang', 'alpha') ?GETPOST('default_lang', 'alpha') : ($object->default_lang ? $object->default_lang : ''), 'default_lang', 0, 0, 1, 0, 0, 'maxwidth200onsmartphone', 0, 0, 0, null, 1); + + print ''; + print ''; + } + // Categories if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { print ''.$form->editfieldkey('Categories', 'contcats', '', $object, 0).''; @@ -1150,6 +1168,15 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print $form->selectarray('priv', $selectarray, $object->priv, 0); print ''; + //Default language + if (!empty($conf->global->MAIN_MULTILANGS)) { + print ''.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0).''."\n"; + print $formadmin->select_language($object->default_lang, 'default_lang', 0, 0, 1, 0, 0, '', 0, 0, 0, null, 1); + + print ''; + print ''; + } + // Note Public print ''; $doleditor = new DolEditor('note_public', $object->note_public, '', 80, 'dolibarr_notes', 'In', 0, false, empty($conf->global->FCKEDITOR_ENABLE_NOTE_PUBLIC) ? 0 : 1, ROWS_3, '90%'); @@ -1362,6 +1389,18 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''; } + // Default language + if (!empty($conf->global->MAIN_MULTILANGS)) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + print ''.$langs->trans("DefaultLang").''; + //$s=picto_from_langcode($object->default_lang); + //print ($s?$s.' ':''); + $langs->load("languages"); + $labellang = ($object->default_lang ? $langs->trans('Language_'.$object->default_lang.'_'.strtoupper($object->default_lang)) : ''); + print $labellang; + print ''; + } + print ''.$langs->trans("ContactVisibility").''; print $object->LibPubPriv($object->priv); print ''; @@ -1550,7 +1589,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { $MAXEVENT = 10; - $morehtmlright = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-list-alt imgforviewmode', DOL_URL_ROOT.'/contact/agenda.php?id='.$object->id); + $morehtmlright = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/contact/agenda.php?id='.$object->id); // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index bb3f2ae035d..9fa3602ee4b 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -130,6 +130,13 @@ class Contact extends CommonObject public $civility_code; public $civility; + /** + * @var string The civilite code, not an integer + * @deprecated + * @see $civility_code + */ + public $civilite; + /** * @var string Address */ @@ -181,6 +188,12 @@ class Contact extends CommonObject */ public $email; + /** + * URL + * @var string + */ + public $url; + /** * Unsuscribe all : 1 = contact has globaly unsubscribe of all mass emailings * @var int @@ -315,6 +328,7 @@ class Contact extends CommonObject */ public $stcomm_picto; + /** * Constructor * @@ -376,7 +390,7 @@ class Contact extends CommonObject public function load_state_board() { // phpcs:enable - global $user; + global $user, $hookmanager; $this->nb = array(); $clause = "WHERE"; @@ -394,6 +408,12 @@ class Contact extends CommonObject if ($user->socid > 0) { $sql .= " AND sp.fk_soc = ".((int) $user->socid); } + // Add where from hooks + if (is_object($hookmanager)) { + $parameters = array(); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $this); // Note that $action and $object may have been modified by hook + $sql .= $hookmanager->resPrint; + } $resql = $this->db->query($sql); if ($resql) { @@ -1455,13 +1475,6 @@ class Contact extends CommonObject } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - - /* - $hookmanager->initHooks(array('contactdao')); - $parameters=array('id'=>$this->id); - $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $linkclose = $hookmanager->resPrint; - */ } $linkstart = 'initHooks(array('contactdao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; @@ -1820,7 +1833,7 @@ class Contact extends CommonObject $this->db->begin(); - $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_contacts WHERE fk_socpeople=".((int) $this->id)." AND entity IN (".getEntity("societe_contact").")"; + $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_contacts WHERE fk_socpeople=".((int) $this->id)." AND entity IN (".getEntity("contact").")"; $result = $this->db->query($sql); if (!$result) { diff --git a/htdocs/contact/consumption.php b/htdocs/contact/consumption.php index 631bf932640..b7fc682d2c6 100644 --- a/htdocs/contact/consumption.php +++ b/htdocs/contact/consumption.php @@ -153,16 +153,16 @@ print ''; if ($object->thirdparty->client) { $thirdTypeArray['customer'] = $langs->trans("customer"); - if ($conf->propal->enabled && $user->rights->propal->lire) { + if (!empty($conf->propal->enabled) && $user->rights->propal->lire) { $elementTypeArray['propal'] = $langs->transnoentitiesnoconv('Proposals'); } - if ($conf->commande->enabled && $user->rights->commande->lire) { + if (!empty($conf->commande->enabled) && $user->rights->commande->lire) { $elementTypeArray['order'] = $langs->transnoentitiesnoconv('Orders'); } - if ($conf->facture->enabled && $user->rights->facture->lire) { + if (!empty($conf->facture->enabled) && $user->rights->facture->lire) { $elementTypeArray['invoice'] = $langs->transnoentitiesnoconv('Invoices'); } - if ($conf->contrat->enabled && $user->rights->contrat->lire) { + if (!empty($conf->contrat->enabled) && $user->rights->contrat->lire) { $elementTypeArray['contract'] = $langs->transnoentitiesnoconv('Contracts'); } } @@ -355,7 +355,7 @@ if (empty($elementTypeArray) && !$object->thirdparty->client && !$object->thirdp // Define type of elements $typeElementString = $form->selectarray("type_element", $elementTypeArray, GETPOST('type_element'), $showempty, 0, 0, '', 0, 0, $disabled, '', 'maxwidth150onsmartphone'); -$button = ''; +$button = ''; $param = ''; $param .= "&sref=".urlencode($sref); @@ -366,7 +366,7 @@ $param .= "&socid=".urlencode($socid); $param .= "&type_element=".urlencode($type_element); $total_qty = 0; - +$num=0; if ($sql_select) { $resql = $db->query($sql); if (!$resql) { @@ -410,7 +410,7 @@ if ($sql_select) { print ''; print ''; // date print $formother->select_month($month ? $month : -1, 'month', 1, 0, 'valignmiddle'); - $formother->select_year($year ? $year : -1, 'year', 1, 20, 1); + print $formother->selectyear($year ? $year : -1, 'year', 1, 20, 1); print ''; print ''; print ''; diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 66561730829..e68274ecff2 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -132,31 +132,31 @@ if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('b } $offset = $limit * $page; -$titre = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("ListOfContacts") : $langs->trans("ListOfContactsAddresses")); +$title = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("Contacts") : $langs->trans("ContactsAddresses")); if ($type == "p") { if (empty($contextpage) || $contextpage == 'contactlist') { $contextpage = 'contactprospectlist'; } - $titre .= ' ('.$langs->trans("ThirdPartyProspects").')'; + $title .= ' ('.$langs->trans("ThirdPartyProspects").')'; $urlfiche = "card.php"; } if ($type == "c") { if (empty($contextpage) || $contextpage == 'contactlist') { $contextpage = 'contactcustomerlist'; } - $titre .= ' ('.$langs->trans("ThirdPartyCustomers").')'; + $title .= ' ('.$langs->trans("ThirdPartyCustomers").')'; $urlfiche = "card.php"; } elseif ($type == "f") { if (empty($contextpage) || $contextpage == 'contactlist') { $contextpage = 'contactsupplierlist'; } - $titre .= ' ('.$langs->trans("ThirdPartySuppliers").')'; + $title .= ' ('.$langs->trans("ThirdPartySuppliers").')'; $urlfiche = "card.php"; } elseif ($type == "o") { if (empty($contextpage) || $contextpage == 'contactlist') { $contextpage = 'contactotherlist'; } - $titre .= ' ('.$langs->trans("OthersNotLinkedToThirdParty").')'; + $title .= ' ('.$langs->trans("OthersNotLinkedToThirdParty").')'; $urlfiche = ""; } @@ -384,7 +384,7 @@ if (!empty($conf->mailing->enabled)) { } // Add fields from hooks $parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as p"; if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { @@ -405,7 +405,7 @@ if (!empty($search_categ_supplier) && $search_categ_supplier != '-1') { if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; } -$sql .= ' WHERE p.entity IN ('.getEntity('socpeople').')'; +$sql .= ' WHERE p.entity IN ('.getEntity('contact').')'; if (empty($user->rights->societe->client->voir) && !$socid) { //restriction $sql .= " AND (sc.fk_user = ".((int) $user->id)." OR p.fk_soc IS NULL)"; } @@ -543,7 +543,7 @@ if (!empty($socid)) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks $parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; // Add order if ($view == "recent") { @@ -709,7 +709,7 @@ print ''; print ''; print ''; -print_barre_liste($titre, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'address', 0, $newcardbutton, '', $limit, 0, 0, 1); +print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'address', 0, $newcardbutton, '', $limit, 0, 0, 1); $topicmail = "Information"; $modelmail = "contact"; @@ -767,7 +767,7 @@ $moreforfilter .= '
    '; print '
    '; print $moreforfilter; $parameters = array('type'=>$type); -$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; print '
    '; @@ -910,7 +910,7 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; // Fields from hook $parameters = array('arrayfields'=>$arrayfields); -$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation if (!empty($arrayfields['p.datec']['checked'])) { @@ -1018,7 +1018,7 @@ $parameters = array( 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, ); -$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; if (!empty($arrayfields['p.datec']['checked'])) { print_liste_field_titre($arrayfields['p.datec']['label'], $_SERVER["PHP_SELF"], "p.datec", "", $param, '', $sortfield, $sortorder, 'center nowrap '); @@ -1255,7 +1255,7 @@ while ($i < min($num, $limit)) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); - $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation if (!empty($arrayfields['p.datec']['checked'])) { @@ -1309,19 +1309,31 @@ while ($i < min($num, $limit)) { $i++; } +// Show total line +include DOL_DOCUMENT_ROOT.'/core/tpl/list_print_total.tpl.php'; + +// If no record found +if ($num == 0) { + $colspan = 1; + foreach ($arrayfields as $key => $val) { + if (!empty($val['checked'])) { + $colspan++; + } + } + print ''.$langs->trans("NoRecordFound").''; +} + $db->free($resql); $parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql); -$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; -print ""; -print "
    "; - -//if ($num > $limit || $page) print_barre_liste('', $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_companies.png', 0, '', '', $limit, 1); - -print ''; +print ''."\n"; +print ''."\n"; +print ''."\n"; +// End of page llxFooter(); $db->close(); diff --git a/htdocs/contact/project.php b/htdocs/contact/project.php new file mode 100644 index 00000000000..b05709f019a --- /dev/null +++ b/htdocs/contact/project.php @@ -0,0 +1,117 @@ + + * + * 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 . + */ + +/** + * \file htdocs/contact/project.php + * \ingroup contact + * \brief Page of third party projects + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + +$langs->loadLangs(array("contacts", "companies", "projects")); + +// Security check +$id = GETPOST('id', 'int'); +$result = restrictedArea($user, 'contact', $id, 'socpeople&societe'); + +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('projectcontact')); + +/* + * 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'); +} + +/* + * View + */ + +$form = new Form($db); + +if ($id) { + require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/contact.lib.php'; + + $object = new Contact($db); + + $result = $object->fetch($id); + if (empty($object->thirdparty)) { + $object->fetch_thirdparty(); + } + $socid = $object->thirdparty->id; + $title = $langs->trans("Projects"); + if (! empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/', $conf->global->MAIN_HTML_TITLE) && $object->name) { + $title = $object->name." - ".$title; + } + llxHeader('', $title); + + if (! empty($conf->notification->enabled)) { + $langs->load("mails"); + } + $head = contact_prepare_head($object); + + print dol_get_fiche_head($head, 'project', $langs->trans("Contact"), -1, 'contact'); + + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + if (empty($conf->global->SOCIETE_DISABLE_CONTACTS) && !empty($socid)) { + $object->thirdparty->fetch($socid); + // Thirdparty + $morehtmlref .= $langs->trans('ThirdParty').' : '; + if ($object->thirdparty->id > 0) { + $morehtmlref .= $object->thirdparty->getNomUrl(1, 'contact'); + } else { + $morehtmlref .= $langs->trans("ContactNotLinkedToCompany"); + } + } + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'id', $linkback, ($user->socid ? 0 : 1), 'rowid', 'nom', $morehtmlref); + + print '
    '; + + print '
    '; + print ''; + + // Civility + print ''; + + print '
    '.$langs->trans("UserTitle").''; + print $object->getCivilityLabel(); + print '
    '; + + print '
    '; + + print dol_get_fiche_end(); + print '
    '; + + // Projects list + $result = show_contacts_projects($conf, $langs, $db, $object, $_SERVER["PHP_SELF"].'?id='.$object->id, 1); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/contrat/admin/contract_extrafields.php b/htdocs/contrat/admin/contract_extrafields.php index b725ef6f3f4..71483f6b1aa 100644 --- a/htdocs/contrat/admin/contract_extrafields.php +++ b/htdocs/contrat/admin/contract_extrafields.php @@ -84,7 +84,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/contrat/admin/contractdet_extrafields.php b/htdocs/contrat/admin/contractdet_extrafields.php index 70d3193c12f..cc4cf23e37b 100644 --- a/htdocs/contrat/admin/contractdet_extrafields.php +++ b/htdocs/contrat/admin/contractdet_extrafields.php @@ -84,7 +84,7 @@ print dol_get_fiche_end(); // Buttons if ($action != 'create' && $action != 'edit') { print '"; } diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index a4a270f5227..d17f5399679 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -40,6 +40,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/modules/contract/modules_contract.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; if (!empty($conf->propal->enabled)) { require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; } @@ -248,6 +249,10 @@ if (empty($reshook)) { if ($element == 'propal') { $element = 'comm/propal'; $subelement = 'propal'; } + if ($element == 'invoice' || $element == 'facture') { + $element = 'compta/facture'; + $subelement = 'facture'; + } $object->origin = $origin; $object->origin_id = $originid; @@ -528,9 +533,9 @@ if (empty($reshook)) { $localtax2_tx = get_localtax($tva_tx, 2, $object->thirdparty, $mysoc, $tva_npr); // ajout prix achat - $fk_fournprice = $_POST['fournprice']; - if (!empty($_POST['buying_price'])) { - $pa_ht = $_POST['buying_price']; + $fk_fournprice = GETPOST('fournprice'); + if (GETPOST('buying_price')) { + $pa_ht = GETPOST('buying_price'); } else { $pa_ht = null; } @@ -1039,6 +1044,10 @@ if ($action == 'create') { if ($element == 'propal') { $element = 'comm/propal'; $subelement = 'propal'; } + if ($element == 'invoice' || $element == 'facture') { + $element = 'compta/facture'; + $subelement = 'facture'; + } dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); @@ -2017,62 +2026,73 @@ if ($action == 'create') { $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { + $params = array( + 'attr' => array( + 'title' => '', + 'class' => 'classfortooltip' + ) + ); + // Send if (empty($user->socid)) { if ($object->statut == 1) { if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->contrat->creer)) { - print ''; + print dolGetButtonAction($langs->trans('SendMail'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&token='.newToken().'&mode=init#formmailbeforetitle', '', true, $params); } else { - print ''; + print dolGetButtonAction($langs->trans('SendMail'), '', 'default', '#', '', false, $params); } } } if ($object->statut == 0 && $nbofservices) { if ($user->rights->contrat->creer) { - print ''; + print dolGetButtonAction($langs->trans('Validate'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=valid&token='.newToken(), '', true, $params); } else { - print ''; + $params['attr']['title'] = $langs->trans("NotEnoughPermissions"); + print dolGetButtonAction($langs->trans('Validate'), '', 'default', '#', '', false, $params); } } if ($object->statut == 1) { if ($user->rights->contrat->creer) { - print ''; + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken(), '', true, $params); } else { - print ''; + $params['attr']['title'] = $langs->trans("NotEnoughPermissions"); + print dolGetButtonAction($langs->trans('Modify'), '', 'default', '#', '', false, $params); } } if (!empty($conf->commande->enabled) && $object->statut > 0 && $object->nbofservicesclosed < $nbofservices) { $langs->load("orders"); if ($user->rights->commande->creer) { - print ''; + print dolGetButtonAction($langs->trans('CreateOrder'), '', 'default', DOL_URL_ROOT.'/commande/card.php?action=create&token='.newToken().'&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->thirdparty->id, '', true, $params); } else { - print ''; + $params['attr']['title'] = $langs->trans("NotEnoughPermissions"); + print dolGetButtonAction($langs->trans('CreateOrder'), '', 'default', '#', '', false, $params); } } if (!empty($conf->facture->enabled) && $object->statut > 0) { $langs->load("bills"); if ($user->rights->facture->creer) { - print ''; + print dolGetButtonAction($langs->trans('CreateBill'), '', 'default', DOL_URL_ROOT.'/compta/facture/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->thirdparty->id, '', true, $params); } else { - print ''; + $params['attr']['title'] = $langs->trans("NotEnoughPermissions"); + print dolGetButtonAction($langs->trans('CreateBill'), '', 'default', '#', '', false, $params); } } if ($object->nbofservicesclosed > 0 || $object->nbofserviceswait > 0) { if ($user->rights->contrat->activer) { - print ''; + print dolGetButtonAction($langs->trans('ActivateAllContracts'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=activate&token='.newToken(), '', true, $params); } else { - print ''; + print dolGetButtonAction($langs->trans('ActivateAllContracts'), '', 'default', '#', '', false, $params); } } if ($object->nbofservicesclosed < $nbofservices) { if ($user->rights->contrat->desactiver) { - print ''; + print dolGetButtonAction($langs->trans('CloseAllContracts'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=close&token='.newToken(), '', true, $params); } else { - print ''; + print dolGetButtonAction($langs->trans('CloseAllContracts'), '', 'default', '#', '', false, $params); } //if (! $numactive) @@ -2094,16 +2114,17 @@ if ($action == 'create') { // Clone if ($user->rights->contrat->creer) { - print ''; + print dolGetButtonAction($langs->trans('ToClone'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&socid='.$object->socid.'&action=clone&token='.newToken(), '', true, $params); } // On peut supprimer entite si // - Droit de creer + mode brouillon (erreur creation) // - Droit de supprimer if (($user->rights->contrat->creer && $object->statut == $object::STATUS_DRAFT) || $user->rights->contrat->supprimer) { - print ''; + print dolGetButtonAction($langs->trans('Delete'), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), '', true, $params); } else { - print ''; + $params['attr']['title'] = $langs->trans("NotAllowed"); + print dolGetButtonAction($langs->trans('Delete'), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), '', false, $params); } } @@ -2139,7 +2160,7 @@ if ($action == 'create') { $MAXEVENT = 10; - $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-list-alt imgforviewmode', DOL_URL_ROOT.'/contrat/agenda.php?id='.$object->id); + $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/contrat/agenda.php?id='.$object->id); // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; diff --git a/htdocs/contrat/class/api_contracts.class.php b/htdocs/contrat/class/api_contracts.class.php index 5e534f3e43c..ea228550cae 100644 --- a/htdocs/contrat/class/api_contracts.class.php +++ b/htdocs/contrat/class/api_contracts.class.php @@ -278,8 +278,8 @@ class Contracts extends DolibarrApi $request_data = (object) $request_data; - $request_data->desc = checkVal($request_data->desc, 'restricthtml'); - $request_data->price_base_type = checkVal($request_data->price_base_type); + $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml'); + $request_data->price_base_type = sanitizeVal($request_data->price_base_type); $updateRes = $this->contract->addline( $request_data->desc, @@ -336,8 +336,8 @@ class Contracts extends DolibarrApi $request_data = (object) $request_data; - $request_data->desc = checkVal($request_data->desc, 'restricthtml'); - $request_data->price_base_type = checkVal($request_data->price_base_type); + $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml'); + $request_data->price_base_type = sanitizeVal($request_data->price_base_type); $updateRes = $this->contract->updateline( $lineid, diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 27e8cc6bf95..79f2e8e9e15 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -232,11 +232,11 @@ class Contrat extends CommonObject 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35), 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>40), 'date_contrat' =>array('type'=>'datetime', 'label'=>'Date contrat', 'enabled'=>1, 'visible'=>-1, 'position'=>45), - 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>70), - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>1, 'visible'=>-1, 'position'=>75), - 'fk_commercial_signature' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk commercial signature', 'enabled'=>1, 'visible'=>-1, 'position'=>80), - 'fk_commercial_suivi' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk commercial suivi', 'enabled'=>1, 'visible'=>-1, 'position'=>85), - 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>90), + 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'$conf->societe->enabled', 'visible'=>-1, 'notnull'=>1, 'position'=>70), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>'$conf->projet->enabled', 'visible'=>-1, 'position'=>75), + 'fk_commercial_signature' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'SaleRepresentative Signature', 'enabled'=>1, 'visible'=>-1, 'position'=>80), + 'fk_commercial_suivi' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'SaleRepresentative follower', 'enabled'=>1, 'visible'=>-1, 'position'=>85), + 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>90), 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>105), 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>110), 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>115), @@ -245,7 +245,7 @@ class Contrat extends CommonObject 'ref_customer' =>array('type'=>'varchar(50)', 'label'=>'Ref customer', 'enabled'=>1, 'visible'=>-1, 'position'=>130), 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135), 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'Last main doc', 'enabled'=>1, 'visible'=>-1, 'position'=>140), - 'statut' =>array('type'=>'smallint(6)', 'label'=>'Statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Closed')) + 'statut' =>array('type'=>'smallint(6)', 'label'=>'Statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500, 'notnull'=>1, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Validated', 2=>'Closed')) ); // END MODULEBUILDER PROPERTIES @@ -387,7 +387,7 @@ class Contrat extends CommonObject if ($contratline->statut != ContratLigne::STATUS_OPEN) { $contratline->context = $this->context; - $result = $contratline->active_line($user, $date_start, -1, $comment); + $result = $contratline->active_line($user, $date_start, -1, $comment); // This call trigger LINECONTRACT_ACTIVATE if ($result < 0) { $error++; $this->error = $contratline->error; @@ -751,15 +751,14 @@ class Contrat extends CommonObject * Load lines array into this->lines. * This set also nbofserviceswait, nbofservicesopened, nbofservicesexpired and nbofservicesclosed * - * @param int $only_product Return only physical products - * @param int $loadalsotranslation Return translation for products - * - * @return ContratLigne[] Return array of contract lines + * @param int $only_services 0=Default, 1=Force only services (depending on setup, we may also have physical products in a contract) + * @param int $loadalsotranslation 0=Default, 1=Load also translations of product descriptions + * @return ContratLigne[] Return array of contract lines */ - public function fetch_lines($only_product = 0, $loadalsotranslation = 0) + public function fetch_lines($only_services = 0, $loadalsotranslation = 0) { // phpcs:enable - global $langs, $conf, $extrafields; + global $langs, $conf; $this->nbofservices = 0; $this->nbofserviceswait = 0; @@ -773,14 +772,6 @@ class Contrat extends CommonObject $now = dol_now(); - if (!is_object($extrafields)) { - require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; - $extrafields = new ExtraFields($this->db); - } - - $line = new ContratLigne($this->db); - $extrafields->fetch_name_optionals_label($line->table_element, true); - $this->lines = array(); $pos = 0; @@ -802,6 +793,9 @@ class Contrat extends CommonObject $sql .= " d.product_type as type"; $sql .= " FROM ".MAIN_DB_PREFIX."contratdet as d LEFT JOIN ".MAIN_DB_PREFIX."product as p ON d.fk_product = p.rowid"; $sql .= " WHERE d.fk_contrat = ".((int) $this->id); + if ($only_services == 1) { + $sql .= " AND d.product_type = 1"; + } $sql .= " ORDER by d.rowid ASC"; dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG); @@ -814,6 +808,7 @@ class Contrat extends CommonObject $objp = $this->db->fetch_object($result); $line = new ContratLigne($this->db); + $line->id = $objp->rowid; $line->ref = $objp->rowid; $line->fk_contrat = $objp->fk_contrat; @@ -840,7 +835,7 @@ class Contrat extends CommonObject $line->type = $objp->type; $line->fk_fournprice = $objp->fk_fournprice; - $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht); + $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $objp->fk_fournprice, $objp->pa_ht); $line->pa_ht = $marginInfos[0]; $line->fk_user_author = $objp->fk_user_author; @@ -870,18 +865,21 @@ class Contrat extends CommonObject $line->date_fin_prevue = $this->db->jdate($objp->date_fin_validite); $line->date_fin_reel = $this->db->jdate($objp->date_cloture); - // Retrieve all extrafields for contract + // Retrieve all extrafields for contract line // fetch optionals attributes and labels $line->fetch_optionals(); // multilangs if (!empty($conf->global->MAIN_MULTILANGS) && !empty($objp->fk_product) && !empty($loadalsotranslation)) { - $line = new Product($this->db); - $line->fetch($objp->fk_product); - $line->getMultiLangs(); + $tmpproduct = new Product($this->db); + $tmpproduct->fetch($objp->fk_product); + $tmpproduct->getMultiLangs(); + + $line->multilangs = $tmpproduct->multilangs; } $this->lines[$pos] = $line; + $this->lines_id_index_mapper[$line->id] = $pos; //dol_syslog("1 ".$line->desc); @@ -1792,7 +1790,7 @@ class Contrat extends CommonObject if (empty($error)) { // Call trigger - $result = $this->call_trigger('LINECONTRACT_UPDATE', $user); + $result = $this->call_trigger('LINECONTRACT_MODIFY', $user); if ($result < 0) { $this->db->rollback(); return -3; @@ -2042,7 +2040,7 @@ class Contrat extends CommonObject global $action; $hookmanager->initHooks(array('contractdao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { $result = $hookmanager->resPrint; @@ -2130,19 +2128,27 @@ class Contrat extends CommonObject /** * Return list of other contracts for same company than current contract * - * @param string $option 'all' or 'others' - * @return array|int Array of contracts id or <0 if error + * @param string $option 'all' or 'others' + * @param array $status sort contracts having these status + * @param array $product_categories sort contracts containing these product categories + * @param array $line_status sort contracts where lines have these status + * @return array|int Array of contracts id or <0 if error */ - public function getListOfContracts($option = 'all') + public function getListOfContracts($option = 'all', $status = [], $product_categories = [], $line_status = []) { $tab = array(); $sql = "SELECT c.rowid, c.ref"; $sql .= " FROM ".MAIN_DB_PREFIX."contrat as c"; - $sql .= " WHERE fk_soc =".((int) $this->socid); - if ($option == 'others') { - $sql .= " AND c.rowid <> ".((int) $this->id); + if (!empty($product_categories)) { + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."contratdet as cd ON cd.fk_contrat = c.rowid"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."categorie_product as cp ON cp.fk_product = cd.fk_product AND cp.fk_categorie IN (".$this->db->sanitize(implode(', ', $product_categories)).")"; } + $sql .= " WHERE c.fk_soc =".((int) $this->socid); + $sql .= ($option == 'others') ? " AND c.rowid <> ".((int) $this->id) : ""; + $sql .= (!empty($status)) ? " AND c.statut IN (".$this->db->sanitize(implode(', ', $status)).")" : ""; + $sql .= (!empty($line_status)) ? " AND cd.statut IN (".$this->db->sanitize(implode(', ', $line_status)).")" : ""; + $sql .= " GROUP BY c.rowid"; dol_syslog(get_class($this)."::getOtherContracts()", LOG_DEBUG); $resql = $this->db->query($sql); @@ -2460,6 +2466,23 @@ class Contrat extends CommonObject return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + /** + * Function used to replace a product id with another one. + * + * @param DoliDB $db Database handler + * @param int $origin_id Old product id + * @param int $dest_id New product id + * @return bool + */ + public static function replaceProduct(DoliDB $db, $origin_id, $dest_id) + { + $tables = array( + 'contratdet' + ); + + return CommonObject::commonReplaceProduct($db, $origin_id, $dest_id, $tables); + } + /** * Load an object from its id and create a new one in database * @@ -2591,6 +2614,11 @@ class ContratLigne extends CommonObjectLine */ public $table_element = 'contratdet'; + /** + * @var string Name to use for 'features' parameter to check module permissions with restrictedArea() + */ + public $element_for_permission = 'contrat'; + /** * @var int ID */ @@ -2718,11 +2746,40 @@ class ContratLigne extends CommonObjectLine public $commentaire; + const STATUS_INITIAL = 0; const STATUS_OPEN = 4; const STATUS_CLOSED = 5; + // BEGIN MODULEBUILDER PROPERTIES + /** + * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. + */ + public $fields = array( + 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), + 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>30, 'index'=>1), + 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35), + 'qty' =>array('type'=>'integer', 'label'=>'Quantity', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>35, 'isameasure'=>1), + 'total_ht' =>array('type'=>'integer', 'label'=>'AmountHT', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>36, 'isameasure'=>1), + 'total_tva' =>array('type'=>'integer', 'label'=>'AmountVAT', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>37, 'isameasure'=>1), + 'total_ttc' =>array('type'=>'integer', 'label'=>'AmountTTC', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>38, 'isameasure'=>1), + //'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>40), + //'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>70), + 'fk_contrat' =>array('type'=>'integer:Contrat:contrat/class/contrat.class.php', 'label'=>'Contract', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>70), + 'fk_product' =>array('type'=>'integer:Product:product/class/product.class.php:1', 'label'=>'Product', 'enabled'=>1, 'visible'=>-1, 'position'=>75), + //'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>90), + 'note_private' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>105), + 'note_public' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>110), + //'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>115), + //'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>120), + //'extraparams' =>array('type'=>'varchar(255)', 'label'=>'Extraparams', 'enabled'=>1, 'visible'=>-1, 'position'=>125), + 'fk_user_ouverture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserStartingService', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135), + 'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserClosingService', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>135), + 'statut' =>array('type'=>'smallint(6)', 'label'=>'Statut', 'enabled'=>1, 'visible'=>-1, 'position'=>500, 'arrayofkeyval'=>array(0=>'Draft', 4=>'Open', 5=>'Closed')) + ); + // END MODULEBUILDER PROPERTIES + /** * Constructor @@ -2934,7 +2991,6 @@ class ContratLigne extends CommonObjectLine $this->localtax2_type = $obj->localtax2_type; $this->qty = $obj->qty; $this->remise_percent = $obj->remise_percent; - $this->remise = $obj->remise; $this->fk_remise_except = $obj->fk_remise_except; $this->subprice = $obj->subprice; $this->price_ht = $obj->price_ht; @@ -2992,7 +3048,6 @@ class ContratLigne extends CommonObjectLine $this->localtax2_tx = trim($this->localtax2_tx); $this->qty = trim($this->qty); $this->remise_percent = trim($this->remise_percent); - $this->remise = trim($this->remise); $this->fk_remise_except = (int) $this->fk_remise_except; $this->subprice = price2num($this->subprice); $this->price_ht = price2num($this->price_ht); @@ -3157,7 +3212,7 @@ class ContratLigne extends CommonObjectLine if (!$error && !$notrigger) { // Call trigger - $result = $this->call_trigger('LINECONTRACT_UPDATE', $user); + $result = $this->call_trigger('LINECONTRACT_MODIFY', $user); if ($result < 0) { $error++; $this->db->rollback(); diff --git a/htdocs/contrat/index.php b/htdocs/contrat/index.php index 99739260b36..1b9ab289774 100644 --- a/htdocs/contrat/index.php +++ b/htdocs/contrat/index.php @@ -346,22 +346,28 @@ if ($result) { while ($i < $num) { $obj = $db->fetch_object($result); + $datem = $db->jdate($obj->tms); + + $staticcontrat->ref = ($obj->ref ? $obj->ref : $obj->cid); + $staticcontrat->id = $obj->cid; + + $staticcompany->id = $obj->socid; + $staticcompany->name = $obj->name; print ''; print ''; - $staticcontrat->ref = ($obj->ref ? $obj->ref : $obj->cid); - $staticcontrat->id = $obj->cid; print $staticcontrat->getNomUrl(1, 16); if ($obj->nb_late) { print img_warning($langs->trans("Late")); } print ''; - print ''; - $staticcompany->id = $obj->socid; - $staticcompany->name = $obj->name; + + print ''; print $staticcompany->getNomUrl(1, '', 20); print ''; - print ''.dol_print_date($db->jdate($obj->tms), 'dayhour').''; + print ''; + print dol_print_date($datem, 'dayhour'); + print ''; //print ''.$staticcontrat->LibStatut($obj->statut,2).''; print ''.($obj->nb_initial > 0 ? ''.$obj->nb_initial.''.$staticcontratligne->LibStatut(0, 3, -1, 'class="paddingleft"') : '').''; print ''.($obj->nb_running > 0 ? ''.$obj->nb_running.''.$staticcontratligne->LibStatut(4, 3, 0, 'class="marginleft"') : '').''; @@ -439,7 +445,7 @@ if ($resql) { } } print ''; - print ''; + print ''; $staticcompany->id = $obj->fk_soc; $staticcompany->name = $obj->name; print $staticcompany->getNomUrl(1, '', 20); @@ -451,7 +457,7 @@ if ($resql) { print "\n"; $i++; } - $db->free(); + $db->free($resql); print ""; } else { @@ -521,7 +527,7 @@ if ($resql) { } } print ''; - print ''; + print ''; $staticcompany->id = $obj->fk_soc; $staticcompany->name = $obj->name; print $staticcompany->getNomUrl(1, '', 20); @@ -532,7 +538,8 @@ if ($resql) { print "\n"; $i++; } - $db->free(); + + $db->free($resql); print ""; } else { @@ -603,7 +610,7 @@ if ($resql) { } } print ''; - print ''; + print ''; $staticcompany->id = $obj->fk_soc; $staticcompany->name = $obj->name; print $staticcompany->getNomUrl(1, '', 20); @@ -614,7 +621,7 @@ if ($resql) { print "\n"; $i++; } - $db->free(); + $db->free($resql); print ""; } else { diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index 8b00ec2a857..e76261010da 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -203,7 +203,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_date_end = ''; $sall = ""; $search_status = ""; - $toselect = ''; + $toselect = array(); $search_type_thirdparty = ''; $search_array_options = array(); } @@ -312,6 +312,9 @@ if ($search_zip) { if ($search_town) { $sql .= natural_search(array('s.town'), $search_town); } +if ($search_country && $search_country != '-1') { + $sql .= " AND s.fk_pays IN (".$db->sanitize($search_country).')'; +} if ($search_sale > 0) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $search_sale); } @@ -338,23 +341,50 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { } } // Add where from hooks -$parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters); // Note that $action and $object may have been modified by hook +$parameters = array('search_dfyear' => $search_dfyear, 'search_op2df'=>$search_op2df); +$reshook = $hookmanager->executeHooks('printFieldListGroupBy', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; -if ($search_dfyear > 0 && $search_op2df) { - if ($search_op2df == '<=') { - $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear, $search_dfmonth, false))."'"; - } elseif ($search_op2df == '>=') { - $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear, $search_dfmonth, false))."'"; - } else { - $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear, $search_dfmonth, false))."' AND MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear, $search_dfmonth, false))."'"; +// Add HAVING from hooks +$parameters = array('search_dfyear' => $search_dfyear, 'search_op2df'=>$search_op2df); +$reshook = $hookmanager->executeHooks('printFieldListHaving', $parameters, $object); // Note that $action and $object may have been modified by hook +if (empty($reshook)) { + if ($search_dfyear > 0 && $search_op2df) { + if ($search_op2df == '<=') { + $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear, $search_dfmonth, false))."'"; + } elseif ($search_op2df == '>=') { + $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear, $search_dfmonth, false))."'"; + } else { + $sql .= " HAVING MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") <= '".$db->idate(dol_get_last_day($search_dfyear, $search_dfmonth, false))."' AND MIN(".$db->ifsql("cd.statut=4", "cd.date_fin_validite", "null").") >= '".$db->idate(dol_get_first_day($search_dfyear, $search_dfmonth, false))."'"; + } } } +$sql .= $hookmanager->resPrint; $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + //$result = $db->query($sql); + //$nbtotalofrecords = $db->num_rows($result); + + if ($search_dfyear > 0 && $search_op2df) { + $resql = $db->query($sql, 0, 'auto', 1); + while ($db->fetch_object($resql)) { + if (empty($nbtotalofrecords)) { + $nbtotalofrecords = 1; // We can't make +1 because init value is '' + } else { + $nbtotalofrecords++; + } + } + } else { + $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql); + $sqlforcount = preg_replace('/LEFT JOIN '.MAIN_DB_PREFIX.'contratdet as cd ON c.rowid = cd.fk_contrat/', '', $sqlforcount); + $sqlforcount = preg_replace('/LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product=cd.fk_product/', '', $sqlforcount); + $sqlforcount = preg_replace('/AND cp.fk_categorie = '.((int) $search_product_category).'/', '', $sqlforcount); + $sqlforcount = preg_replace('/GROUP BY.*$/', '', $sqlforcount); + + $resql = $db->query($sqlforcount); + $objforcount = $db->fetch_object($resql); + $nbtotalofrecords = $objforcount->nbtotalofrecords; + } if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 $page = 0; @@ -462,6 +492,9 @@ if ($search_user > 0) { if ($search_type_thirdparty > 0) { $param .= '&search_type_thirdparty='.urlencode($search_type_thirdparty); } +if ($search_country != '') { + $param .= "&search_country=".urlencode($search_country); +} if ($search_product_category > 0) { $param .= '&search_product_category='.urlencode($search_product_category); } @@ -523,7 +556,7 @@ if ($sall) { $moreforfilter = ''; // If the user can view prospects other than his' -if ($user->rights->societe->client->voir || $socid) { +if ($user->rights->user->user->lire) { $langs->load("commercial"); $moreforfilter .= '
    '; $tmptitle = $langs->trans('ThirdPartiesOfSaleRepresentative'); @@ -660,7 +693,7 @@ if (!empty($arrayfields['lower_planned_end_date']['checked'])) { print '
    '; print $formother->select_month($search_dfmonth, 'search_dfmonth', 1, 0); print ' '; - $formother->select_year($search_dfyear, 'search_dfyear', 1, 20, 5, 0, 0, ''); + print $formother->selectyear($search_dfyear, 'search_dfyear', 1, 20, 5, 0, 0, ''); print ''; } // Status diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php index 39dfe336a31..1f3ccf70f3a 100644 --- a/htdocs/contrat/services_list.php +++ b/htdocs/contrat/services_list.php @@ -163,7 +163,7 @@ $arrayfields = dol_sort_array($arrayfields, 'position'); if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; } -if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend' && $massaction != 'confirm_createbills') { +if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; } @@ -201,7 +201,7 @@ if (empty($reshook)) { $filter_opcloture = ""; $mode = ''; $filter = ''; - $toselect = ''; + $toselect = array(); $search_array_options = array(); } } @@ -326,25 +326,25 @@ if (!empty($filter_opouvertureprevue) && $filter_opouvertureprevue != -1 && $fil $sql .= " AND cd.date_ouverture_prevue ".$filter_opouvertureprevue." '".$db->idate($filter_dateouvertureprevue_start)."'"; } if (!empty($filter_opouvertureprevue) && $filter_opouvertureprevue == ' BETWEEN ') { - $sql .= " AND '".$db->idate($filter_dateouvertureprevue_end)."'"; + $sql .= " AND cd.date_ouverture_prevue ".$filter_opouvertureprevue." '".$db->idate($filter_dateouvertureprevue_start)."' AND '".$db->idate($filter_dateouvertureprevue_end)."'"; } if (!empty($filter_op1) && $filter_op1 != -1 && $filter_op1 != ' BETWEEN ' && $filter_date1_start != '') { $sql .= " AND cd.date_ouverture ".$filter_op1." '".$db->idate($filter_date1_start)."'"; } if (!empty($filter_op1) && $filter_op1 == ' BETWEEN ') { - $sql .= " AND '".$db->idate($filter_date1_end)."'"; + $sql .= " AND cd.date_ouverture ".$filter_op1." '".$db->idate($filter_date1_start)."' AND '".$db->idate($filter_date1_end)."'"; } if (!empty($filter_op2) && $filter_op2 != -1 && $filter_op2 != ' BETWEEN ' && $filter_date2_start != '') { $sql .= " AND cd.date_fin_validite ".$filter_op2." '".$db->idate($filter_date2_start)."'"; } if (!empty($filter_op2) && $filter_op2 == ' BETWEEN ') { - $sql .= " AND '".$db->idate($filter_date2_end)."'"; + $sql .= " AND cd.date_fin_validite ".$filter_op2." '".$db->idate($filter_date2_start)."' AND '".$db->idate($filter_date2_end)."'"; } if (!empty($filter_opcloture) && $filter_opcloture != ' BETWEEN ' && $filter_opcloture != -1 && $filter_datecloture_start != '') { $sql .= " AND cd.date_cloture ".$filter_opcloture." '".$db->idate($filter_datecloture_start)."'"; } if (!empty($filter_opcloture) && $filter_opcloture == ' BETWEEN ') { - $sql .= " AND '".$db->idate($filter_datecloture_end)."'"; + $sql .= " AND cd.date_cloture ".$filter_opcloture." '".$db->idate($filter_datecloture_start)."' AND '".$db->idate($filter_datecloture_end)."'"; } // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; diff --git a/htdocs/contrat/tpl/linkedobjectblock.tpl.php b/htdocs/contrat/tpl/linkedobjectblock.tpl.php index 1adf43edce3..5f178da19bc 100644 --- a/htdocs/contrat/tpl/linkedobjectblock.tpl.php +++ b/htdocs/contrat/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index 4857902b8cc..b90f3c8ebd0 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -28,8 +28,14 @@ // $permissiontodelete must be defined // $backurlforlist must be defined // $backtopage may be defined +// $noback may be defined // $triggermodname may be defined +$hidedetails = isset($hidedetails) ? $hidedetails : ''; +$hidedesc = isset($hidedesc) ? $hidedesc : ''; +$hideref = isset($hideref) ? $hideref : ''; + + if (!empty($permissionedit) && empty($permissiontoadd)) { $permissiontoadd = $permissionedit; // For backward compatibility } @@ -101,10 +107,10 @@ if ($action == 'add' && !empty($permissiontoadd)) { //var_dump($key.' '.$value.' '.$object->fields[$key]['type']); $object->$key = $value; - if ($val['notnull'] > 0 && $object->$key == '' && !is_null($val['default']) && $val['default'] == '(PROV)') { + if (!empty($val['notnull']) && $val['notnull'] > 0 && $object->$key == '' && isset($val['default']) && $val['default'] == '(PROV)') { $object->$key = '(PROV)'; } - if ($val['notnull'] > 0 && $object->$key == '' && is_null($val['default'])) { + if (!empty($val['notnull']) && $val['notnull'] > 0 && $object->$key == '' && !isset($val['default'])) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv($val['label'])), null, 'errors'); } @@ -121,7 +127,7 @@ if ($action == 'add' && !empty($permissiontoadd)) { // Fill array 'array_options' with data from add form if (!$error) { - $ret = $extrafields->setOptionalsFromPost(null, $object); + $ret = $extrafields->setOptionalsFromPost(null, $object, '', 1); if ($ret < 0) { $error++; } @@ -137,8 +143,11 @@ if ($action == 'add' && !empty($permissiontoadd)) { } $urltogo = $backtopage ? str_replace('__ID__', $result, $backtopage) : $backurlforlist; $urltogo = preg_replace('/--IDFORBACKTOPAGE--/', $object->id, $urltogo); // New method to autoselect project after a New on another form object creation - header("Location: ".$urltogo); - exit; + + if (!empty($noback)) { + header("Location: " . $urltogo); + exit; + } } else { $error++; // Creation KO @@ -255,6 +264,12 @@ if ($action == 'update' && !empty($permissiontoadd)) { $result = $object->update($user); if ($result > 0) { $action = 'view'; + $urltogo = $backtopage ? str_replace('__ID__', $result, $backtopage) : $backurlforlist; + $urltogo = preg_replace('/--IDFORBACKTOPAGE--/', $object->id, $urltogo); // New method to autoselect project after a New on another form object creation + if ($urltogo) { + header("Location: " . $urltogo); + exit; + } } else { $error++; // Creation KO @@ -305,8 +320,10 @@ if ($action == 'confirm_delete' && !empty($permissiontodelete)) { // Delete OK setEventMessages("RecordDeleted", null, 'mesgs'); - header("Location: ".$backurlforlist); - exit; + if (!empty($noback)) { + header("Location: " . $backurlforlist); + exit; + } } else { $error++; if (!empty($object->errors)) { @@ -349,8 +366,10 @@ if ($action == 'confirm_deleteline' && $confirm == 'yes' && !empty($permissionto setEventMessages($langs->trans('RecordDeleted'), null, 'mesgs'); - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id); - exit; + if (!empty($noback)) { + header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id); + exit; + } } else { $error++; setEventMessages($object->error, $object->errors, 'errors'); @@ -367,10 +386,10 @@ if ($action == 'confirm_validate' && $confirm == 'yes' && $permissiontoadd) { if (method_exists($object, 'generateDocument')) { $outputlangs = $langs; $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { + if (!empty($conf->global->MAIN_MULTILANGS) && empty($newlang) && GETPOST('lang_id', 'aZ09')) { $newlang = GETPOST('lang_id', 'aZ09'); } - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) { + if (!empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) { $newlang = $object->thirdparty->default_lang; } if (!empty($newlang)) { @@ -488,8 +507,10 @@ if ($action == 'confirm_clone' && $confirm == 'yes' && !empty($permissiontoadd)) $newid = $result; } - header("Location: ".$_SERVER['PHP_SELF'].'?id='.$newid); // Open record of new object - exit; + if (!empty($noback)) { + header("Location: " . $_SERVER['PHP_SELF'] . '?id=' . $newid); // Open record of new object + exit; + } } else { $error++; setEventMessages($objectutil->error, $objectutil->errors, 'errors'); diff --git a/htdocs/core/actions_extrafields.inc.php b/htdocs/core/actions_extrafields.inc.php index 1ca04a00c8b..7a7ab380e29 100644 --- a/htdocs/core/actions_extrafields.inc.php +++ b/htdocs/core/actions_extrafields.inc.php @@ -147,11 +147,12 @@ if ($action == 'add') { if (!$error) { // attrname must be alphabetical and lower case only - if (GETPOSTISSET("attrname") && preg_match("/^[a-z0-9-_]+$/", GETPOST('attrname', 'aZ09')) && !is_numeric(GETPOST('attrname', 'aZ09'))) { + if (GETPOSTISSET("attrname") && preg_match("/^[a-z0-9_]+$/", GETPOST('attrname', 'aZ09')) && !is_numeric(GETPOST('attrname', 'aZ09'))) { // Construct array for parameter (value of select list) $default_value = GETPOST('default_value', 'alpha'); $parameters = $param; $parameters_array = explode("\r\n", $parameters); + $params = array(); //In sellist we have only one line and it can have come to do SQL expression if ($type == 'sellist' || $type == 'chkbxlst') { foreach ($parameters_array as $param_ligne) { @@ -161,6 +162,9 @@ if ($action == 'add') { // Else it's separated key/value and coma list foreach ($parameters_array as $param_ligne) { list($key, $value) = explode(',', $param_ligne); + if (!array_key_exists('options', $params)) { + $params['options'] = array(); + } $params['options'][$key] = $value; } } @@ -183,7 +187,7 @@ if ($action == 'add') { $default_value, $params, (GETPOST('alwayseditable', 'alpha') ? 1 : 0), - (GETPOST('perms', 'alpha') ?GETPOST('perms', 'alpha') : ''), + (GETPOST('perms', 'alpha') ? GETPOST('perms', 'alpha') : ''), $visibility, GETPOST('help', 'alpha'), GETPOST('computed_value', 'alpha'), @@ -315,6 +319,7 @@ if ($action == 'update') { // Construct array for parameter (value of select list) $parameters = $param; $parameters_array = explode("\r\n", $parameters); + $params = array(); //In sellist we have only one line and it can have come to do SQL expression if ($type == 'sellist' || $type == 'chkbxlst') { foreach ($parameters_array as $param_ligne) { @@ -324,6 +329,9 @@ if ($action == 'update') { //Esle it's separated key/value and coma list foreach ($parameters_array as $param_ligne) { list($key, $value) = explode(',', $param_ligne); + if (!array_key_exists('options', $params)) { + $params['options'] = array(); + } $params['options'][$key] = $value; } } diff --git a/htdocs/core/actions_fetchobject.inc.php b/htdocs/core/actions_fetchobject.inc.php index 3ca797a9bb3..b73f6adbae8 100644 --- a/htdocs/core/actions_fetchobject.inc.php +++ b/htdocs/core/actions_fetchobject.inc.php @@ -30,7 +30,7 @@ if (($id > 0 || (!empty($ref) && !in_array($action, array('create', 'createtask', 'add')))) && (empty($cancel) || $id > 0)) { if (($id > 0 && is_numeric($id)) || !empty($ref)) { // To discard case when id is list of ids like '1,2,3...' - $ret = $object->fetch($id, $ref); + $ret = $object->fetch($id, (empty($ref)? '' : $ref)); if ($ret > 0) { $object->fetch_thirdparty(); $id = $object->id; diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 5e803ae3cdf..5acc6b22ee2 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -90,7 +90,7 @@ if (!$error && $massaction == 'confirm_presend') { if ($objecttmp->element == 'expensereport') { $thirdparty = new User($db); } - if ($objecttmp->element == 'partnership' && $conf->global->PARTNERSHIP_IS_MANAGED_FOR == 'member') { + if ($objecttmp->element == 'partnership' && getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR') == 'member') { $thirdparty = new Adherent($db); } if ($objecttmp->element == 'holiday') { @@ -110,7 +110,7 @@ if (!$error && $massaction == 'confirm_presend') { if ($objecttmp->element == 'expensereport') { $thirdpartyid = $objecttmp->fk_user_author; } - if ($objecttmp->element == 'partnership' && $conf->global->PARTNERSHIP_IS_MANAGED_FOR == 'member') { + if ($objecttmp->element == 'partnership' && getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR') == 'member') { $thirdpartyid = $objecttmp->fk_member; } if ($objecttmp->element == 'holiday') { @@ -128,6 +128,14 @@ if (!$error && $massaction == 'confirm_presend') { $listofobjectcontacts[$toselectid][$data_email['id']] = $data_email['email']; } } + } elseif ($objectclass == 'CommandeFournisseur') { + $tmparraycontact = array(); + $tmparraycontact = $objecttmp->liste_contact(-1, 'external', 0, 'CUSTOMER'); + if (is_array($tmparraycontact) && count($tmparraycontact) > 0) { + foreach ($tmparraycontact as $data_email) { + $listofobjectcontacts[$toselectid][$data_email['id']] = $data_email['email']; + } + } } $listofobjectthirdparties[$thirdpartyid] = $thirdpartyid; @@ -143,7 +151,7 @@ if (!$error && $massaction == 'confirm_presend') { $massaction = 'presend'; } - $receiver = $_POST['receiver']; + $receiver = GETPOST('receiver', 'alphawithlgt'); if (!is_array($receiver)) { if (empty($receiver) || $receiver == '-1') { $receiver = array(); @@ -181,7 +189,7 @@ if (!$error && $massaction == 'confirm_presend') { $tmparray = array(); if (trim($_POST['sendto'])) { // Recipients are provided into free text - $tmparray[] = trim($_POST['sendto']); + $tmparray[] = trim(GETPOST('sendto', 'alphawithlgt')); } if (count($receiver) > 0) { foreach ($receiver as $key => $val) { @@ -197,7 +205,7 @@ if (!$error && $massaction == 'confirm_presend') { $sendto = implode(',', $tmparray); // Define $sendtocc - $receivercc = $_POST['receivercc']; + $receivercc = GETPOST('receivercc', 'alphawithlgt'); if (!is_array($receivercc)) { if ($receivercc == '-1') { $receivercc = array(); @@ -207,7 +215,7 @@ if (!$error && $massaction == 'confirm_presend') { } $tmparray = array(); if (trim($_POST['sendtocc'])) { - $tmparray[] = trim($_POST['sendtocc']); + $tmparray[] = trim(GETPOST('sendtocc', 'alphawithlgt')); } if (count($receivercc) > 0) { foreach ($receivercc as $key => $val) { @@ -256,7 +264,7 @@ if (!$error && $massaction == 'confirm_presend') { $fuser = new User($db); $fuser->fetch($objectobj->fk_user_author); $sendto = $fuser->email; - } elseif ($objectobj->element == 'partnership' && $conf->global->PARTNERSHIP_IS_MANAGED_FOR == 'member') { + } elseif ($objectobj->element == 'partnership' && getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR') == 'member') { $fadherent = new Adherent($db); $fadherent->fetch($objectobj->fk_member); $sendto = $fadherent->email; @@ -277,6 +285,19 @@ if (!$error && $massaction == 'confirm_presend') { if (count($emails_to_sends) > 0) { $sendto = implode(',', $emails_to_sends); } + } elseif ($objectobj->element == 'order_supplier' && !empty($listofobjectcontacts[$objectid])) { + $emails_to_sends = array(); + $objectobj->fetch_thirdparty(); + $contactidtosend = array(); + foreach ($listofobjectcontacts[$objectid] as $contactemailid => $contactemailemail) { + $emails_to_sends[] = $objectobj->thirdparty->contact_get_property($contactemailid, 'email'); + if (!in_array($contactemailid, $contactidtosend)) { + $contactidtosend[] = $contactemailid; + } + } + if (count($emails_to_sends) > 0) { + $sendto = implode(',', $emails_to_sends); + } } else { $objectobj->fetch_thirdparty(); $sendto = $objectobj->thirdparty->email; @@ -298,7 +319,7 @@ if (!$error && $massaction == 'confirm_presend') { continue; } - if ($_POST['addmaindocfile']) { + if (GETPOST('addmaindocfile')) { // TODO Use future field $objectobj->fullpathdoc to know where is stored default file // TODO If not defined, use $objectobj->model_pdf (or defaut invoice config) to know what is template to use to regenerate doc. $filename = dol_sanitizeFileName($objectobj->ref).'.pdf'; @@ -306,29 +327,51 @@ if (!$error && $massaction == 'confirm_presend') { // TODO Set subdir to be compatible with multi levels dir trees // $subdir = get_exdir($objectobj->id, 2, 0, 0, $objectobj, $objectobj->element) $filedir = $uploaddir.'/'.$subdir.dol_sanitizeFileName($objectobj->ref); - $file = $filedir.'/'.$filename; + $filepath = $filedir.'/'.$filename; // For supplier invoices, we use the file provided by supplier, not the one we generate if ($objectobj->element == 'invoice_supplier') { $fileparams = dol_most_recent_file($uploaddir.'/'.get_exdir($objectobj->id, 2, 0, 0, $objectobj, $objectobj->element).$objectobj->ref, preg_quote($objectobj->ref, '/').'([^\-])+'); - $file = $fileparams['fullname']; + $filepath = $fileparams['fullname']; } - $mime = dol_mimetype($file); + // try to find other files generated for this object (last_main_doc) + $filename_found = ''; + $filepath_found = ''; + $file_check_list = array(); + $file_check_list[] = array( + 'name' => $filename, + 'path' => $filepath, + ); + if (!empty($conf->global->MAIL_MASS_ACTION_ADD_LAST_IF_MAIN_DOC_NOT_FOUND) && !empty($objectobj->last_main_doc)) { + $file_check_list[] = array( + 'name' => basename($objectobj->last_main_doc), + 'path' => DOL_DATA_ROOT . '/' . $objectobj->last_main_doc, + ); + } + foreach ($file_check_list as $file_check_arr) { + if (dol_is_file($file_check_arr['path'])) { + $filename_found = $file_check_arr['name']; + $filepath_found = $file_check_arr['path']; + break; + } + } - if (dol_is_file($file)) { + if ($filepath_found) { // Create form object $attachedfilesThirdpartyObj[$thirdpartyid][$objectid] = array( - 'paths'=>array($file), - 'names'=>array($filename), - 'mimes'=>array($mime) + 'paths'=>array($filepath_found), + 'names'=>array($filename_found), + 'mimes'=>array(dol_mimetype($filepath_found)) ); } else { - $nbignored++; - $langs->load("errors"); - $resaction .= '
    '.$langs->trans('ErrorCantReadFile', $file).'

    '; - dol_syslog('Failed to read file: '.$file, LOG_WARNING); - continue; + $nbignored++; + $langs->load("errors"); + foreach ($file_check_list as $file_check_arr) { + $resaction .= '
    '.$langs->trans('ErrorCantReadFile', $file_check_arr['path']).'

    '; + dol_syslog('Failed to read file: '.$file_check_arr['path'], LOG_WARNING); + } + continue; } } @@ -347,7 +390,7 @@ if (!$error && $massaction == 'confirm_presend') { $reg = array(); $fromtype = GETPOST('fromtype'); if ($fromtype === 'user') { - $from = $user->getFullName($langs).' <'.$user->email.'>'; + $from = dol_string_nospecial($user->getFullName($langs), ' ', array(",")).' <'.$user->email.'>'; } elseif ($fromtype === 'company') { $from = $conf->global->MAIN_INFO_SOCIETE_NOM.' <'.$conf->global->MAIN_INFO_SOCIETE_MAIL.'>'; } elseif (preg_match('/user_aliases_(\d+)/', $fromtype, $reg)) { @@ -361,10 +404,10 @@ if (!$error && $massaction == 'confirm_presend') { $resql = $db->query($sql); $obj = $db->fetch_object($resql); if ($obj) { - $from = $obj->label.' <'.$obj->email.'>'; + $from = dol_string_nospecial($obj->label, ' ', array(",")).' <'.$obj->email.'>'; } } else { - $from = $_POST['fromname'].' <'.$_POST['frommail'].'>'; + $from = GETPOST('fromname').' <'.GETPOST('frommail').'>'; } $replyto = $from; @@ -625,338 +668,6 @@ if (!$error && $massaction == 'confirm_presend') { } } -// TODO Move this action into commande/list.php if called only by this page. -if ($massaction == 'confirm_createbills') { // Create bills from orders. - $orders = GETPOST('toselect', 'array'); - $createbills_onebythird = GETPOST('createbills_onebythird', 'int'); - $validate_invoices = GETPOST('validate_invoices', 'int'); - - $errors = array(); - - $TFact = array(); - $TFactThird = array(); - - $nb_bills_created = 0; - $lastid= 0; - $lastref = ''; - - $db->begin(); - - foreach ($orders as $id_order) { - $cmd = new Commande($db); - if ($cmd->fetch($id_order) <= 0) { - continue; - } - $cmd->fetch_thirdparty(); - - $objecttmp = new Facture($db); - if (!empty($createbills_onebythird) && !empty($TFactThird[$cmd->socid])) { - // If option "one bill per third" is set, and an invoice for this thirdparty was already created, we re-use it. - $objecttmp = $TFactThird[$cmd->socid]; - } else { - // If we want one invoice per order or if there is no first invoice yet for this thirdparty. - $objecttmp->socid = $cmd->socid; - $objecttmp->type = $objecttmp::TYPE_STANDARD; - $objecttmp->cond_reglement_id = !empty($cmd->cond_reglement_id) ? $cmd->cond_reglement_id : $cmd->thirdparty->cond_reglement_id; - $objecttmp->mode_reglement_id = !empty($cmd->mode_reglement_id) ? $cmd->mode_reglement_id : $cmd->thirdparty->mode_reglement_id; - - $objecttmp->fk_project = $cmd->fk_project; - $objecttmp->multicurrency_code = $cmd->multicurrency_code; - if (empty($createbills_onebythird)) { - $objecttmp->ref_client = $cmd->ref_client; - } - - $datefacture = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); - if (empty($datefacture)) { - $datefacture = dol_now(); - } - - $objecttmp->date = $datefacture; - $objecttmp->origin = 'commande'; - $objecttmp->origin_id = $id_order; - - $objecttmp->array_options = $cmd->array_options; // Copy extrafields - - $res = $objecttmp->create($user); - - if ($res > 0) { - $nb_bills_created++; - $lastref = $objecttmp->ref; - $lastid = $objecttmp->id; - - $TFactThird[$cmd->socid] = $objecttmp; - } else { - $langs->load("errors"); - $errors[] = $cmd->ref.' : '.$langs->trans($objecttmp->error); - $error++; - } - } - - if ($objecttmp->id > 0) { - $res = $objecttmp->add_object_linked($objecttmp->origin, $id_order); - - if ($res == 0) { - $errors[] = $objecttmp->error; - $error++; - } - - if (!$error) { - $lines = $cmd->lines; - if (empty($lines) && method_exists($cmd, 'fetch_lines')) { - $cmd->fetch_lines(); - $lines = $cmd->lines; - } - - $fk_parent_line = 0; - $num = count($lines); - - for ($i = 0; $i < $num; $i++) { - $desc = ($lines[$i]->desc ? $lines[$i]->desc : ''); - // If we build one invoice for several orders, we must put the ref of order on the invoice line - if (!empty($createbills_onebythird)) { - $desc = dol_concatdesc($desc, $langs->trans("Order").' '.$cmd->ref.' - '.dol_print_date($cmd->date, 'day')); - } - - if ($lines[$i]->subprice < 0) { - // Negative line, we create a discount line - $discount = new DiscountAbsolute($db); - $discount->fk_soc = $objecttmp->socid; - $discount->amount_ht = abs($lines[$i]->total_ht); - $discount->amount_tva = abs($lines[$i]->total_tva); - $discount->amount_ttc = abs($lines[$i]->total_ttc); - $discount->tva_tx = $lines[$i]->tva_tx; - $discount->fk_user = $user->id; - $discount->description = $desc; - $discountid = $discount->create($user); - if ($discountid > 0) { - $result = $objecttmp->insert_discount($discountid); - //$result=$discount->link_to_invoice($lineid,$id); - } else { - setEventMessages($discount->error, $discount->errors, 'errors'); - $error++; - break; - } - } else { - // Positive line - $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0); - // Date start - $date_start = false; - if ($lines[$i]->date_debut_prevue) { - $date_start = $lines[$i]->date_debut_prevue; - } - if ($lines[$i]->date_debut_reel) { - $date_start = $lines[$i]->date_debut_reel; - } - if ($lines[$i]->date_start) { - $date_start = $lines[$i]->date_start; - } - //Date end - $date_end = false; - if ($lines[$i]->date_fin_prevue) { - $date_end = $lines[$i]->date_fin_prevue; - } - if ($lines[$i]->date_fin_reel) { - $date_end = $lines[$i]->date_fin_reel; - } - if ($lines[$i]->date_end) { - $date_end = $lines[$i]->date_end; - } - // Reset fk_parent_line for no child products and special product - if (($lines[$i]->product_type != 9 && empty($lines[$i]->fk_parent_line)) || $lines[$i]->product_type == 9) { - $fk_parent_line = 0; - } - - // Extrafields - if (method_exists($lines[$i], 'fetch_optionals')) { - $lines[$i]->fetch_optionals(); - $array_options = $lines[$i]->array_options; - } - - $objecttmp->context['createfromclone']; - - $result = $objecttmp->addline( - $desc, - $lines[$i]->subprice, - $lines[$i]->qty, - $lines[$i]->tva_tx, - $lines[$i]->localtax1_tx, - $lines[$i]->localtax2_tx, - $lines[$i]->fk_product, - $lines[$i]->remise_percent, - $date_start, - $date_end, - 0, - $lines[$i]->info_bits, - $lines[$i]->fk_remise_except, - 'HT', - 0, - $product_type, - $lines[$i]->rang, - $lines[$i]->special_code, - $objecttmp->origin, - $lines[$i]->rowid, - $fk_parent_line, - $lines[$i]->fk_fournprice, - $lines[$i]->pa_ht, - $lines[$i]->label, - $array_options, - 100, - 0, - $lines[$i]->fk_unit - ); - if ($result > 0) { - $lineid = $result; - } else { - $lineid = 0; - $error++; - break; - } - // Defined the new fk_parent_line - if ($result > 0 && $lines[$i]->product_type == 9) { - $fk_parent_line = $result; - } - } - } - } - } - - //$cmd->classifyBilled($user); // Disabled. This behavior must be set or not using the workflow module. - - if (!empty($createbills_onebythird) && empty($TFactThird[$cmd->socid])) { - $TFactThird[$cmd->socid] = $objecttmp; - } else { - $TFact[$objecttmp->id] = $objecttmp; - } - } - - // Build doc with all invoices - $TAllFact = empty($createbills_onebythird) ? $TFact : $TFactThird; - $toselect = array(); - - if (!$error && $validate_invoices) { - $massaction = $action = 'builddoc'; - - foreach ($TAllFact as &$objecttmp) { - $result = $objecttmp->validate($user); - if ($result <= 0) { - $error++; - setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); - break; - } - - $id = $objecttmp->id; // For builddoc action - - // Builddoc - $donotredirect = 1; - $upload_dir = $conf->facture->dir_output; - $permissiontoadd = $user->rights->facture->creer; - - // Call action to build doc - $savobject = $object; - $object = $objecttmp; - include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; - $object = $savobject; - } - - $massaction = $action = 'confirm_createbills'; - } - - if (!$error) { - $db->commit(); - - if ($nb_bills_created == 1) { - $texttoshow = $langs->trans('BillXCreated', '{s1}'); - $texttoshow = str_replace('{s1}', ''.$lastref.'', $texttoshow); - setEventMessages($texttoshow, null, 'mesgs'); - } else { - setEventMessages($langs->trans('BillCreated', $nb_bills_created), null, 'mesgs'); - } - - // Make a redirect to avoid to bill twice if we make a refresh or back - $param = ''; - if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { - $param .= '&contextpage='.urlencode($contextpage); - } - if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); - } - if ($sall) { - $param .= '&sall='.urlencode($sall); - } - if ($socid > 0) { - $param .= '&socid='.urlencode($socid); - } - if ($search_status != '') { - $param .= '&search_status='.urlencode($search_status); - } - if ($search_orderday) { - $param .= '&search_orderday='.urlencode($search_orderday); - } - if ($search_ordermonth) { - $param .= '&search_ordermonth='.urlencode($search_ordermonth); - } - if ($search_orderyear) { - $param .= '&search_orderyear='.urlencode($search_orderyear); - } - if ($search_deliveryday) { - $param .= '&search_deliveryday='.urlencode($search_deliveryday); - } - if ($search_deliverymonth) { - $param .= '&search_deliverymonth='.urlencode($search_deliverymonth); - } - if ($search_deliveryyear) { - $param .= '&search_deliveryyear='.urlencode($search_deliveryyear); - } - if ($search_ref) { - $param .= '&search_ref='.urlencode($search_ref); - } - if ($search_company) { - $param .= '&search_company='.urlencode($search_company); - } - if ($search_ref_customer) { - $param .= '&search_ref_customer='.urlencode($search_ref_customer); - } - if ($search_user > 0) { - $param .= '&search_user='.urlencode($search_user); - } - if ($search_sale > 0) { - $param .= '&search_sale='.urlencode($search_sale); - } - if ($search_total_ht != '') { - $param .= '&search_total_ht='.urlencode($search_total_ht); - } - if ($search_total_vat != '') { - $param .= '&search_total_vat='.urlencode($search_total_vat); - } - if ($search_total_ttc != '') { - $param .= '&search_total_ttc='.urlencode($search_total_ttc); - } - if ($search_project_ref >= 0) { - $param .= "&search_project_ref=".urlencode($search_project_ref); - } - if ($show_files) { - $param .= '&show_files='.urlencode($show_files); - } - if ($optioncss != '') { - $param .= '&optioncss='.urlencode($optioncss); - } - if ($billed != '') { - $param .= '&billed='.urlencode($billed); - } - - header("Location: ".$_SERVER['PHP_SELF'].'?'.$param); - exit; - } else { - $db->rollback(); - - $action = 'create'; - $_GET["origin"] = $_POST["origin"]; - $_GET["originid"] = $_POST["originid"]; - setEventMessages("Error", null, 'errors'); - $error++; - } -} - if (!$error && $massaction == 'cancelorders') { $db->begin(); @@ -1209,6 +920,26 @@ if (!$error && $massaction == 'validate' && $permissiontoadd) { setEventMessages($langs->trans('ErrorMassValidationNotAllowedWhenStockIncreaseOnAction'), null, 'errors'); $error++; } + if ($objecttmp->element == 'facture') { + if (!empty($toselect) && !empty($conf->global->INVOICE_CHECK_POSTERIOR_DATE)) { + // order $toselect by date + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture"; + $sql .= " WHERE rowid IN (".$db->sanitize(implode(",", $toselect)).")"; + $sql .= " ORDER BY datef"; + + $resql = $db->query($sql); + if ($resql) { + $toselectnew = []; + while ( !empty($arr = $db->fetch_row($resql))) { + $toselectnew[] = $arr[0]; + } + $toselect = (empty($toselectnew)) ? $toselect : $toselectnew; + } else { + dol_print_error($db); + $error++; + } + } + } if (!$error) { $db->begin(); @@ -1571,6 +1302,87 @@ if (!$error && ($massaction == 'disable' || ($action == 'disable' && $confirm == } } +if (!$error && $action == 'confirm_edit_value_extrafields' && $confirm == 'yes' && $permissiontoadd) { + $db->begin(); + + $objecttmp = new $objectclass($db); + $e = new ExtraFields($db);// fetch optionals attributes and labels + $e->fetch_name_optionals_label($objecttmp->table_element); + + $nbok = 0; + $extrafieldKeyToUpdate = GETPOST('extrafield-key-to-update'); + + + foreach ($toselect as $toselectid) { + /** @var CommonObject $objecttmp */ + $objecttmp = new $objectclass($db); // to avoid ghost data + $result = $objecttmp->fetch($toselectid); + if ($result>0) { + // Fill array 'array_options' with data from add form + $ret = $e->setOptionalsFromPost(null, $objecttmp, $extrafieldKeyToUpdate); + if ($ret > 0) { + $objecttmp->insertExtraFields(); + } else { + $error++; + setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); + } + } else { + setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); + $error++; + break; + } + } + + if (!$error) { + if ($nbok > 1) { + setEventMessages($langs->trans("RecordsDisabled", $nbok), null, 'mesgs'); + } else { + setEventMessages($langs->trans("save"), null, 'mesgs'); + } + $db->commit(); + } else { + $db->rollback(); + } +} + +if (!$error && ($massaction == 'affectcommercial' || ($action == 'affectcommercial' && $confirm == 'yes')) && $permissiontoadd) { + $db->begin(); + + $objecttmp = new $objectclass($db); + $nbok = 0; + + foreach ($toselect as $toselectid) { + $result = $objecttmp->fetch($toselectid); + if ($result>0) { + if (in_array($objecttmp->element, array('societe'))) { + $result = $objecttmp->setSalesRep(GETPOST("commercial", "alpha")); + } + if ($result <= 0) { + setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); + $error++; + break; + } else { + $nbok++; + } + } else { + setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); + $error++; + break; + } + } + + if (!$error) { + if ($nbok > 1) { + setEventMessages($langs->trans("CommercialsAffected", $nbok), null, 'mesgs'); + } else { + setEventMessages($langs->trans("CommercialAffected"), null, 'mesgs'); + } + $db->commit(); + } else { + $db->rollback(); + } +} + // Approve for leave only if (!$error && ($massaction == 'approveleave' || ($action == 'approveleave' && $confirm == 'yes')) && $permissiontoapprove) { $db->begin(); diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index 55416354441..f0ef66eb78b 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -49,7 +49,7 @@ if (GETPOST('addfile', 'alpha')) { /* * Remove file in email form */ -if (!empty($_POST['removedfile']) && empty($_POST['removAll'])) { +if (GETPOST('removedfile') && !GETPOST('removAll')) { $trackid = GETPOST('trackid', 'aZ09'); require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; @@ -103,13 +103,13 @@ if (GETPOST('removAll', 'alpha')) { /* * Send mail */ -if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST['removAll'] && !$_POST['removedfile'] && !$_POST['cancel'] && !$_POST['modelselected']) { +if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPOST('removAll') && !GETPOST('removedfile') && !GETPOST('cancel') && !GETPOST('modelselected')) { if (empty($trackid)) { $trackid = GETPOST('trackid', 'aZ09'); } $subject = ''; - $actionmsg = ''; + //$actionmsg = ''; $actionmsg2 = ''; $langs->load('mails'); @@ -171,7 +171,7 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST $sendtoccuserid = array(); // Define $sendto - $receiver = $_POST['receiver']; + $receiver = GETPOST('receiver', 'alphawithlgt'); if (!is_array($receiver)) { if ($receiver == '-1') { $receiver = array(); @@ -183,12 +183,12 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST $tmparray = array(); if (trim($_POST['sendto'])) { // Recipients are provided into free text field - $tmparray[] = trim($_POST['sendto']); + $tmparray[] = trim(GETPOST('sendto', 'alphawithlgt')); } if (trim($_POST['tomail'])) { // Recipients are provided into free hidden text field - $tmparray[] = trim($_POST['tomail']); + $tmparray[] = trim(GETPOST('tomail', 'alphawithlgt')); } if (count($receiver) > 0) { @@ -207,7 +207,7 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST } if (!empty($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT)) { - $receiveruser = $_POST['receiveruser']; + $receiveruser = GETPOST('receiveruser', 'alphawithlgt'); if (is_array($receiveruser) && count($receiveruser) > 0) { $fuserdest = new User($db); foreach ($receiveruser as $key => $val) { @@ -220,7 +220,7 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST $sendto = implode(',', $tmparray); // Define $sendtocc - $receivercc = $_POST['receivercc']; + $receivercc = GETPOST('receivercc', 'alphawithlgt'); if (!is_array($receivercc)) { if ($receivercc == '-1') { $receivercc = array(); @@ -230,7 +230,7 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST } $tmparray = array(); if (trim($_POST['sendtocc'])) { - $tmparray[] = trim($_POST['sendtocc']); + $tmparray[] = trim(GETPOST('sendtocc', 'alphawithlgt')); } if (count($receivercc) > 0) { foreach ($receivercc as $key => $val) { @@ -248,7 +248,7 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST } } if (!empty($conf->global->MAIN_MAIL_ENABLED_USER_DEST_SELECT)) { - $receiverccuser = $_POST['receiverccuser']; + $receiverccuser = GETPOST('receiverccuser', 'alphawithlgt'); if (is_array($receiverccuser) && count($receiverccuser) > 0) { $fuserdest = new User($db); @@ -293,10 +293,10 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST $from = dol_string_nospecial($obj->label, ' ', array(",")).' <'.$obj->email.'>'; } } else { - $from = dol_string_nospecial($_POST['fromname'], ' ', array(",")).' <'.$_POST['frommail'].'>'; + $from = dol_string_nospecial(GETPOST('fromname'), ' ', array(",")).' <'.GETPOST('frommail').'>'; } - $replyto = dol_string_nospecial($_POST['replytoname'], ' ', array(",")).' <'.$_POST['replytomail'].'>'; + $replyto = dol_string_nospecial(GETPOST('replytoname'), ' ', array(",")).' <'.GETPOST('replytomail').'>'; $message = GETPOST('message', 'restricthtml'); $subject = GETPOST('subject', 'restricthtml'); @@ -313,11 +313,11 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST $sendtobcc .= (empty($conf->global->$autocopy) ? '' : (($sendtobcc ? ", " : "").$conf->global->$autocopy)); } - $deliveryreceipt = $_POST['deliveryreceipt']; + $deliveryreceipt = GETPOST('deliveryreceipt'); if ($action == 'send' || $action == 'relance') { $actionmsg2 = $langs->transnoentities('MailSentBy').' '.CMailFile::getValidAddress($from, 4, 0, 1).' '.$langs->transnoentities('To').' '.CMailFile::getValidAddress($sendto, 4, 0, 1); - if ($message) { + /*if ($message) { $actionmsg = $langs->transnoentities('MailFrom').': '.dol_escape_htmltag($from); $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($sendto)); if ($sendtocc) { @@ -326,7 +326,7 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic').": ".$subject); $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody').":"); $actionmsg = dol_concatdesc($actionmsg, $message); - } + }*/ } // Create form object @@ -376,7 +376,7 @@ if (($action == 'send' || $action == 'relance') && !$_POST['addfile'] && !$_POST $object->socid = $sendtosocid; // To link to a company $object->sendtoid = $sendtoid; // To link to contact-addresses. This is an array. $object->actiontypecode = $actiontypecode; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...) - $object->actionmsg = $actionmsg; // Long text (@todo Replace this with $message, we already have details of email in dedicated properties) + $object->actionmsg = $message; // Long text $object->actionmsg2 = $actionmsg2; // Short text ($langs->transnoentities('MailSentBy')...); $object->trackid = $trackid; diff --git a/htdocs/core/ajax/ajaxcompanies.php b/htdocs/core/ajax/ajaxcompanies.php new file mode 100644 index 00000000000..350f03398aa --- /dev/null +++ b/htdocs/core/ajax/ajaxcompanies.php @@ -0,0 +1,122 @@ + + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2007-2010 Laurent Destailleur + * Copyright (C) 2010 Cyrille de Lambert + * + * 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 . + */ + +/** + * \file htdocs/core/ajax/ajaxcompanies.php + * \brief File to return Ajax response on third parties request + */ + +if (!defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', 1); // Disables token renewal +if (!defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); +if (!defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); +if (!defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); +if (!defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); +if (!defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1'); + +require '../../main.inc.php'; + + +/* + * View + */ + +// Ajout directives pour resoudre bug IE +//header('Cache-Control: Public, must-revalidate'); +//header('Pragma: public'); + +//top_htmlhead("", "", 1); // Replaced with top_httphead. An ajax page does not need html header. +top_httphead(); + +//print ''."\n"; + +dol_syslog(join(',', $_GET)); + + +// Generation liste des societes +if (GETPOST('newcompany') || GETPOST('socid', 'int') || GETPOST('id_fourn')) { + $return_arr = array(); + + // Define filter on text typed + $socid = $_GET['newcompany'] ? $_GET['newcompany'] : ''; + if (!$socid) $socid = $_GET['socid'] ? $_GET['socid'] : ''; + if (!$socid) $socid = $_GET['id_fourn'] ? $_GET['id_fourn'] : ''; + + $sql = "SELECT s.rowid, s.nom, s.name_alias, s.code_client, s.code_fournisseur, s.address, s.zip, s.town, s.email, s.siren, s.siret, s.ape, s.idprof4, s.client, s.fournisseur, s.datec, s.logo"; + $sql .= " , c.label as country, d.nom as departement"; + $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = s.fk_pays"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as d ON d.rowid = s.fk_departement"; + $sql .= " WHERE s.entity IN (".getEntity('societe').")"; + if ($socid) { + $sql .= " AND ("; + // Add criteria on name/code + if (!empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)) { // Can use index + $sql .= "s.nom LIKE '".$db->escape($socid)."%'"; + $sql .= " OR s.code_client LIKE '".$db->escape($socid)."%'"; + $sql .= " OR s.code_fournisseur LIKE '".$db->escape($socid)."%'"; + } else { + $sql .= "s.nom LIKE '%".$db->escape($socid)."%'"; + $sql .= " OR s.code_client LIKE '%".$db->escape($socid)."%'"; + $sql .= " OR s.code_fournisseur LIKE '%".$db->escape($socid)."%'"; + } + if (!empty($conf->global->SOCIETE_ALLOW_SEARCH_ON_ROWID)) $sql .= " OR s.rowid = '".$db->escape($socid)."'"; + $sql .= ")"; + } + //if (GETPOST("filter")) $sql.= " AND (".GETPOST("filter", "alpha").")"; // Add other filters + $sql .= " ORDER BY s.nom ASC"; + + //dol_syslog("ajaxcompanies", LOG_DEBUG); + $resql = $db->query($sql); + + if ($resql) { + while ($row = $db->fetch_array($resql)) { + $label = $row['nom']; + if ($socid) $label = $label; + $row_array['label'] = $label; + $row_array['value'] = $row['nom']; + $row_array['key'] = $row['rowid']; + $row_array['name_alias'] = $row['name_alias']; + $row_array['code_client'] = $row['code_client']; + $row_array['code_fournisseur'] = $row['code_fournisseur']; + $row_array['address'] = $row['address']; + $row_array['zip'] = $row['zip']; + $row_array['town'] = $row['town']; + $row_array['email'] = $row['email']; + $row_array['siren'] = $row['siren']; + $row_array['siret'] = $row['siret']; + $row_array['ape'] = $row['ape']; + $row_array['idprof4'] = $row['idprof4']; + $row_array['client'] = $row['client']; + $row_array['fournisseur'] = $row['fournisseur']; + $row_array['datec'] = $row['datec']; + $row_array['logo'] = $row['logo']; + $row_array['country'] = $row['country']; + $row_array['departement'] = $row['departement']; + + array_push($return_arr, $row_array); + } + + echo json_encode($return_arr); + } else { + echo json_encode(array('nom'=>'Error', 'label'=>'Error', 'key'=>'Error', 'value'=>'Error')); + } +} else { + echo json_encode(array('nom'=>'ErrorBadParameter', 'label'=>'ErrorBadParameter', 'key'=>'ErrorBadParameter', 'value'=>'ErrorBadParameter')); +} diff --git a/htdocs/core/ajax/ajaxdirtree.php b/htdocs/core/ajax/ajaxdirtree.php index 19c389ec7f8..7daa715bbb9 100644 --- a/htdocs/core/ajax/ajaxdirtree.php +++ b/htdocs/core/ajax/ajaxdirtree.php @@ -47,8 +47,6 @@ if (!isset($mode) || $mode != 'noajax') { // For ajax call include_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php'; - //if (GETPOST('preopened')) { $_GET['dir'] = $_POST['dir'] = '/bbb/'; } - $openeddir = GETPOST('openeddir'); $modulepart = GETPOST('modulepart'); $selecteddir = jsUnEscape(GETPOST('dir')); // relative path. We must decode using same encoding function used by javascript: escape() @@ -60,7 +58,6 @@ if (!isset($mode) || $mode != 'noajax') { // For ajax call } } else { // For no ajax call - //if (GETPOST('preopened')) { $_GET['dir'] = $_POST['dir'] = GETPOST('preopened'); } $openeddir = GETPOST('openeddir'); $modulepart = GETPOST('modulepart'); diff --git a/htdocs/core/ajax/objectonoff.php b/htdocs/core/ajax/objectonoff.php index 5bac89345ce..ffd05c4747e 100644 --- a/htdocs/core/ajax/objectonoff.php +++ b/htdocs/core/ajax/objectonoff.php @@ -88,7 +88,10 @@ if (($action == 'set') && !empty($id)) { $triggerkey = strtoupper($element).'_UPDATE'; // Special case if ($triggerkey == 'SOCIETE_UPDATE') { - $triggerkey = 'COMPANY_UPDATE'; + $triggerkey = 'COMPANY_MODIFY'; + } + if ($triggerkey == 'PRODUCT_UPDATE') { + $triggerkey = 'PRODUCT_MODIFY'; } $object->setValueFrom($field, $value, $tablename, $id, $format, '', $user, $triggerkey); diff --git a/htdocs/core/ajax/row.php b/htdocs/core/ajax/row.php index 8158b935ad5..fcc39e1aae1 100644 --- a/htdocs/core/ajax/row.php +++ b/htdocs/core/ajax/row.php @@ -93,6 +93,10 @@ if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3) $perm = 1; } elseif ($table_element_line == 'facture_fourn_det' && $user->rights->fournisseur->facture->creer) { $perm = 1; + } elseif ($table_element_line == 'facture_fourn_det_rec' && $user->rights->fournisseur->facture->creer) { + $perm = 1; + } elseif ($table_element_line == 'product_attribute_value' && $fk_element == 'fk_product_attribute' && ($user->rights->produit->lire || $user->rights->service->lire)) { + $perm = 1; } elseif ($table_element_line == 'ecm_files') { // Used when of page "documents.php" if (!empty($user->rights->ecm->creer)) { $perm = 1; diff --git a/htdocs/core/ajax/saveinplace.php b/htdocs/core/ajax/saveinplace.php index 2f88cebf58b..05fad8148fa 100644 --- a/htdocs/core/ajax/saveinplace.php +++ b/htdocs/core/ajax/saveinplace.php @@ -103,6 +103,7 @@ if (!empty($field) && !empty($element) && !empty($table_element) && !empty($fk_e } $_POST['action'] = 'update'; // Hack so restrictarea will test permissions on write too + $feature = $newelement; $feature2 = $subelement; $object_id = $fk_element; diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php index 371a7a0dbed..02b5070a96c 100644 --- a/htdocs/core/boxes/box_activity.php +++ b/htdocs/core/boxes/box_activity.php @@ -329,7 +329,7 @@ class box_activity extends ModeleBoxes if (!empty($data)) { $j = 0; while ($j < count($data)) { - $billurl = "search_status=2&paye=1&year=".$data[$j]->annee; + $billurl = "search_status=2&paye=1"; $this->info_box_contents[$line][0] = array( 'td' => 'class="left" width="16"', 'tooltip' => $langs->trans('Bills').' '.$facturestatic->LibStatut(1, $data[$j]->fk_statut, 0), @@ -339,7 +339,7 @@ class box_activity extends ModeleBoxes $this->info_box_contents[$line][1] = array( 'td' => '', - 'text' => $langs->trans("Bills")." ".$facturestatic->LibStatut(1, $data[$j]->fk_statut, 0)." ".$data[$j]->annee, + 'text' => $langs->trans("Bills")." ".$facturestatic->LibStatut(1, $data[$j]->fk_statut, 0), ); $this->info_box_contents[$line][2] = array( diff --git a/htdocs/core/boxes/box_birthdays.php b/htdocs/core/boxes/box_birthdays.php index 02c39c2f625..9462c810393 100644 --- a/htdocs/core/boxes/box_birthdays.php +++ b/htdocs/core/boxes/box_birthdays.php @@ -131,7 +131,7 @@ class box_birthdays extends ModeleBoxes } if ($num == 0) { - $this->info_box_contents[$line][0] = array('td' => 'class="center opacitymedium"', 'text'=>$langs->trans("None")); + $this->info_box_contents[$line][0] = array('td' => 'class="center"', 'text' => ''.$langs->trans("None").''); } $this->db->free($result); @@ -144,8 +144,8 @@ class box_birthdays extends ModeleBoxes } } else { $this->info_box_contents[0][0] = array( - 'td' => 'class="nohover opacitymedium left"', - 'text' => $langs->trans("ReadPermissionNotAllowed") + 'td' => 'class="nohover left"', + 'text' => ''.$langs->trans("ReadPermissionNotAllowed").'' ); } } diff --git a/htdocs/core/boxes/box_birthdays_members.php b/htdocs/core/boxes/box_birthdays_members.php index 5e772ff3593..6138664db2d 100644 --- a/htdocs/core/boxes/box_birthdays_members.php +++ b/htdocs/core/boxes/box_birthdays_members.php @@ -128,7 +128,7 @@ class box_birthdays_members extends ModeleBoxes } if ($num == 0) { - $this->info_box_contents[$line][0] = array('td' => 'class="center opacitymedium"', 'text'=>$langs->trans("None")); + $this->info_box_contents[$line][0] = array('td' => 'class="center"', 'text' => ''.$langs->trans("None").''); } $this->db->free($result); @@ -141,8 +141,8 @@ class box_birthdays_members extends ModeleBoxes } } else { $this->info_box_contents[0][0] = array( - 'td' => 'class="nohover opacitymedium left"', - 'text' => $langs->trans("ReadPermissionNotAllowed") + 'td' => 'class="nohover left"', + 'text' => ''.$langs->trans("ReadPermissionNotAllowed").'' ); } } diff --git a/htdocs/core/boxes/box_boms.php b/htdocs/core/boxes/box_boms.php index d96fac8bc76..a9a4f8746da 100644 --- a/htdocs/core/boxes/box_boms.php +++ b/htdocs/core/boxes/box_boms.php @@ -147,7 +147,7 @@ class box_boms extends ModeleBoxes } $this->info_box_contents[$line][] = array( - 'td' => 'class="right"', + 'td' => 'class="center nowraponall" title="'.dol_escape_htmltag($langs->trans("DateModification").': '.dol_print_date($datem, 'dayhour', 'tzuserrel')).'"', 'text' => dol_print_date($datem, 'day', 'tzuserrel'), ); diff --git a/htdocs/core/boxes/box_clients.php b/htdocs/core/boxes/box_clients.php index 74ba5a9d4c9..4a7ea965006 100644 --- a/htdocs/core/boxes/box_clients.php +++ b/htdocs/core/boxes/box_clients.php @@ -76,7 +76,7 @@ class box_clients extends ModeleBoxes */ public function loadBox($max = 5) { - global $user, $langs, $conf; + global $user, $langs, $hookmanager; $langs->load("boxes"); $this->max = $max; @@ -100,9 +100,15 @@ class box_clients extends ModeleBoxes if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } - if ($user->socid) { - $sql .= " AND s.rowid = ".((int) $user->socid); + // Add where from hooks + $parameters = array('socid' => $user->socid, 'boxcode' => $this->boxcode); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $thirdpartystatic); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if ($user->socid > 0) { + $sql .= " AND s.rowid = ".((int) $user->socid); + } } + $sql .= $hookmanager->resPrint; $sql .= " ORDER BY s.tms DESC"; $sql .= $this->db->plimit($max, 0); @@ -134,7 +140,7 @@ class box_clients extends ModeleBoxes ); $this->info_box_contents[$line][] = array( - 'td' => 'class="center nowraponall"', + 'td' => 'class="center nowraponall" title="'.dol_escape_htmltag($langs->trans("DateModification").': '.dol_print_date($datem, 'dayhour', 'tzuserrel')).'"', 'text' => dol_print_date($datem, "day", 'tzuserrel') ); diff --git a/htdocs/core/boxes/box_contacts.php b/htdocs/core/boxes/box_contacts.php index 0d774faf569..ea35a080d0e 100644 --- a/htdocs/core/boxes/box_contacts.php +++ b/htdocs/core/boxes/box_contacts.php @@ -74,11 +74,15 @@ class box_contacts extends ModeleBoxes */ public function loadBox($max = 5) { - global $user, $langs, $conf; + global $user, $langs, $conf, $hookmanager; + $langs->load("boxes"); $this->max = $max; + $contactstatic = new Contact($this->db); + $societestatic = new Societe($this->db); + $this->info_box_head = array('text' => $langs->trans("BoxTitleLastModifiedContacts", $max)); if ($user->rights->societe->lire && $user->rights->societe->contact->lire) { @@ -106,13 +110,19 @@ class box_contacts extends ModeleBoxes if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } - $sql .= " WHERE sp.entity IN (".getEntity('socpeople').")"; + $sql .= " WHERE sp.entity IN (".getEntity('contact').")"; if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } - if ($user->socid) { - $sql .= " AND sp.fk_soc = ".((int) $user->socid); + // Add where from hooks + $parameters = array('socid' => $user->socid, 'boxcode' => $this->boxcode); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $contactstatic); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if ($user->socid > 0) { + $sql .= " AND sp.fk_soc = ".((int) $user->socid); + } } + $sql .= $hookmanager->resPrint; $sql .= " ORDER BY sp.tms DESC"; $sql .= $this->db->plimit($max, 0); @@ -120,9 +130,6 @@ class box_contacts extends ModeleBoxes if ($result) { $num = $this->db->num_rows($result); - $contactstatic = new Contact($this->db); - $societestatic = new Societe($this->db); - $line = 0; while ($line < $num) { $objp = $this->db->fetch_object($result); @@ -170,7 +177,7 @@ class box_contacts extends ModeleBoxes ); $this->info_box_contents[$line][] = array( - 'td' => 'class="right"', + 'td' => 'class="center nowraponall" title="'.dol_escape_htmltag($langs->trans("DateModification").': '.dol_print_date($datem, 'dayhour', 'tzuserrel')).'"', 'text' => dol_print_date($datem, "day", 'tzuserrel'), ); diff --git a/htdocs/core/boxes/box_contracts.php b/htdocs/core/boxes/box_contracts.php index 8eeb1b93323..dddafffdc02 100644 --- a/htdocs/core/boxes/box_contracts.php +++ b/htdocs/core/boxes/box_contracts.php @@ -83,8 +83,8 @@ class box_contracts extends ModeleBoxes $thirdpartytmp = new Societe($this->db); $sql = "SELECT s.nom as name, s.rowid as socid, s.email, s.client, s.fournisseur, s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur,"; - $sql .= " c.rowid, c.ref, c.statut as fk_statut, c.date_contrat, c.datec, c.fin_validite, c.date_cloture"; - $sql .= ", c.ref_customer, c.ref_supplier"; + $sql .= " c.rowid, c.ref, c.statut as fk_statut, c.date_contrat, c.datec, c.tms as date_modification, c.fin_validite, c.date_cloture,"; + $sql .= " c.ref_customer, c.ref_supplier"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as c"; if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; @@ -117,6 +117,7 @@ class box_contracts extends ModeleBoxes $objp = $this->db->fetch_object($resql); $datec = $this->db->jdate($objp->datec); + $datem = $this->db->jdate($objp->date_modification); $dateterm = $this->db->jdate($objp->fin_validite); $dateclose = $this->db->jdate($objp->date_cloture); $late = ''; @@ -155,8 +156,8 @@ class box_contracts extends ModeleBoxes ); $this->info_box_contents[$line][] = array( - 'td' => 'class="right"', - 'text' => dol_print_date($datec, 'day', 'tzuserrel'), + 'td' => 'class="center nowraponall" title="'.dol_escape_htmltag($langs->trans("DateModification").': '.dol_print_date($datem, 'dayhour', 'tzuserrel')).'"', + 'text' => dol_print_date($datem, 'day', 'tzuserrel'), ); $this->info_box_contents[$line][] = array( diff --git a/htdocs/core/boxes/box_external_rss.php b/htdocs/core/boxes/box_external_rss.php index aff48328edb..2a04aa27803 100644 --- a/htdocs/core/boxes/box_external_rss.php +++ b/htdocs/core/boxes/box_external_rss.php @@ -127,7 +127,7 @@ class box_external_rss extends ModeleBoxes // Feed common fields $href = $item['link']; $title = urldecode($item['title']); - $date = $item['date_timestamp']; // date will be empty if conversion into timestamp failed + $date = empty($item['date_timestamp']) ? null : $item['date_timestamp']; // date will be empty if conversion into timestamp failed if ($rssparser->getFormat() == 'rss') { // If RSS if (!$date && isset($item['pubdate'])) { $date = $item['pubdate']; diff --git a/htdocs/core/boxes/box_fournisseurs.php b/htdocs/core/boxes/box_fournisseurs.php index 4f297135b26..3cb1f570a30 100644 --- a/htdocs/core/boxes/box_fournisseurs.php +++ b/htdocs/core/boxes/box_fournisseurs.php @@ -71,7 +71,7 @@ class box_fournisseurs extends ModeleBoxes */ public function loadBox($max = 5) { - global $conf, $user, $langs; + global $conf, $user, $langs, $hookmanager; $langs->load("boxes"); $this->max = $max; @@ -95,9 +95,15 @@ class box_fournisseurs extends ModeleBoxes if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } - if ($user->socid) { - $sql .= " AND s.rowid = ".((int) $user->socid); + // Add where from hooks + $parameters = array('socid' => $user->socid, 'boxcode' => $this->boxcode); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $thirdpartystatic); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if ($user->socid > 0) { + $sql .= " AND s.rowid = ".((int) $user->socid); + } } + $sql .= $hookmanager->resPrint; $sql .= " ORDER BY s.tms DESC "; $sql .= $this->db->plimit($max, 0); diff --git a/htdocs/core/boxes/box_graph_nb_ticket_last_x_days.php b/htdocs/core/boxes/box_graph_nb_ticket_last_x_days.php index 2ce9444f677..b75d0752334 100644 --- a/htdocs/core/boxes/box_graph_nb_ticket_last_x_days.php +++ b/htdocs/core/boxes/box_graph_nb_ticket_last_x_days.php @@ -31,7 +31,7 @@ require_once DOL_DOCUMENT_ROOT."/core/boxes/modules_boxes.php"; class box_graph_nb_ticket_last_x_days extends ModeleBoxes { - public $boxcode = "box_nb_ticket_last_x_days"; + public $boxcode = "box_graph_nb_ticket_last_x_days"; public $boximg = "ticket"; public $boxlabel; public $depends = array("ticket"); @@ -87,11 +87,11 @@ class box_graph_nb_ticket_last_x_days extends ModeleBoxes $param_day = 'DOLUSERCOOKIE_ticket_last_days'; - if (!empty($_POST[$param_day])) { - if ($_POST[$param_day] >= 15) { + if (GETPOST($param_day)) { + if (GETPOST($param_day) >= 15) { $days = 14; } else { - $days = $_POST[$param_day]; + $days = GETPOST($param_day); } } else { $days = 7; @@ -102,18 +102,17 @@ class box_graph_nb_ticket_last_x_days extends ModeleBoxes 'text' => $text, 'limit' => dol_strlen($text) ); - $today = date_time_set(date_create(), 0, 0); - $todayformat = date('Y-m-d', date_timestamp_get($today)); - $intervaltosub = new DateInterval('P'.dol_escape_htmltag($days - 1).'D'); - $intervaltoadd = new DateInterval('P1D'); - $minimumdatec = date_sub($today, $intervaltosub); - $minimumdatecformated = date('Y-m-d', date_timestamp_get($minimumdatec)); + $today = dol_now(); + $intervaltoadd = 1; + $minimumdatec = dol_time_plus_duree($today, -1 * ($days - 1), 'd'); + $minimumdatecformated = dol_print_date($minimumdatec, 'dayrfc'); if ($user->rights->ticket->read) { $sql = "SELECT CAST(t.datec AS DATE) as datec, COUNT(t.datec) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."ticket as t"; - $sql .= " WHERE CAST(t.datec AS DATE) > DATE_SUB(CURRENT_DATE, INTERVAL ".$days." DAY)"; + $sql .= " WHERE CAST(t.datec AS DATE) > '".$this->db->idate($minimumdatec)."'"; $sql .= " GROUP BY CAST(t.datec AS DATE)"; + $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -122,18 +121,18 @@ class box_graph_nb_ticket_last_x_days extends ModeleBoxes $objp = $this->db->fetch_object($resql); while ($minimumdatecformated < $objp->datec) { $dataseries[] = array('label' => dol_print_date($minimumdatecformated, 'day'), 'data' => 0); - $minimumdatec = date_add($minimumdatec, $intervaltoadd); - $minimumdatecformated = date('Y-m-d', date_timestamp_get($minimumdatec)); + $minimumdatec = dol_time_plus_duree($minimumdatec, $intervaltoadd, 'd'); + $minimumdatecformated = dol_print_date($minimumdatec, 'dayrfc'); } $dataseries[] = array('label' => dol_print_date($objp->datec, 'day'), 'data' => $objp->nb); - $minimumdatec = date_add($minimumdatec, $intervaltoadd); - $minimumdatecformated = date('Y-m-d', date_timestamp_get($minimumdatec)); + $minimumdatec = dol_time_plus_duree($minimumdatec, $intervaltoadd, 'd'); + $minimumdatecformated = dol_print_date($minimumdatec, 'dayrfc'); $i++; } while (count($dataseries) < $days) { $dataseries[] = array('label' => dol_print_date($minimumdatecformated, 'day'), 'data' => 0); - $minimumdatec = date_add($minimumdatec, $intervaltoadd); - $minimumdatecformated = date('Y-m-d', date_timestamp_get($minimumdatec)); + $minimumdatec = dol_time_plus_duree($minimumdatec, $intervaltoadd, 'd'); + $minimumdatecformated = dol_print_date($minimumdatec, 'dayrfc'); $i++; } } else { diff --git a/htdocs/core/boxes/box_graph_nb_tickets_type.php b/htdocs/core/boxes/box_graph_nb_tickets_type.php index f4efce23797..6b25f5d84d0 100644 --- a/htdocs/core/boxes/box_graph_nb_tickets_type.php +++ b/htdocs/core/boxes/box_graph_nb_tickets_type.php @@ -31,7 +31,7 @@ require_once DOL_DOCUMENT_ROOT."/core/boxes/modules_boxes.php"; class box_graph_nb_tickets_type extends ModeleBoxes { - public $boxcode = "box_nb_tickets_type"; + public $boxcode = "box_graph_nb_tickets_type"; public $boximg = "ticket"; public $boxlabel; public $depends = array("ticket"); @@ -171,7 +171,7 @@ class box_graph_nb_tickets_type extends ModeleBoxes } $stringtoprint .= '
    '; $this->info_box_contents[][]=array( - 'td' => 'center', + 'td' => 'class="center"', 'text' => $stringtoprint ); } else { diff --git a/htdocs/core/boxes/box_graph_product_distribution.php b/htdocs/core/boxes/box_graph_product_distribution.php index 04d785799af..adcc750a6a8 100644 --- a/htdocs/core/boxes/box_graph_product_distribution.php +++ b/htdocs/core/boxes/box_graph_product_distribution.php @@ -150,7 +150,7 @@ class box_graph_product_distribution extends ModeleBoxes $userid = 0; // No filter on user creation $WIDTH = ($nbofgraph >= 2 || !empty($conf->dol_optimize_smallscreen)) ? '300' : '320'; - $HEIGHT = '120'; + $HEIGHT = '150'; // Height require to have 5+1 entries into legend visible. if (!empty($conf->propal->enabled) && !empty($user->rights->propale->lire)) { // Build graphic number of object. $data = array(array('Lib',val1,val2,val3),...) diff --git a/htdocs/core/boxes/box_graph_ticket_by_severity.php b/htdocs/core/boxes/box_graph_ticket_by_severity.php index 72e74542b20..c668894d991 100644 --- a/htdocs/core/boxes/box_graph_ticket_by_severity.php +++ b/htdocs/core/boxes/box_graph_ticket_by_severity.php @@ -191,19 +191,19 @@ class box_graph_ticket_by_severity extends ModeleBoxes } $stringtoprint .= ''; $this->info_box_contents[][]=array( - 'td' => 'center', + 'td' => 'class="center"', 'text' => $stringtoprint ); } else { $this->info_box_contents[0][0] = array( - 'td' => 'class="center opacitymedium"', - 'text' => $langs->trans("BoxNoTicketSeverity") + 'td' => '', + 'text' => ''.$langs->trans("BoxNoTicketSeverity").'' ); } } else { $this->info_box_contents[0][0] = array( - 'td' => 'class="left"', - 'text' => $langs->trans("ReadPermissionNotAllowed"), + 'td' => '', + 'text' => ''.$langs->trans("ReadPermissionNotAllowed").'', ); } } diff --git a/htdocs/core/boxes/box_last_modified_ticket.php b/htdocs/core/boxes/box_last_modified_ticket.php index 300a13803c5..fd8ecd95eaf 100644 --- a/htdocs/core/boxes/box_last_modified_ticket.php +++ b/htdocs/core/boxes/box_last_modified_ticket.php @@ -177,15 +177,15 @@ class box_last_modified_ticket extends ModeleBoxes } if ($num == 0) { - $this->info_box_contents[$i][0] = array('td' => 'class="center"', 'text'=>$langs->trans("BoxLastModifiedTicketNoRecordedTickets")); + $this->info_box_contents[$i][0] = array('td' => '', 'text'=>''.$langs->trans("BoxLastModifiedTicketNoRecordedTickets").''); } } else { dol_print_error($this->db); } } else { $this->info_box_contents[0][0] = array( - 'td' => 'class="left"', - 'text' => $langs->trans("ReadPermissionNotAllowed"), + 'td' => '', + 'text' => ''.$langs->trans("ReadPermissionNotAllowed").'', ); } } diff --git a/htdocs/core/boxes/box_last_ticket.php b/htdocs/core/boxes/box_last_ticket.php index 25cb353b268..41ac39c1239 100644 --- a/htdocs/core/boxes/box_last_ticket.php +++ b/htdocs/core/boxes/box_last_ticket.php @@ -85,9 +85,9 @@ class box_last_ticket extends ModeleBoxes ); if ($user->rights->ticket->read) { - $sql = "SELECT t.rowid as id, t.ref, t.track_id, t.fk_soc, t.fk_user_create, t.fk_user_assign, t.subject, t.message, t.fk_statut, t.type_code, t.category_code, t.severity_code, t.datec, t.date_read, t.date_close, t.origin_email "; - $sql .= ", type.label as type_label, category.label as category_label, severity.label as severity_label"; - $sql .= ", s.nom as company_name, s.email as socemail, s.client, s.fournisseur"; + $sql = "SELECT t.rowid as id, t.ref, t.track_id, t.fk_soc, t.fk_user_create, t.fk_user_assign, t.subject, t.message, t.fk_statut as status, t.type_code, t.category_code, t.severity_code, t.datec, t.date_read, t.date_close, t.origin_email,"; + $sql .= " type.label as type_label, category.label as category_label, severity.label as severity_label,"; + $sql .= " s.nom as company_name, s.email as socemail, s.client, s.fournisseur"; $sql .= " FROM ".MAIN_DB_PREFIX."ticket as t"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_ticket_type as type ON type.code=t.type_code"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_ticket_category as category ON category.code=t.category_code"; @@ -113,6 +113,7 @@ class box_last_ticket extends ModeleBoxes while ($i < $num) { $objp = $this->db->fetch_object($resql); + $datec = $this->db->jdate($objp->datec); //$dateterm = $this->db->jdate($objp->fin_validite); //$dateclose = $this->db->jdate($objp->date_close); @@ -122,7 +123,8 @@ class box_last_ticket extends ModeleBoxes $ticket->id = $objp->id; $ticket->track_id = $objp->track_id; $ticket->ref = $objp->ref; - $ticket->fk_statut = $objp->fk_statut; + $ticket->fk_statut = $objp->status; + $ticket->status = $objp->status; $ticket->subject = $objp->subject; if ($objp->fk_soc > 0) { $thirdparty = new Societe($this->db); @@ -149,8 +151,8 @@ class box_last_ticket extends ModeleBoxes // Subject $this->info_box_contents[$i][$r] = array( 'td' => 'class="tdoverflowmax200"', - 'text' => ''.$objp->subject.'', // Some event have no ref - 'url' => DOL_URL_ROOT."/ticket/card.php?track_id=".$objp->track_id, + 'text' => ''.dol_escape_htmltag($objp->subject).'', // Some event have no ref + 'url' => DOL_URL_ROOT."/ticket/card.php?track_id=".urlencode($objp->track_id), ); $r++; @@ -180,14 +182,14 @@ class box_last_ticket extends ModeleBoxes } if ($num == 0) { - $this->info_box_contents[$i][0] = array('td' => 'class="center"', 'text' => $langs->trans("BoxLastTicketNoRecordedTickets")); + $this->info_box_contents[$i][0] = array('td' => '', 'text' => ''.$langs->trans("BoxLastTicketNoRecordedTickets").''); } } else { dol_print_error($this->db); } } else { - $this->info_box_contents[0][0] = array('td' => 'class="left"', - 'text' => $langs->trans("ReadPermissionNotAllowed")); + $this->info_box_contents[0][0] = array('td' => '', + 'text' => ''.$langs->trans("ReadPermissionNotAllowed").''); } } diff --git a/htdocs/core/boxes/box_members.php b/htdocs/core/boxes/box_members.php deleted file mode 100644 index 5865cba2530..00000000000 --- a/htdocs/core/boxes/box_members.php +++ /dev/null @@ -1,195 +0,0 @@ - - * Copyright (C) 2004-2017 Laurent Destailleur - * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2015-2020 Frederic France - * - * 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 . - */ - -/** - * \file htdocs/core/boxes/box_members.php - * \ingroup adherent - * \brief Module to show box of members - */ - -include_once DOL_DOCUMENT_ROOT.'/core/boxes/modules_boxes.php'; - - -/** - * Class to manage the box to show last members - */ -class box_members extends ModeleBoxes -{ - public $boxcode = "lastmembers"; - public $boximg = "object_user"; - public $boxlabel = "BoxLastMembers"; - public $depends = array("adherent"); - - /** - * @var DoliDB Database handler. - */ - public $db; - - public $param; - public $enabled = 1; - - public $info_box_head = array(); - public $info_box_contents = array(); - - - /** - * Constructor - * - * @param DoliDB $db Database handler - * @param string $param More parameters - */ - public function __construct($db, $param = '') - { - global $conf, $user; - - $this->db = $db; - - // disable module for such cases - $listofmodulesforexternal = explode(',', $conf->global->MAIN_MODULES_FOR_EXTERNAL); - if (!in_array('adherent', $listofmodulesforexternal) && !empty($user->socid)) { - $this->enabled = 0; // disabled for external users - } - - $this->hidden = !($user->rights->adherent->lire); - } - - /** - * Load data into info_box_contents array to show array later. - * - * @param int $max Maximum number of records to load - * @return void - */ - public function loadBox($max = 5) - { - global $user, $langs, $conf; - $langs->load("boxes"); - - $this->max = $max; - - include_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; - $memberstatic = new Adherent($this->db); - - $this->info_box_head = array('text' => $langs->trans("BoxTitleLastModifiedMembers", $max)); - - if ($user->rights->adherent->lire) { - $sql = "SELECT a.rowid, a.ref, a.lastname, a.firstname, a.societe as company, a.fk_soc,"; - $sql .= " a.datec, a.tms, a.statut as status, a.datefin as date_end_subscription,"; - $sql .= ' a.photo, a.email, a.gender, a.morphy,'; - $sql .= " t.subscription, t.libelle as label"; - $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a, ".MAIN_DB_PREFIX."adherent_type as t"; - $sql .= " WHERE a.entity IN (".getEntity('member').")"; - $sql .= " AND a.fk_adherent_type = t.rowid"; - $sql .= " ORDER BY a.tms DESC"; - $sql .= $this->db->plimit($max, 0); - - $result = $this->db->query($sql); - if ($result) { - $num = $this->db->num_rows($result); - - $line = 0; - while ($line < $num) { - $objp = $this->db->fetch_object($result); - $datec = $this->db->jdate($objp->datec); - $datem = $this->db->jdate($objp->tms); - - $memberstatic->lastname = $objp->lastname; - $memberstatic->firstname = $objp->firstname; - $memberstatic->id = $objp->rowid; - $memberstatic->ref = $objp->ref; - $memberstatic->photo = $objp->photo; - $memberstatic->gender = $objp->gender; - $memberstatic->email = $objp->email; - $memberstatic->morphy = $objp->morphy; - $memberstatic->company = $objp->company; - $memberstatic->statut = $objp->status; - $memberstatic->date_creation = $datec; - $memberstatic->date_modification = $datem; - $memberstatic->need_subscription = $objp->subscription; - $memberstatic->datefin = $this->db->jdate($objp->date_end_subscription); - - if (!empty($objp->fk_soc)) { - $memberstatic->socid = $objp->fk_soc; - $memberstatic->fetch_thirdparty(); - $memberstatic->name = $memberstatic->thirdparty->name; - } else { - $memberstatic->name = $objp->company; - } - - $this->info_box_contents[$line][] = array( - 'td' => 'class="tdoverflowmax150 maxwidth150onsmartphone"', - 'text' => $memberstatic->getNomUrl(-1), - 'asis' => 1, - ); - - $this->info_box_contents[$line][] = array( - 'td' => 'class="tdoverflowmax150 maxwidth150onsmartphone"', - 'text' => $memberstatic->company, - 'url' => DOL_URL_ROOT."/adherents/card.php?rowid=".$objp->rowid, - ); - - $this->info_box_contents[$line][] = array( - 'td' => 'class="center nowraponall"', - 'text' => dol_print_date($datem, "day", 'tzuserrel'), - ); - - $this->info_box_contents[$line][] = array( - 'td' => 'class="right" width="18"', - 'text' => $memberstatic->LibStatut($objp->status, $objp->subscription, $this->db->jdate($objp->date_end_subscription), 3), - ); - - $line++; - } - - if ($num == 0) { - $this->info_box_contents[$line][0] = array( - 'td' => 'class="center"', - 'text'=>$langs->trans("NoRecordedCustomers"), - ); - } - - $this->db->free($result); - } else { - $this->info_box_contents[0][0] = array( - 'td' => '', - 'maxlength'=>500, - 'text' => ($this->db->error().' sql='.$sql), - ); - } - } else { - $this->info_box_contents[0][0] = array( - 'td' => 'class="nohover opacitymedium left"', - 'text' => $langs->trans("ReadPermissionNotAllowed") - ); - } - } - - /** - * Method to show box - * - * @param array $head Array with properties of box title - * @param array $contents Array with properties of box lines - * @param int $nooutput No print, only return string - * @return string - */ - public function showBox($head = null, $contents = null, $nooutput = 0) - { - return parent::showBox($this->info_box_head, $this->info_box_contents, $nooutput); - } -} diff --git a/htdocs/core/boxes/box_members_by_type.php b/htdocs/core/boxes/box_members_by_type.php index 4bbf20e9cbf..23542999b47 100644 --- a/htdocs/core/boxes/box_members_by_type.php +++ b/htdocs/core/boxes/box_members_by_type.php @@ -173,27 +173,34 @@ class box_members_by_type extends ModeleBoxes $line = 0; $this->info_box_contents[$line][] = array( 'td' => 'class=""', - 'text' => $langs->trans("MembersTypes"), + 'text' => '', ); + $labelstatus = $staticmember->LibStatut($staticmember::STATUS_DRAFT, 0, 0, 1); $this->info_box_contents[$line][] = array( - 'td' => 'class="right"', - 'text' => $langs->trans("MembersStatusToValid"), // Draft + 'td' => 'class="right tdoverflowmax100" width="15%" title="'.dol_escape_htmltag($labelstatus).'"', + 'text' => $labelstatus ); + $labelstatus = $langs->trans("UpToDate"); + $labelstatus = $staticmember->LibStatut($staticmember::STATUS_VALIDATED, 1, dol_now() + 86400, 1); $this->info_box_contents[$line][] = array( - 'td' => 'class="right"', - 'text' => $langs->trans("UpToDate"), + 'td' => 'class="right tdoverflowmax100" width="15%" title="'.dol_escape_htmltag($labelstatus).'"', + 'text' => $labelstatus, ); + $labelstatus = $langs->trans("OutOfDate"); + $labelstatus = $staticmember->LibStatut($staticmember::STATUS_VALIDATED, 1, dol_now() - 86400, 1); $this->info_box_contents[$line][] = array( - 'td' => 'class="right"', - 'text' => $langs->trans("OutOfDate"), + 'td' => 'class="right tdoverflowmax100" width="15%" title="'.dol_escape_htmltag($labelstatus).'"', + 'text' => $labelstatus ); + $labelstatus = $staticmember->LibStatut($staticmember::STATUS_EXCLUDED, 0, 0, 1); $this->info_box_contents[$line][] = array( - 'td' => 'class="right"', - 'text' => $langs->trans("MembersStatusExcluded"), + 'td' => 'class="right tdoverflowmax100" width="15%" title="'.dol_escape_htmltag($labelstatus).'"', + 'text' => $labelstatus ); + $labelstatus = $staticmember->LibStatut($staticmember::STATUS_RESILIATED, 0, 0, 1); $this->info_box_contents[$line][] = array( - 'td' => 'class="right"', - 'text' => $langs->trans("MembersStatusResiliated"), + 'td' => 'class="right tdoverflowmax100" width="15%" title="'.dol_escape_htmltag($labelstatus).'"', + 'text' => $labelstatus ); $line++; foreach ($AdherentType as $key => $adhtype) { diff --git a/htdocs/core/boxes/box_members_last_modified.php b/htdocs/core/boxes/box_members_last_modified.php index cf70bcafcb1..6b4a033f1a2 100644 --- a/htdocs/core/boxes/box_members_last_modified.php +++ b/htdocs/core/boxes/box_members_last_modified.php @@ -28,7 +28,7 @@ include_once DOL_DOCUMENT_ROOT.'/core/boxes/modules_boxes.php'; /** - * Class to manage the box to show last modofied members + * Class to manage the box to show last modified members */ class box_members_last_modified extends ModeleBoxes { @@ -92,7 +92,7 @@ class box_members_last_modified extends ModeleBoxes if ($user->rights->adherent->lire) { $sql = "SELECT a.rowid, a.ref, a.lastname, a.firstname, a.societe as company, a.fk_soc,"; - $sql .= " a.datec, a.tms, a.statut as status, a.datefin as date_end_subscription,"; + $sql .= " a.datec, a.tms as datem, a.statut as status, a.datefin as date_end_subscription,"; $sql .= ' a.photo, a.email, a.gender, a.morphy,'; $sql .= " t.rowid as typeid, t.subscription, t.libelle as label"; $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a, ".MAIN_DB_PREFIX."adherent_type as t"; @@ -121,6 +121,8 @@ class box_members_last_modified extends ModeleBoxes $memberstatic->morphy = $objp->morphy; $memberstatic->company = $objp->company; $memberstatic->statut = $objp->status; + $memberstatic->date_creation = $datec; + $memberstatic->date_modification = $datem; $memberstatic->need_subscription = $objp->subscription; $memberstatic->datefin = $this->db->jdate($objp->date_end_subscription); if (!empty($objp->fk_soc)) { @@ -140,6 +142,11 @@ class box_members_last_modified extends ModeleBoxes 'asis' => 1, ); + $this->info_box_contents[$line][] = array( + 'td' => 'class="tdoverflowmax150 maxwidth150onsmartphone"', + 'text' =>$memberstatic->company, + ); + $this->info_box_contents[$line][] = array( 'td' => 'class="tdoverflowmax150 maxwidth150onsmartphone"', 'text' => $statictype->getNomUrl(1, 32), @@ -147,7 +154,7 @@ class box_members_last_modified extends ModeleBoxes ); $this->info_box_contents[$line][] = array( - 'td' => 'class="center nowraponall"', + 'td' => 'class="center nowraponall" title="'.dol_escape_htmltag($langs->trans("DateModification").': '.dol_print_date($datem, 'dayhour', 'tzuserrel')).'"', 'text' => dol_print_date($datem, "day", 'tzuserrel'), ); diff --git a/htdocs/core/boxes/box_mos.php b/htdocs/core/boxes/box_mos.php index 6436fb8e34e..cff19388c17 100644 --- a/htdocs/core/boxes/box_mos.php +++ b/htdocs/core/boxes/box_mos.php @@ -144,7 +144,7 @@ class box_mos extends ModeleBoxes } $this->info_box_contents[$line][] = array( - 'td' => 'class="center nowraponall"', + 'td' => 'class="center nowraponall" title="'.dol_escape_htmltag($langs->trans("DateModification").': '.dol_print_date($datem, 'dayhour', 'tzuserrel')).'"', 'text' => dol_print_date($datem, 'day', 'tzuserrel'), ); diff --git a/htdocs/core/boxes/box_produits.php b/htdocs/core/boxes/box_produits.php index 9a0c76503d0..8ea14ebc8d5 100644 --- a/htdocs/core/boxes/box_produits.php +++ b/htdocs/core/boxes/box_produits.php @@ -103,8 +103,8 @@ class box_produits extends ModeleBoxes } // Add where from hooks if (is_object($hookmanager)) { - $parameters = array('boxproductlist'=>1); - $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook + $parameters = array('boxproductlist' => 1, 'boxcode' => $this->boxcode); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $productstatic); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; } $sql .= $this->db->order('p.datec', 'DESC'); diff --git a/htdocs/core/boxes/box_produits_alerte_stock.php b/htdocs/core/boxes/box_produits_alerte_stock.php index e074cb76198..72b1957b287 100644 --- a/htdocs/core/boxes/box_produits_alerte_stock.php +++ b/htdocs/core/boxes/box_produits_alerte_stock.php @@ -103,8 +103,8 @@ class box_produits_alerte_stock extends ModeleBoxes } // Add where from hooks if (is_object($hookmanager)) { - $parameters = array('boxproductalertstocklist'=>1); - $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook + $parameters = array('boxproductalertstocklist' => 1, 'boxcode' => $this->boxcode); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $productstatic); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; } $sql .= " GROUP BY p.rowid, p.ref, p.label, p.price, p.price_base_type, p.price_ttc, p.fk_product_type, p.tms, p.tosell, p.tobuy, p.barcode, p.seuil_stock_alerte, p.entity,"; diff --git a/htdocs/core/boxes/box_propales.php b/htdocs/core/boxes/box_propales.php index f3f9496325f..97b7bd5fd51 100644 --- a/htdocs/core/boxes/box_propales.php +++ b/htdocs/core/boxes/box_propales.php @@ -165,7 +165,7 @@ class box_propales extends ModeleBoxes ); $this->info_box_contents[$line][] = array( - 'td' => 'class="center nowraponall"', + 'td' => 'class="center nowraponall" title="'.dol_escape_htmltag($langs->trans("Date").': '.dol_print_date($datem, 'day', 'tzuserrel')).'"', 'text' => dol_print_date($date, 'day', 'tzuserrel'), ); diff --git a/htdocs/core/boxes/box_prospect.php b/htdocs/core/boxes/box_prospect.php index a46713a3206..3bf69f91fe0 100644 --- a/htdocs/core/boxes/box_prospect.php +++ b/htdocs/core/boxes/box_prospect.php @@ -78,7 +78,7 @@ class box_prospect extends ModeleBoxes */ public function loadBox($max = 5) { - global $user, $langs, $conf; + global $user, $langs, $hookmanager; $this->max = $max; @@ -101,9 +101,15 @@ class box_prospect extends ModeleBoxes if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } - if ($user->socid) { - $sql .= " AND s.rowid = ".((int) $user->socid); + // Add where from hooks + $parameters = array('socid' => $user->socid, 'boxcode' => $this->boxcode); + $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $thirdpartystatic); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + if ($user->socid > 0) { + $sql .= " AND s.rowid = ".((int) $user->socid); + } } + $sql .= $hookmanager->resPrint; $sql .= " ORDER BY s.tms DESC"; $sql .= $this->db->plimit($max, 0); diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 246bec42ba4..910e6d3ca77 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -222,7 +222,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" box // Show box title if (!empty($head['text']) || !empty($head['sublink']) || !empty($head['subpicto'])) { $out .= ''; - $out .= ' 0) { $out .= ' colspan="'.$nbcol.'"'; } @@ -268,7 +268,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" box $out .= ''; } - $out .= ""; + $out .= ""; $out .= "\n"; } diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index d76f75d8ea5..94fb05d5346 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -140,7 +140,7 @@ class CMailFile */ public function __construct($subject, $to, $from, $msg, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = 0, $errors_to = '', $css = '', $trackid = '', $moreinheader = '', $sendcontext = 'standard', $replyto = '') { - global $conf, $dolibarr_main_data_root; + global $conf, $dolibarr_main_data_root, $user; // Clean values of $mimefilename_list if (is_array($mimefilename_list)) { @@ -149,31 +149,7 @@ class CMailFile } } - // Add autocopy to if not already in $to (Note: Adding bcc for specific modules are also done from pages) - if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_TO) && !preg_match('/'.preg_quote($conf->global->MAIN_MAIL_AUTOCOPY_TO, '/').'/i', $to)) { - $addr_bcc .= ($addr_bcc ? ', ' : '').$conf->global->MAIN_MAIL_AUTOCOPY_TO; - } - - $this->subject = $subject; - $this->addr_to = $to; - $this->addr_from = $from; - $this->msg = $msg; - $this->filename_list = $filename_list; - $this->mimetype_list = $mimetype_list; - $this->mimefilename_list = $mimefilename_list; - $this->addr_cc = $addr_cc; - $this->addr_bcc = $addr_bcc; - $this->deliveryreceipt = $deliveryreceipt; - if (empty($replyto)) { - $replyto = $from; - } - $this->reply_to = $replyto; - $this->errors_to = $errors_to; - $this->trackid = $trackid; $this->sendcontext = $sendcontext; - $this->filename_list = $filename_list; - $this->mimetype_list = $mimetype_list; - $this->mimefilename_list = $mimefilename_list; // Define this->sendmode $this->sendmode = ''; @@ -186,10 +162,7 @@ class CMailFile } } if (empty($this->sendmode)) { - $this->sendmode = $conf->global->MAIN_MAIL_SENDMODE; - } - if (empty($this->sendmode)) { - $this->sendmode = 'mail'; + $this->sendmode = (!empty($conf->global->MAIN_MAIL_SENDMODE) ? $conf->global->MAIN_MAIL_SENDMODE : 'mail'); } // We define end of line (RFC 821). @@ -278,20 +251,52 @@ class CMailFile } } - // Add autocopy to if not already in $to (Note: Adding bcc for specific modules are also done from pages) - if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_TO) && !preg_match('/'.preg_quote($conf->global->MAIN_MAIL_AUTOCOPY_TO, '/').'/i', $to)) { - $addr_bcc .= ($addr_bcc ? ', ' : '').$conf->global->MAIN_MAIL_AUTOCOPY_TO; + // Add auto copy to if not already in $to (Note: Adding bcc for specific modules are also done from pages) + // For example MAIN_MAIL_AUTOCOPY_TO can be 'email@example.com, __USER_EMAIL__, ...' + if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) { + $listofemailstoadd = explode(',', $conf->global->MAIN_MAIL_AUTOCOPY_TO); + foreach ($listofemailstoadd as $key => $val) { + $emailtoadd = $listofemailstoadd[$key]; + if (trim($emailtoadd) == '__USER_EMAIL__') { + if (!empty($user) && !empty($user->email)) { + $emailtoadd = $user->email; + } else { + $emailtoadd = ''; + } + } + if ($emailtoadd && preg_match('/'.preg_quote($emailtoadd, '/').'/i', $to)) { + $emailtoadd = ''; // Email already in the "To" + } + if ($emailtoadd) { + $listofemailstoadd[$key] = $emailtoadd; + } else { + unset($listofemailstoadd[$key]); + } + } + if (!empty($listofemailstoadd)) { + $addr_bcc .= ($addr_bcc ? ', ' : '').join(', ', $listofemailstoadd); + } } + $this->subject = $subject; $this->addr_to = $to; + $this->addr_from = $from; + $this->msg = $msg; + $this->filename_list = $filename_list; + $this->mimetype_list = $mimetype_list; + $this->mimefilename_list = $mimefilename_list; $this->addr_cc = $addr_cc; $this->addr_bcc = $addr_bcc; - $this->reply_to = $replyto; - $this->addr_from = $from; - $this->subject = $subject; - $this->errors_to = $errors_to; $this->deliveryreceipt = $deliveryreceipt; + if (empty($replyto)) { + $replyto = $from; + } + $this->reply_to = $replyto; + $this->errors_to = $errors_to; $this->trackid = $trackid; + $this->filename_list = $filename_list; + $this->mimetype_list = $mimetype_list; + $this->mimefilename_list = $mimefilename_list; if (!empty($conf->global->MAIN_MAIL_FORCE_SENDTO)) { $this->addr_to = $conf->global->MAIN_MAIL_FORCE_SENDTO; diff --git a/htdocs/core/class/CSMSFile.class.php b/htdocs/core/class/CSMSFile.class.php index 8d5bcf7dc50..3f082ba6d53 100644 --- a/htdocs/core/class/CSMSFile.class.php +++ b/htdocs/core/class/CSMSFile.class.php @@ -29,8 +29,9 @@ /** * Class to send SMS - * Usage: $smsfile = new CSMSFile($subject,$sendto,$replyto,$message,$filepath,$mimetype,$filename,$cc,$ccc,$deliveryreceipt,$msgishtml,$errors_to); - * $smsfile->sendfile(); + * Usage: $smsfile = new CSMSFile($subject,$sendto,$replyto,$message,$filepath,$mimetype,$filename,$cc,$ccc,$deliveryreceipt,$msgishtml,$errors_to); + * $smsfile->socid=...; $smsfile->contact_id=...; $smsfile->member_id=...; $smsfile->fk_project=...; + * $smsfile->sendfile(); */ class CSMSFile { @@ -48,7 +49,8 @@ class CSMSFile public $nostop; public $socid; - public $contactid; + public $contact_id; + public $member_id; public $fk_project; @@ -135,6 +137,7 @@ class CSMSFile $sms->socid = $this->socid; $sms->contact_id = $this->contact_id; + $sms->member_id = $this->member_id; $sms->project = $this->fk_project; $res = $sms->SmsSend(); @@ -167,6 +170,7 @@ class CSMSFile $sms->socid = $this->socid; $sms->contact_id = $this->contact_id; + $sms->member_id = $this->member_id; $sms->fk_project = $this->fk_project; $res = $sms->SmsSend(); diff --git a/htdocs/core/class/ccountry.class.php b/htdocs/core/class/ccountry.class.php index 4f448845e80..7b46b0a08b0 100644 --- a/htdocs/core/class/ccountry.class.php +++ b/htdocs/core/class/ccountry.class.php @@ -111,7 +111,7 @@ class Ccountry // extends CommonObject // Put here code to add control on parameters values // Insert request - $sql = "INSERT INTO ".MAIN_DB_PREFIX."c_country("; + $sql = "INSERT INTO ".$this->db->prefix()."c_country("; $sql .= "rowid,"; $sql .= "code,"; $sql .= "code_iso,"; @@ -135,7 +135,7 @@ class Ccountry // extends CommonObject } if (!$error) { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."c_country"); + $this->id = $this->db->last_insert_id($this->db->prefix()."c_country"); } // Commit or rollback @@ -169,7 +169,7 @@ class Ccountry // extends CommonObject $sql .= " t.code_iso,"; $sql .= " t.label,"; $sql .= " t.active"; - $sql .= " FROM ".MAIN_DB_PREFIX."c_country as t"; + $sql .= " FROM ".$this->db->prefix()."c_country as t"; if ($id) { $sql .= " WHERE t.rowid = ".((int) $id); } elseif ($code) { @@ -235,7 +235,7 @@ class Ccountry // extends CommonObject // Put here code to add control on parameters values // Update request - $sql = "UPDATE ".MAIN_DB_PREFIX."c_country SET"; + $sql = "UPDATE ".$this->db->prefix()."c_country SET"; $sql .= " code=".(isset($this->code) ? "'".$this->db->escape($this->code)."'" : "null").","; $sql .= " code_iso=".(isset($this->code_iso) ? "'".$this->db->escape($this->code_iso)."'" : "null").","; $sql .= " label=".(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").","; @@ -278,7 +278,7 @@ class Ccountry // extends CommonObject global $conf, $langs; $error = 0; - $sql = "DELETE FROM ".MAIN_DB_PREFIX."c_country"; + $sql = "DELETE FROM ".$this->db->prefix()."c_country"; $sql .= " WHERE rowid=".((int) $this->id); $this->db->begin(); diff --git a/htdocs/core/class/cgenericdic.class.php b/htdocs/core/class/cgenericdic.class.php new file mode 100644 index 00000000000..ab1023b81f5 --- /dev/null +++ b/htdocs/core/class/cgenericdic.class.php @@ -0,0 +1,478 @@ + + * Copyright (C) 2014-2016 Juanjo Menent + * Copyright (C) 2016 Florian Henry + * Copyright (C) 2015 Raphaël Doursenaud + * + * 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 . + */ + +/** + * \file htdocs/core/class/cgenericdic.class.php + * \ingroup resource + */ + +/** + * Class CGenericDic + * + * @see CommonObject + */ +class CGenericDic +{ + /** + * @var string Id to identify managed objects + */ + public $element = 'undefined'; // Will be defined into constructor + + /** + * @var string Name of table without prefix where object is stored + */ + public $table_element = 'undefined'; // Will be defined into constructor + + /** + * @var CtyperesourceLine[] Lines + */ + public $lines = array(); + + public $code; + + /** + * @var string Type resource label + */ + public $label; + + public $active; + + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + + // Don't forget to set this->element and this->table_element after the construction + } + + /** + * Create object into database + * + * @param User $user User that creates + * @param bool $notrigger false=launch triggers after, true=disable triggers + * + * @return int <0 if KO, Id of created object if OK + */ + public function create(User $user, $notrigger = false) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $fieldlabel = 'label'; + if ($this->table_element == 'c_stcomm') { + $fieldlabel = 'libelle'; + } + + $error = 0; + + // Clean parameters + + if (isset($this->code)) { + $this->code = trim($this->code); + } + if (isset($this->label)) { + $this->label = trim($this->label); + } + if (isset($this->active)) { + $this->active = trim($this->active); + } + + // Insert request + $sql = 'INSERT INTO '.$this->db->prefix().$this->table_element.'('; + $sql .= 'code,'; + $sql .= $fieldlabel; + $sql .= 'active'; + $sql .= ') VALUES ('; + $sql .= ' '.(!isset($this->code) ? 'NULL' : "'".$this->db->escape($this->code)."'").','; + $sql .= ' '.(!isset($this->label) ? 'NULL' : "'".$this->db->escape($this->label)."'").','; + $sql .= ' '.(!isset($this->active) ? 'NULL' : $this->active); + $sql .= ')'; + + $this->db->begin(); + + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); + } + + if (!$error) { + $this->id = $this->db->last_insert_id($this->db->prefix().$this->table_element); + + // Uncomment this and change CTYPERESOURCE to your own tag if you + // want this action to call a trigger. + //if (!$notrigger) { + + // // Call triggers + // $result=$this->call_trigger('CTYPERESOURCE_CREATE',$user); + // if ($result < 0) $error++; + // // End call triggers + //} + } + + // Commit or rollback + if ($error) { + $this->db->rollback(); + + return -1 * $error; + } else { + $this->db->commit(); + + return $this->id; + } + } + + /** + * Load object in memory from the database + * + * @param int $id Id object + * @param string $code code + * @param string $label Label + * + * @return int <0 if KO, 0 if not found, >0 if OK + */ + public function fetch($id, $code = '', $label = '') + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $fieldrowid = 'rowid'; + $fieldlabel = 'label'; + if ($this->table_element == 'c_stcomm') { + $fieldrowid = 'id'; + $fieldlabel = 'libelle'; + } + + $sql = "SELECT"; + $sql .= " t.".$fieldrowid.","; + $sql .= " t.code,"; + $sql .= " t.".$fieldlabel." as label,"; + $sql .= " t.active"; + $sql .= " FROM ".$this->db->prefix().$this->table_element." as t"; + if ($id) { + $sql .= " WHERE t.".$fieldrowid." = ".((int) $id); + } elseif ($code) { + $sql .= " WHERE t.code = '".$this->db->escape($code)."'"; + } elseif ($label) { + $sql .= " WHERE t.label = '".$this->db->escape($label)."'"; + } + + $resql = $this->db->query($sql); + if ($resql) { + $numrows = $this->db->num_rows($resql); + if ($numrows) { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->$fieldrowid; + + $this->code = $obj->code; + $this->label = $obj->label; + $this->active = $obj->active; + } + + // Retrieve all extrafields for invoice + // fetch optionals attributes and labels + // $this->fetch_optionals(); + + // $this->fetch_lines(); + + $this->db->free($resql); + + if ($numrows) { + return 1; + } else { + return 0; + } + } else { + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); + + return -1; + } + } + + /** + * Load object in memory from the database + * + * @param string $sortorder Sort Order + * @param string $sortfield Sort field + * @param int $limit offset limit + * @param int $offset offset limit + * @param array $filter filter array + * @param string $filtermode filter mode (AND or OR) + * + * @return int <0 if KO, >0 if OK + */ + public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $fieldrowid = 'rowid'; + $fieldlabel = 'label'; + if ($this->table_element == 'c_stcomm') { + $fieldrowid = 'id'; + $fieldlabel = 'libelle'; + } + + $sql = "SELECT"; + $sql .= " t.".$fieldrowid.","; + $sql .= " t.code,"; + $sql .= " t.".$fieldlabel." as label,"; + $sql .= " t.active"; + $sql .= " FROM ".$this->db->prefix().$this->table_element." as t"; + + // Manage filter + $sqlwhere = array(); + if (count($filter) > 0) { + foreach ($filter as $key => $value) { + $sqlwhere[] = $key." LIKE '%".$this->db->escape($value)."%'"; + } + } + + if (count($sqlwhere) > 0) { + $sql .= " WHERE ".implode(' '.$this->db->escape($filtermode).' ', $sqlwhere); + } + if (!empty($sortfield)) { + $sql .= $this->db->order($sortfield, $sortorder); + } + if (!empty($limit)) { + $sql .= $this->db->plimit($limit, $offset); + } + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + + while ($obj = $this->db->fetch_object($resql)) { + $line = new self($this->db); + + $line->id = $obj->$fieldrowid; + + $line->code = $obj->code; + $line->label = $obj->label; + $line->active = $obj->active; + } + $this->db->free($resql); + + return $num; + } else { + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); + + return -1; + } + } + + /** + * Update object into database + * + * @param User $user User that modifies + * @param bool $notrigger false=launch triggers after, true=disable triggers + * + * @return int <0 if KO, >0 if OK + */ + public function update(User $user, $notrigger = false) + { + $error = 0; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $fieldrowid = 'rowid'; + $fieldlabel = 'label'; + if ($this->table_element == 'c_stcomm') { + $fieldrowid = 'id'; + $fieldlabel = 'libelle'; + } + + // Clean parameters + + if (isset($this->code)) { + $this->code = trim($this->code); + } + if (isset($this->label)) { + $this->label = trim($this->label); + } + if (isset($this->active)) { + $this->active = trim($this->active); + } + + // Check parameters + // Put here code to add a control on parameters values + + // Update request + $sql = "UPDATE ".$this->db->prefix().$this->table_element.' SET'; + $sql .= " code = ".(isset($this->code) ? "'".$this->db->escape($this->code)."'" : "null").','; + $sql .= " ".$fieldlabel." = ".(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").','; + $sql .= " active = ".(isset($this->active) ? $this->active : "null"); + $sql .= " WHERE ".$fieldrowid." = ".((int) $this->id); + + $this->db->begin(); + + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); + } + + // Uncomment this and change CTYPERESOURCE to your own tag if you + // want this action calls a trigger. + //if (!$error && !$notrigger) { + + // // Call triggers + // $result=$this->call_trigger('CTYPERESOURCE_MODIFY',$user); + // if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} + // // End call triggers + //} + + // Commit or rollback + if ($error) { + $this->db->rollback(); + + return -1 * $error; + } else { + $this->db->commit(); + + return 1; + } + } + + /** + * Delete object in database + * + * @param User $user User that deletes + * @param bool $notrigger false=launch triggers after, true=disable triggers + * + * @return int <0 if KO, >0 if OK + */ + public function delete(User $user, $notrigger = false) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $fieldrowid = 'rowid'; + + $error = 0; + + $this->db->begin(); + + // Uncomment this and change CTYPERESOURCE to your own tag if you + // want this action calls a trigger. + //if (!$error && !$notrigger) { + + // // Call triggers + // $result=$this->call_trigger('CTYPERESOURCE_DELETE',$user); + // if ($result < 0) { $error++; //Do also what you must do to rollback action if trigger fail} + // // End call triggers + //} + + // If you need to delete child tables to, you can insert them here + + if (!$error) { + $sql = "DELETE FROM ".$this->db->prefix().$this->table_element; + $sql .= " WHERE ".$fieldrowid." = ".((int) $this->id); + + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = 'Error '.$this->db->lasterror(); + dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); + } + } + + // Commit or rollback + if ($error) { + $this->db->rollback(); + + return -1 * $error; + } else { + $this->db->commit(); + + return 1; + } + } + + /** + * Load an object from its id and create a new one in database + * + * @param User $user User making the clone + * @param int $fromid Id of object to clone + * @return int New id of clone + */ + public function createFromClone(User $user, $fromid) + { + dol_syslog(__METHOD__, LOG_DEBUG); + + $error = 0; + $object = new Ctyperesource($this->db); + + $this->db->begin(); + + // Load source object + $object->fetch($fromid); + // Reset object + $object->id = 0; + + // Clear fields + // ... + + // Create clone + $object->context['createfromclone'] = 'createfromclone'; + $result = $object->create($user); + + // Other options + if ($result < 0) { + $error++; + $this->errors = $object->errors; + dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); + } + + unset($object->context['createfromclone']); + + // End + if (!$error) { + $this->db->commit(); + + return $object->id; + } else { + $this->db->rollback(); + + return -1; + } + } + + /** + * Initialise object with example values + * Id must be 0 if object instance is a specimen + * + * @return void + */ + public function initAsSpecimen() + { + $this->id = 0; + + $this->code = 'CODE'; + $this->label = 'Label'; + $this->active = 1; + } +} diff --git a/htdocs/core/class/comment.class.php b/htdocs/core/class/comment.class.php index c2dd055522e..937ca6f7875 100644 --- a/htdocs/core/class/comment.class.php +++ b/htdocs/core/class/comment.class.php @@ -113,7 +113,7 @@ class Comment extends CommonObject $error = 0; // Insert request - $sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element." ("; + $sql = "INSERT INTO ".$this->db->prefix().$this->table_element." ("; $sql .= "description"; $sql .= ", datec"; $sql .= ", fk_element"; @@ -146,7 +146,7 @@ class Comment extends CommonObject } if (!$error) { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element); + $this->id = $this->db->last_insert_id($this->db->prefix().$this->table_element); if (!$notrigger) { // Call trigger @@ -195,7 +195,7 @@ class Comment extends CommonObject $sql .= " c.fk_user_modif,"; $sql .= " c.entity,"; $sql .= " c.import_key"; - $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as c"; + $sql .= " FROM ".$this->db->prefix().$this->table_element." as c"; $sql .= " WHERE c.rowid = ".((int) $id); dol_syslog(get_class($this)."::fetch", LOG_DEBUG); @@ -254,7 +254,7 @@ class Comment extends CommonObject // Update request - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; + $sql = "UPDATE ".$this->db->prefix().$this->table_element." SET"; $sql .= " description=".(isset($this->description) ? "'".$this->db->escape($this->description)."'" : "null").","; $sql .= " datec=".($this->datec != '' ? "'".$this->db->idate($this->datec)."'" : 'null').","; $sql .= " fk_element=".(isset($this->fk_element) ? $this->fk_element : "null").","; @@ -315,7 +315,7 @@ class Comment extends CommonObject $this->db->begin(); - $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element; + $sql = "DELETE FROM ".$this->db->prefix().$this->table_element; $sql .= " WHERE rowid=".((int) $this->id); $resql = $this->db->query($sql); @@ -364,7 +364,7 @@ class Comment extends CommonObject if (!empty($element_type) && !empty($fk_element)) { $sql = "SELECT"; $sql .= " c.rowid"; - $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as c"; + $sql .= " FROM ".$this->db->prefix().$this->table_element." as c"; $sql .= " WHERE c.fk_element = ".((int) $fk_element); $sql .= " AND c.element_type = '".$this->db->escape($element_type)."'"; $sql .= " AND c.entity = ".$conf->entity; diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 21c1cce4cfd..bee63613bca 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -60,6 +60,32 @@ abstract class CommonDocGenerator */ public $update_main_doc_field; + /** + * @var string The name of constant to use to scan ODT files (Exemple: 'COMMANDE_ADDON_PDF_ODT_PATH') + */ + public $scandir; + + public $page_hauteur; + public $page_largeur; + public $marge_gauche; + public $marge_droite; + public $marge_haute; + public $marge_basse; + + public $option_logo; + public $option_tva; + public $option_multilang; + public $option_freetext; + public $option_draft_watermark; + + public $option_modereg; + public $option_condreg; + public $option_escompte; + public $option_credit_note; + + public $emetteur; + + /** * Constructor * @@ -655,7 +681,7 @@ abstract class CommonDocGenerator if ($columns != "") { $columns = substr($columns, 0, strlen($columns) - 2); - $resql = $this->db->query("SELECT ".$columns." FROM ".MAIN_DB_PREFIX."product_fournisseur_price_extrafields AS ex INNER JOIN ".MAIN_DB_PREFIX."product_fournisseur_price AS f ON ex.fk_object = f.rowid WHERE f.ref_fourn = '".$this->db->escape($line->ref_supplier)."'"); + $resql = $this->db->query("SELECT ".$columns." FROM ".$this->db->prefix()."product_fournisseur_price_extrafields AS ex INNER JOIN ".$this->db->prefix()."product_fournisseur_price AS f ON ex.fk_object = f.rowid WHERE f.ref_fourn = '".$this->db->escape($line->ref_supplier)."'"); if ($this->db->num_rows($resql) > 0) { $resql = $this->db->fetch_object($resql); diff --git a/htdocs/core/class/commonincoterm.class.php b/htdocs/core/class/commonincoterm.class.php index d0485acc5a9..6c707141774 100644 --- a/htdocs/core/class/commonincoterm.class.php +++ b/htdocs/core/class/commonincoterm.class.php @@ -60,11 +60,13 @@ trait CommonIncoterm $this->label_incoterms = ''; if (!empty($this->fk_incoterms)) { - $sql = "SELECT code FROM ".MAIN_DB_PREFIX."c_incoterms WHERE rowid = ".(int) $this->fk_incoterms; + $sql = "SELECT code FROM ".$this->db->prefix()."c_incoterms WHERE rowid = ".(int) $this->fk_incoterms; $result = $this->db->query($sql); if ($result) { $res = $this->db->fetch_object($result); - $out .= $res->code; + if ($res) { + $out .= $res->code; + } } } @@ -76,17 +78,21 @@ trait CommonIncoterm /** * Return incoterms informations for pdf display * - * @return string incoterms info + * @return string|boolean Incoterms info or false */ public function getIncotermsForPDF() { - $sql = "SELECT code FROM ".MAIN_DB_PREFIX."c_incoterms WHERE rowid = ".(int) $this->fk_incoterms; + $sql = "SELECT code FROM ".$this->db->prefix()."c_incoterms WHERE rowid = ".(int) $this->fk_incoterms; $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); if ($num > 0) { $res = $this->db->fetch_object($resql); - return 'Incoterm : '.$res->code.' - '.$this->location_incoterms; + if ($res) { + return 'Incoterm : '.$res->code.' - '.$this->location_incoterms; + } else { + return $res; + } } else { return ''; } @@ -106,7 +112,7 @@ trait CommonIncoterm public function setIncoterms($id_incoterm, $location) { if ($this->id && $this->table_element) { - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql = "UPDATE ".$this->db->prefix().$this->table_element; $sql .= " SET fk_incoterms = ".($id_incoterm > 0 ? ((int) $id_incoterm) : "null"); $sql .= ", location_incoterms = ".($id_incoterm > 0 ? "'".$this->db->escape($location)."'" : "null"); $sql .= " WHERE rowid = ".((int) $this->id); @@ -116,7 +122,7 @@ trait CommonIncoterm $this->fk_incoterms = $id_incoterm; $this->location_incoterms = $location; - $sql = "SELECT libelle as label_incoterms FROM ".MAIN_DB_PREFIX."c_incoterms WHERE rowid = ".(int) $this->fk_incoterms; + $sql = "SELECT libelle as label_incoterms FROM ".$this->db->prefix()."c_incoterms WHERE rowid = ".(int) $this->fk_incoterms; $res = $this->db->query($sql); if ($res) { $obj = $this->db->fetch_object($res); diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index 6b617e2e08e..155b2ca5819 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -93,6 +93,19 @@ abstract class CommonInvoice extends CommonObject const STATUS_ABANDONED = 3; + public $totalpaid; // duplicate with sumpayed + public $totaldeposits; // duplicate with sumdeposit + public $totalcreditnotes; // duplicate with sumcreditnote + + public $sumpayed; + public $sumpayed_multicurrency; + public $sumdeposit; + public $sumdeposit_multicurrency; + public $sumcreditnote; + public $sumcreditnote_multicurrency; + public $remaintopay; + + /** * Return remain amount to pay. Property ->id and ->total_ttc must be set. * This does not include open direct debit requests. @@ -118,8 +131,8 @@ abstract class CommonInvoice extends CommonObject * Return amount of payments already done. This must include ONLY the record into the payment table. * Payments dones using discounts, credit notes, etc are not included. * - * @param int $multicurrency Return multicurrency_amount instead of amount - * @return float Amount of payment already done, <0 if KO + * @param int $multicurrency Return multicurrency_amount instead of amount + * @return float Amount of payment already done, <0 and set ->error if KO */ public function getSommePaiement($multicurrency = 0) { @@ -130,18 +143,21 @@ abstract class CommonInvoice extends CommonObject $field = 'fk_facturefourn'; } - $sql = 'SELECT sum(amount) as amount, sum(multicurrency_amount) as multicurrency_amount'; - $sql .= ' FROM '.MAIN_DB_PREFIX.$table; + $sql = "SELECT sum(amount) as amount, sum(multicurrency_amount) as multicurrency_amount"; + $sql .= " FROM ".$this->db->prefix().$table; $sql .= " WHERE ".$field." = ".((int) $this->id); dol_syslog(get_class($this)."::getSommePaiement", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $obj = $this->db->fetch_object($resql); + $this->db->free($resql); if ($multicurrency) { + $this->sumpayed_multicurrency = $obj->multicurrency_amount; return $obj->multicurrency_amount; } else { + $this->sumpayed = $obj->amount; return $obj->amount; } } else { @@ -154,13 +170,13 @@ abstract class CommonInvoice extends CommonObject * Return amount (with tax) of all deposits invoices used by invoice. * Should always be empty, except if option FACTURE_DEPOSITS_ARE_JUST_PAYMENTS is on (not recommended). * - * @param int $multicurrency Return multicurrency_amount instead of amount - * @return float <0 if KO, Sum of deposits amount otherwise + * @param int $multicurrency Return multicurrency_amount instead of amount + * @return float <0 and set ->error if KO, Sum of deposits amount otherwise */ public function getSumDepositsUsed($multicurrency = 0) { if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') { - // TODO + // FACTURE_DEPOSITS_ARE_JUST_PAYMENTS was never supported for purchase invoice, so we can return 0 with no need of SQL for this case. return 0.0; } @@ -170,6 +186,12 @@ abstract class CommonInvoice extends CommonObject $result = $discountstatic->getSumDepositsUsed($this, $multicurrency); if ($result >= 0) { + if ($multicurrency) { + $this->sumdeposit_multicurrency = $result; + } else { + $this->sumdeposit = $result; + } + return $result; } else { $this->error = $discountstatic->error; @@ -180,8 +202,8 @@ abstract class CommonInvoice extends CommonObject /** * Return amount (with tax) of all credit notes invoices + excess received used by invoice * - * @param int $multicurrency Return multicurrency_amount instead of amount - * @return float <0 if KO, Sum of credit notes and deposits amount otherwise + * @param int $multicurrency Return multicurrency_amount instead of amount + * @return float <0 and set ->error if KO, Sum of credit notes and deposits amount otherwise */ public function getSumCreditNotesUsed($multicurrency = 0) { @@ -190,6 +212,12 @@ abstract class CommonInvoice extends CommonObject $discountstatic = new DiscountAbsolute($this->db); $result = $discountstatic->getSumCreditNotesUsed($this, $multicurrency); if ($result >= 0) { + if ($multicurrency) { + $this->sumcreditnote_multicurrency = $result; + } else { + $this->sumcreditnote = $result; + } + return $result; } else { $this->error = $discountstatic->error; @@ -226,10 +254,10 @@ abstract class CommonInvoice extends CommonObject { $idarray = array(); - $sql = 'SELECT rowid'; - $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; + $sql = "SELECT rowid"; + $sql .= " FROM ".$this->db->prefix().$this->table_element; $sql .= " WHERE fk_facture_source = ".((int) $this->id); - $sql .= ' AND type = 2'; + $sql .= " AND type = 2"; $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -253,10 +281,10 @@ abstract class CommonInvoice extends CommonObject */ public function getIdReplacingInvoice($option = '') { - $sql = 'SELECT rowid'; - $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; + $sql = "SELECT rowid"; + $sql .= " FROM ".$this->db->prefix().$this->table_element; $sql .= " WHERE fk_facture_source = ".((int) $this->id); - $sql .= ' AND type < 2'; + $sql .= " AND type < 2"; if ($option == 'validated') { $sql .= ' AND fk_statut = 1'; } @@ -265,7 +293,7 @@ abstract class CommonInvoice extends CommonObject // and another no, priority is given to the valid one. // Should not happen (unless concurrent access and 2 people have created a // replacement invoice for the same invoice at the same time) - $sql .= ' ORDER BY fk_statut DESC'; + $sql .= " ORDER BY fk_statut DESC"; $resql = $this->db->query($sql); if ($resql) { @@ -308,7 +336,7 @@ abstract class CommonInvoice extends CommonObject } $sql = "SELECT p.ref, pf.amount, pf.multicurrency_amount, p.fk_paiement, p.datep, p.num_paiement as num, t.code".$field3; - $sql .= " FROM ".MAIN_DB_PREFIX.$table." as pf, ".MAIN_DB_PREFIX.$table2." as p, ".MAIN_DB_PREFIX."c_paiement as t"; + $sql .= " FROM ".$this->db->prefix().$table." as pf, ".$this->db->prefix().$table2." as p, ".$this->db->prefix()."c_paiement as t"; $sql .= " WHERE pf.".$field." = ".((int) $this->id); $sql .= " AND pf.".$field2." = p.rowid"; $sql .= ' AND p.fk_paiement = t.id'; @@ -337,12 +365,12 @@ abstract class CommonInvoice extends CommonObject $sql = ''; if ($this->element == 'facture' || $this->element == 'invoice') { $sql = "SELECT rc.amount_ttc as amount, rc.multicurrency_amount_ttc as multicurrency_amount, rc.datec as date, f.ref as ref, rc.description as type"; - $sql .= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except as rc, '.MAIN_DB_PREFIX.'facture as f'; + $sql .= ' FROM '.$this->db->prefix().'societe_remise_except as rc, '.$this->db->prefix().'facture as f'; $sql .= ' WHERE rc.fk_facture_source=f.rowid AND rc.fk_facture = '.((int) $this->id); $sql .= ' AND (f.type = 2 OR f.type = 0 OR f.type = 3)'; // Find discount coming from credit note or excess received or deposits (payments from deposits are always null except if FACTURE_DEPOSITS_ARE_JUST_PAYMENTS is set) } elseif ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') { $sql = "SELECT rc.amount_ttc as amount, rc.multicurrency_amount_ttc as multicurrency_amount, rc.datec as date, f.ref as ref, rc.description as type"; - $sql .= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except as rc, '.MAIN_DB_PREFIX.'facture_fourn as f'; + $sql .= ' FROM '.$this->db->prefix().'societe_remise_except as rc, '.$this->db->prefix().'facture_fourn as f'; $sql .= ' WHERE rc.fk_invoice_supplier_source=f.rowid AND rc.fk_invoice_supplier = '.((int) $this->id); $sql .= ' AND (f.type = 2 OR f.type = 0 OR f.type = 3)'; // Find discount coming from credit note or excess received or deposits (payments from deposits are always null except if FACTURE_DEPOSITS_ARE_JUST_PAYMENTS is set) } @@ -462,7 +490,7 @@ abstract class CommonInvoice extends CommonObject $type = 'supplier_invoice'; } - $sql = " SELECT COUNT(ab.rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as ab WHERE ab.doc_type='".$this->db->escape($type)."' AND ab.fk_doc = ".((int) $this->id); + $sql = " SELECT COUNT(ab.rowid) as nb FROM ".$this->db->prefix()."accounting_bookkeeping as ab WHERE ab.doc_type='".$this->db->escape($type)."' AND ab.fk_doc = ".((int) $this->id); $resql = $this->db->query($sql); if ($resql) { $obj = $this->db->fetch_object($resql); @@ -601,8 +629,8 @@ abstract class CommonInvoice extends CommonObject $cdr_type = 0; $cdr_decalage = 0; - $sqltemp = 'SELECT c.type_cdr, c.nbjour, c.decalage'; - $sqltemp .= ' FROM '.MAIN_DB_PREFIX.'c_payment_term as c'; + $sqltemp = "SELECT c.type_cdr, c.nbjour, c.decalage"; + $sqltemp .= " FROM ".$this->db->prefix()."c_payment_term as c"; if (is_numeric($cond_reglement)) { $sqltemp .= " WHERE c.rowid=".((int) $cond_reglement); } else { @@ -697,15 +725,15 @@ abstract class CommonInvoice extends CommonObject $bac = new CompanyBankAccount($this->db); $bac->fetch(0, $this->socid); - $sql = 'SELECT count(*)'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande'; + $sql = "SELECT count(*)"; + $sql .= " FROM ".$this->db->prefix()."prelevement_facture_demande"; if ($type == 'bank-transfer') { - $sql .= ' WHERE fk_facture_fourn = '.((int) $this->id); + $sql .= " WHERE fk_facture_fourn = ".((int) $this->id); } else { - $sql .= ' WHERE fk_facture = '.((int) $this->id); + $sql .= " WHERE fk_facture = ".((int) $this->id); } - $sql .= ' AND ext_payment_id IS NULL'; // To exclude record done for some online payments - $sql .= ' AND traite = 0'; + $sql .= " AND ext_payment_id IS NULL"; // To exclude record done for some online payments + $sql .= " AND traite = 0"; dol_syslog(get_class($this)."::demande_prelevement", LOG_DEBUG); $resql = $this->db->query($sql); @@ -714,21 +742,21 @@ abstract class CommonInvoice extends CommonObject if ($row[0] == 0) { $now = dol_now(); - $totalpaye = $this->getSommePaiement(); + $totalpaid = $this->getSommePaiement(); $totalcreditnotes = $this->getSumCreditNotesUsed(); $totaldeposits = $this->getSumDepositsUsed(); - //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits; + //print "totalpaid=".$totalpaid." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits; // We can also use bcadd to avoid pb with floating points // For example print 239.2 - 229.3 - 9.9; does not return 0. - //$resteapayer=bcadd($this->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT); + //$resteapayer=bcadd($this->total_ttc,$totalpaid,$conf->global->MAIN_MAX_DECIMALS_TOT); //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); if (empty($amount)) { - $amount = price2num($this->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); + $amount = price2num($this->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits, 'MT'); } if (is_numeric($amount) && $amount != 0) { - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'prelevement_facture_demande('; + $sql = 'INSERT INTO '.$this->db->prefix().'prelevement_facture_demande('; if ($type == 'bank-transfer') { $sql .= 'fk_facture_fourn, '; } else { @@ -800,7 +828,7 @@ abstract class CommonInvoice extends CommonObject public function demande_prelevement_delete($fuser, $did) { // phpcs:enable - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'prelevement_facture_demande'; + $sql = 'DELETE FROM '.$this->db->prefix().'prelevement_facture_demande'; $sql .= ' WHERE rowid = '.((int) $did); $sql .= ' AND traite = 0'; if ($this->db->query($sql)) { @@ -839,11 +867,11 @@ abstract class CommonInvoice extends CommonObject $pricewithtax = implode(unpack("H*", price2num($pricewithtaxstring, 2))); $pricetax = implode(unpack("H*", $pricetaxstring)); - var_dump(strlen($this->thirdparty->name)); - var_dump(str_pad(dechex('9'), 2, '0', STR_PAD_LEFT)); - var_dump($this->thirdparty->name); - var_dump(implode(unpack("H*", $this->thirdparty->name))); - var_dump(price($this->total_tva, 0, $tmplang, 0, -1, 2)); + //var_dump(strlen($this->thirdparty->name)); + //var_dump(str_pad(dechex('9'), 2, '0', STR_PAD_LEFT)); + //var_dump($this->thirdparty->name); + //var_dump(implode(unpack("H*", $this->thirdparty->name))); + //var_dump(price($this->total_tva, 0, $tmplang, 0, -1, 2)); $s = '01'.str_pad(dechex(strlen($this->thirdparty->name)), 2, '0', STR_PAD_LEFT).$name; $s .= '02'.str_pad(dechex(strlen($this->thirdparty->tva_intra)), 2, '0', STR_PAD_LEFT).$vatnumber; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index bd8ab4c22f4..b39facd16a4 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7,7 +7,7 @@ * Copyright (C) 2012-2015 Marcos García * Copyright (C) 2012-2015 Raphaël Doursenaud * Copyright (C) 2012 Cedric Salvador - * Copyright (C) 2015-2021 Alexandre Spangaro + * Copyright (C) 2015-2022 Alexandre Spangaro * Copyright (C) 2016 Bahfir abbes * Copyright (C) 2017 ATM Consulting * Copyright (C) 2017-2019 Nicolas ZABOURI @@ -15,6 +15,7 @@ * Copyright (C) 2018-2021 Frédéric France * Copyright (C) 2018 Josep Lluís Amador * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Grégory Blémand * * 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 @@ -42,6 +43,7 @@ */ abstract class CommonObject { + const TRIGGER_PREFIX = ''; // to be overriden in child class implementations, i.e. 'BILL', 'TASK', 'PROPAL', etc. /** * @var DoliDb Database handler (result of a new DoliDB) */ @@ -83,6 +85,11 @@ abstract class CommonObject */ public $element; + /** + * @var string Name to use for 'features' parameter to check module permissions with restrictedArea(). Undefined means same value than $element. + */ + public $element_for_permission; + /** * @var string Name of table without prefix where object is stored */ @@ -108,6 +115,16 @@ abstract class CommonObject */ public $array_languages = null; // Value is array() when load already tried + /** + * @var array To store result of ->liste_contact() + */ + public $contacts_ids; + + /** + * @var mixed Array of linked objects, set and used when calling ->create() to be able to create links during the creation of object + */ + public $linked_objects; + /** * @var int[][] Array of linked objects ids. Loaded by ->fetchObjectLinked */ @@ -118,6 +135,11 @@ abstract class CommonObject */ public $linkedObjects; + /** + * @var boolean Array of boolean with object id as key and value as true if linkedObjects full loaded. Loaded by ->fetchObjectLinked. Important for pdf generation time reduction. + */ + public $linkedObjectsFullLoaded = array(); + /** * @var Object To store a cloned copy of object before to edit it and keep track of old properties */ @@ -189,7 +211,7 @@ abstract class CommonObject public $user; /** - * @var string The type of originating object ('commande', 'facture', ...) + * @var string The type of originating object ('commande', 'facture', ...). Note: on some object this field is called $origin_type * @see fetch_origin() */ public $origin; @@ -536,7 +558,7 @@ abstract class CommonObject global $db, $conf; $sql = "SELECT rowid, ref, ref_ext"; - $sql .= " FROM ".MAIN_DB_PREFIX.$element; + $sql .= " FROM ".$db->prefix().$element; $sql .= " WHERE entity IN (".getEntity($element).")"; if ($id > 0) { @@ -681,13 +703,20 @@ abstract class CommonObject */ public function getKanbanView($option = '') { - $return = '
    '; + $return = '
    '; $return .= '
    '; $return .= ''; - $return .= ''; // Can be image + $return .= img_picto('', $this->picto); + //$return .= ''; // Can be image $return .= ''; $return .= '
    '; - $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + if (property_exists($this, 'label')) { + $return .= '
    '.$this->label.''; + } + if (method_exists($this, 'getLibStatut')) { + $return .= '
    '.$this->getLibStatut(5).'
    '; + } $return .= '
    '; $return .= '
    '; $return .= '
    '; @@ -1041,7 +1070,7 @@ abstract class CommonObject } else { // We look for id type_contact $sql = "SELECT tc.rowid"; - $sql .= " FROM ".MAIN_DB_PREFIX."c_type_contact as tc"; + $sql .= " FROM ".$this->db->prefix()."c_type_contact as tc"; $sql .= " WHERE tc.element='".$this->db->escape($this->element)."'"; $sql .= " AND tc.source='".$this->db->escape($source)."'"; $sql .= " AND tc.code='".$this->db->escape($type_contact)."' AND tc.active=1"; @@ -1079,7 +1108,7 @@ abstract class CommonObject $this->db->begin(); // Insert into database - $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_contact"; + $sql = "INSERT INTO ".$this->db->prefix()."element_contact"; $sql .= " (element_id, fk_socpeople, datecreate, statut, fk_c_type_contact) "; $sql .= " VALUES (".$this->id.", ".((int) $fk_socpeople)." , "; $sql .= "'".$this->db->idate($datecreate)."'"; @@ -1148,7 +1177,7 @@ abstract class CommonObject { // phpcs:enable // Insert into database - $sql = "UPDATE ".MAIN_DB_PREFIX."element_contact set"; + $sql = "UPDATE ".$this->db->prefix()."element_contact set"; $sql .= " statut = ".$statut; if ($type_contact_id) { $sql .= ", fk_c_type_contact = ".((int) $type_contact_id); @@ -1182,7 +1211,7 @@ abstract class CommonObject $this->db->begin(); - $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_contact"; + $sql = "DELETE FROM ".$this->db->prefix()."element_contact"; $sql .= " WHERE rowid = ".((int) $rowid); dol_syslog(get_class($this)."::delete_contact", LOG_DEBUG); @@ -1215,17 +1244,20 @@ abstract class CommonObject public function delete_linked_contact($source = '', $code = '') { // phpcs:enable + $listId = ''; $temp = array(); $typeContact = $this->liste_type_contact($source, '', 0, 0, $code); - foreach ($typeContact as $key => $value) { - array_push($temp, $key); + if (!empty($typeContact)) { + foreach ($typeContact as $key => $value) { + array_push($temp, $key); + } + $listId = implode(",", $temp); } - $listId = implode(",", $temp); - $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_contact"; + $sql = "DELETE FROM ".$this->db->prefix()."element_contact"; $sql .= " WHERE element_id = ".((int) $this->id); - if ($listId) { + if (!empty($listId)) { $sql .= " AND fk_c_type_contact IN (".$this->db->sanitize($listId).")"; } @@ -1264,13 +1296,13 @@ abstract class CommonObject } $sql .= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email"; $sql .= ", tc.source, tc.element, tc.code, tc.libelle"; - $sql .= " FROM ".MAIN_DB_PREFIX."c_type_contact tc"; - $sql .= ", ".MAIN_DB_PREFIX."element_contact ec"; + $sql .= " FROM ".$this->db->prefix()."c_type_contact tc"; + $sql .= ", ".$this->db->prefix()."element_contact ec"; if ($source == 'internal') { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user t on ec.fk_socpeople = t.rowid"; + $sql .= " LEFT JOIN ".$this->db->prefix()."user t on ec.fk_socpeople = t.rowid"; } if ($source == 'external' || $source == 'thirdparty') { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople t on ec.fk_socpeople = t.rowid"; + $sql .= " LEFT JOIN ".$this->db->prefix()."socpeople t on ec.fk_socpeople = t.rowid"; } $sql .= " WHERE ec.element_id = ".((int) $this->id); $sql .= " AND ec.fk_c_type_contact = tc.rowid"; @@ -1345,7 +1377,7 @@ abstract class CommonObject { $sql = "SELECT ec.datecreate, ec.statut, ec.fk_socpeople, ec.fk_c_type_contact,"; $sql .= " tc.code, tc.libelle"; - $sql .= " FROM (".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as tc)"; + $sql .= " FROM (".$this->db->prefix()."element_contact as ec, ".$this->db->prefix()."c_type_contact as tc)"; $sql .= " WHERE ec.rowid =".((int) $rowid); $sql .= " AND ec.fk_c_type_contact=tc.rowid"; $sql .= " AND tc.element = '".$this->db->escape($this->element)."'"; @@ -1390,7 +1422,7 @@ abstract class CommonObject $tab = array(); $sql = "SELECT DISTINCT tc.rowid, tc.code, tc.libelle, tc.position"; - $sql .= " FROM ".MAIN_DB_PREFIX."c_type_contact as tc"; + $sql .= " FROM ".$this->db->prefix()."c_type_contact as tc"; $sql .= " WHERE tc.element='".$this->db->escape($this->element)."'"; if ($activeonly == 1) { $sql .= " AND tc.active=1"; // only the active types @@ -1450,7 +1482,7 @@ abstract class CommonObject $tab = array(); $sql = "SELECT DISTINCT tc.rowid, tc.code, tc.libelle, tc.position, tc.element"; - $sql .= " FROM ".MAIN_DB_PREFIX."c_type_contact as tc"; + $sql .= " FROM ".$this->db->prefix()."c_type_contact as tc"; $sqlWhere = array(); if (!empty($element)) { @@ -1548,14 +1580,14 @@ abstract class CommonObject } $sql = "SELECT ec.fk_socpeople"; - $sql .= " FROM ".MAIN_DB_PREFIX."element_contact as ec,"; + $sql .= " FROM ".$this->db->prefix()."element_contact as ec,"; if ($source == 'internal') { - $sql .= " ".MAIN_DB_PREFIX."user as c,"; + $sql .= " ".$this->db->prefix()."user as c,"; } if ($source == 'external') { - $sql .= " ".MAIN_DB_PREFIX."socpeople as c,"; + $sql .= " ".$this->db->prefix()."socpeople as c,"; } - $sql .= " ".MAIN_DB_PREFIX."c_type_contact as tc"; + $sql .= " ".$this->db->prefix()."c_type_contact as tc"; $sql .= " WHERE ec.element_id = ".((int) $id); $sql .= " AND ec.fk_socpeople = c.rowid"; if ($source == 'internal') { @@ -1671,7 +1703,7 @@ abstract class CommonObject return 0; } - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$this->table_element." WHERE ".$this->table_ref_field." LIKE '".$this->db->escape($ref)."' LIMIT 1"; + $sql = "SELECT rowid FROM ".$this->db->prefix().$this->table_element." WHERE ".$this->table_ref_field." LIKE '".$this->db->escape($ref)."' LIMIT 1"; $query = $this->db->query($sql); @@ -1713,7 +1745,7 @@ abstract class CommonObject if ($idtype > 0) { if (empty($this->barcode_type) || empty($this->barcode_type_code) || empty($this->barcode_type_label) || empty($this->barcode_type_coder)) { // If data not already loaded $sql = "SELECT rowid, code, libelle as label, coder"; - $sql .= " FROM ".MAIN_DB_PREFIX."c_barcode_type"; + $sql .= " FROM ".$this->db->prefix()."c_barcode_type"; $sql .= " WHERE rowid = ".((int) $idtype); dol_syslog(get_class($this).'::fetch_barcode', LOG_DEBUG); $resql = $this->db->query($sql); @@ -1850,7 +1882,7 @@ abstract class CommonObject $result = false; - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$table; + $sql = "SELECT rowid FROM ".$this->db->prefix().$table; $sql .= " WHERE ".$field." = '".$this->db->escape($key)."'"; if (!empty($element)) { $sql .= " AND entity IN (".getEntity($element).")"; @@ -1883,7 +1915,7 @@ abstract class CommonObject { $result = false; if (!empty($id) && !empty($field) && !empty($table)) { - $sql = "SELECT ".$field." FROM ".MAIN_DB_PREFIX.$table; + $sql = "SELECT ".$field." FROM ".$this->db->prefix().$table; $sql .= " WHERE rowid = ".((int) $id); dol_syslog(get_class($this).'::getValueFrom', LOG_DEBUG); @@ -1941,7 +1973,7 @@ abstract class CommonObject $fk_user_field = 'fk_user_mod'; } - $sql = "UPDATE ".MAIN_DB_PREFIX.$table." SET "; + $sql = "UPDATE ".$this->db->prefix().$table." SET "; if ($format == 'text') { $sql .= $field." = '".$this->db->escape($value)."'"; @@ -2041,20 +2073,20 @@ abstract class CommonObject } $restrictiononfksoc = empty($this->restrictiononfksoc) ? 0 : $this->restrictiononfksoc; $sql = "SELECT MAX(te.".$fieldid.")"; - $sql .= " FROM ".(empty($nodbprefix) ?MAIN_DB_PREFIX:'').$this->table_element." as te"; + $sql .= " FROM ".(empty($nodbprefix) ?$this->db->prefix():'').$this->table_element." as te"; if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { - $sql .= ",".MAIN_DB_PREFIX."usergroup_user as ug"; + $sql .= ",".$this->db->prefix()."usergroup_user as ug"; } if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) { $tmparray = explode('@', $this->ismultientitymanaged); - $sql .= ", ".MAIN_DB_PREFIX.$tmparray[1]." as ".($tmparray[1] == 'societe' ? 's' : 'parenttable'); // If we need to link to this table to limit select to entity + $sql .= ", ".$this->db->prefix().$tmparray[1]." as ".($tmparray[1] == 'societe' ? 's' : 'parenttable'); // If we need to link to this table to limit select to entity } elseif ($restrictiononfksoc == 1 && $this->element != 'societe' && empty($user->rights->societe->client->voir) && !$socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to socid + $sql .= ", ".$this->db->prefix()."societe as s"; // If we need to link to societe to limit select to socid } elseif ($restrictiononfksoc == 2 && $this->element != 'societe' && empty($user->rights->societe->client->voir) && !$socid) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON te.fk_soc = s.rowid"; // If we need to link to societe to limit select to socid + $sql .= " LEFT JOIN ".$this->db->prefix()."societe as s ON te.fk_soc = s.rowid"; // If we need to link to societe to limit select to socid } if ($restrictiononfksoc && empty($user->rights->societe->client->voir) && !$socid) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$aliastablesociete.".rowid = sc.fk_soc"; + $sql .= " LEFT JOIN ".$this->db->prefix()."societe_commerciaux as sc ON ".$aliastablesociete.".rowid = sc.fk_soc"; } $sql .= " WHERE te.".$fieldid." < '".$this->db->escape($fieldid == 'rowid' ? $this->id : $this->ref)."'"; // ->ref must always be defined (set to id if field does not exists) if ($restrictiononfksoc == 1 && empty($user->rights->societe->client->voir) && !$socid) { @@ -2111,20 +2143,20 @@ abstract class CommonObject $this->ref_previous = $row[0]; $sql = "SELECT MIN(te.".$fieldid.")"; - $sql .= " FROM ".(empty($nodbprefix) ?MAIN_DB_PREFIX:'').$this->table_element." as te"; + $sql .= " FROM ".(empty($nodbprefix) ?$this->db->prefix():'').$this->table_element." as te"; if ($this->element == 'user' && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { - $sql .= ",".MAIN_DB_PREFIX."usergroup_user as ug"; + $sql .= ",".$this->db->prefix()."usergroup_user as ug"; } if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) { $tmparray = explode('@', $this->ismultientitymanaged); - $sql .= ", ".MAIN_DB_PREFIX.$tmparray[1]." as ".($tmparray[1] == 'societe' ? 's' : 'parenttable'); // If we need to link to this table to limit select to entity + $sql .= ", ".$this->db->prefix().$tmparray[1]." as ".($tmparray[1] == 'societe' ? 's' : 'parenttable'); // If we need to link to this table to limit select to entity } elseif ($restrictiononfksoc == 1 && $this->element != 'societe' && empty($user->rights->societe->client->voir) && !$socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to socid + $sql .= ", ".$this->db->prefix()."societe as s"; // If we need to link to societe to limit select to socid } elseif ($restrictiononfksoc == 2 && $this->element != 'societe' && empty($user->rights->societe->client->voir) && !$socid) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON te.fk_soc = s.rowid"; // If we need to link to societe to limit select to socid + $sql .= " LEFT JOIN ".$this->db->prefix()."societe as s ON te.fk_soc = s.rowid"; // If we need to link to societe to limit select to socid } if ($restrictiononfksoc && empty($user->rights->societe->client->voir) && !$socid) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$aliastablesociete.".rowid = sc.fk_soc"; + $sql .= " LEFT JOIN ".$this->db->prefix()."societe_commerciaux as sc ON ".$aliastablesociete.".rowid = sc.fk_soc"; } $sql .= " WHERE te.".$fieldid." > '".$this->db->escape($fieldid == 'rowid' ? $this->id : $this->ref)."'"; // ->ref must always be defined (set to id if field does not exists) if ($restrictiononfksoc == 1 && empty($user->rights->societe->client->voir) && !$socid) { @@ -2214,16 +2246,20 @@ abstract class CommonObject * Link element with a project * * @param int $projectid Project id to link element to + * @param int $notrigger Disable the trigger * @return int <0 if KO, >0 if OK */ - public function setProject($projectid) + public function setProject($projectid, $notrigger = 0) { + global $user; + $error = 0; + if (!$this->table_element) { dol_syslog(get_class($this)."::setProject was called on objet with property table_element not defined", LOG_ERR); return -1; } - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql = "UPDATE ".$this->db->prefix().$this->table_element; if (!empty($this->fields['fk_project'])) { // Common case if ($projectid) { $sql .= " SET fk_project = ".((int) $projectid); @@ -2248,13 +2284,33 @@ abstract class CommonObject $sql .= " WHERE rowid = ".((int) $this->id); } + $this->db->begin(); + dol_syslog(get_class($this)."::setProject", LOG_DEBUG); if ($this->db->query($sql)) { $this->fk_project = ((int) $projectid); - return 1; } else { dol_print_error($this->db); + $error++; + } + + // Triggers + if (!$error && !$notrigger) { + // Call triggers + $result = $this->call_trigger(strtoupper($this->element) . '_MODIFY', $user); + if ($result < 0) { + $error++; + } //Do also here what you must do to rollback action if trigger fail + // End call triggers + } + + // Commit or rollback + if ($error) { + $this->db->rollback(); return -1; + } else { + $this->db->commit(); + return 1; } } @@ -2288,7 +2344,7 @@ abstract class CommonObject $fieldname = 'fk_typepayment'; } - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql = "UPDATE ".$this->db->prefix().$this->table_element; $sql .= " SET ".$fieldname." = ".(($id > 0 || $id == '0') ? ((int) $id) : 'NULL'); $sql .= ' WHERE rowid='.((int) $this->id); @@ -2336,7 +2392,7 @@ abstract class CommonObject if ($this->statut >= 0 || $this->element == 'societe') { $fieldname = 'multicurrency_code'; - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql = 'UPDATE '.$this->db->prefix().$this->table_element; $sql .= " SET ".$fieldname." = '".$this->db->escape($code)."'"; $sql .= ' WHERE rowid='.((int) $this->id); @@ -2374,7 +2430,7 @@ abstract class CommonObject if ($this->statut >= 0 || $this->element == 'societe') { $fieldname = 'multicurrency_tx'; - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql = 'UPDATE '.$this->db->prefix().$this->table_element; $sql .= " SET ".$fieldname." = ".((float) $rate); $sql .= ' WHERE rowid='.((int) $this->id); @@ -2566,12 +2622,13 @@ abstract class CommonObject /** * Change the payments terms * - * @param int $id Id of new payment terms - * @return int >0 if OK, <0 if KO + * @param int $id Id of new payment terms + * @param string $deposit_percent % of deposit if needed by payment terms + * @return int >0 if OK, <0 if KO */ - public function setPaymentTerms($id) + public function setPaymentTerms($id, $deposit_percent = null) { - dol_syslog(get_class($this).'::setPaymentTerms('.$id.')'); + dol_syslog(get_class($this).'::setPaymentTerms('.$id.', '.var_export($deposit_percent, true).')'); if ($this->statut >= 0 || $this->element == 'societe') { // TODO uniformize field name $fieldname = 'fk_cond_reglement'; @@ -2582,8 +2639,19 @@ abstract class CommonObject $fieldname = 'cond_reglement_supplier'; } - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + if (empty($deposit_percent) || $deposit_percent < 0) { + $deposit_percent = getDictionaryValue('c_payment_term', 'deposit_percent', $id); + } + + if ($deposit_percent > 100) { + $deposit_percent = 100; + } + + $sql = 'UPDATE '.$this->db->prefix().$this->table_element; $sql .= " SET ".$fieldname." = ".(($id > 0 || $id == '0') ? ((int) $id) : 'NULL'); + if (in_array($this->table_element, array('propal', 'commande'))) { + $sql .= " , deposit_percent = " . (empty($deposit_percent) ? 'NULL' : "'".$this->db->escape($deposit_percent)."'"); + } $sql .= ' WHERE rowid='.((int) $this->id); if ($this->db->query($sql)) { @@ -2593,6 +2661,7 @@ abstract class CommonObject $this->cond_reglement_supplier_id = $id; } $this->cond_reglement = $id; // for compatibility + $this->deposit_percent = $deposit_percent; return 1; } else { dol_syslog(get_class($this).'::setPaymentTerms Error '.$sql.' - '.$this->db->error()); @@ -2624,7 +2693,7 @@ abstract class CommonObject $fieldname = 'transport_mode_supplier'; } - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql = 'UPDATE '.$this->db->prefix().$this->table_element; $sql .= " SET ".$fieldname." = ".(($id > 0 || $id == '0') ? ((int) $id) : 'NULL'); $sql .= ' WHERE rowid='.((int) $this->id); @@ -2659,7 +2728,7 @@ abstract class CommonObject if ($this->statut >= 0 || $this->element == 'societe') { $fieldname = 'retained_warranty_fk_cond_reglement'; - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql = 'UPDATE '.$this->db->prefix().$this->table_element; $sql .= " SET ".$fieldname." = ".((int) $id); $sql .= ' WHERE rowid='.((int) $this->id); @@ -2692,7 +2761,7 @@ abstract class CommonObject $fieldname = 'fk_address'; } - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET ".$fieldname." = ".((int) $id); + $sql = "UPDATE ".$this->db->prefix().$this->table_element." SET ".$fieldname." = ".((int) $id); $sql .= " WHERE rowid = ".((int) $this->id)." AND fk_statut = 0"; if ($this->db->query($sql)) { @@ -2737,7 +2806,7 @@ abstract class CommonObject } dol_syslog(get_class($this).'::setShippingMethod('.$shipping_method_id.')'); - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql = "UPDATE ".$this->db->prefix().$this->table_element; $sql .= " SET fk_shipping_method = ".((int) $shipping_method_id); $sql .= " WHERE rowid=".((int) $this->id); $resql = $this->db->query($sql); @@ -2784,7 +2853,7 @@ abstract class CommonObject } dol_syslog(get_class($this).'::setWarehouse('.$warehouse_id.')'); - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql = "UPDATE ".$this->db->prefix().$this->table_element; $sql .= " SET fk_warehouse = ".((int) $warehouse_id); $sql .= " WHERE rowid=".((int) $this->id); @@ -2815,7 +2884,7 @@ abstract class CommonObject $newmodelpdf = dol_trunc($modelpdf, 255); - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql = "UPDATE ".$this->db->prefix().$this->table_element; $sql .= " SET model_pdf = '".$this->db->escape($newmodelpdf)."'"; $sql .= " WHERE rowid = ".((int) $this->id); @@ -2861,7 +2930,7 @@ abstract class CommonObject } dol_syslog(get_class($this).'::setBankAccount('.$fk_account.')'); - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql = "UPDATE ".$this->db->prefix().$this->table_element; $sql .= " SET fk_account = ".((int) $fk_account); $sql .= " WHERE rowid=".((int) $this->id); @@ -2916,15 +2985,20 @@ abstract class CommonObject return -1; } + $fieldposition = 'rang'; // @todo Rename 'rang' into 'position' + if (in_array($this->table_element_line, array('bom_bomline', 'ecm_files', 'emailcollector_emailcollectoraction', 'product_attribute_value'))) { + $fieldposition = 'position'; + } + // Count number of lines to reorder (according to choice $renum) $nl = 0; - $sql = "SELECT count(rowid) FROM ".MAIN_DB_PREFIX.$this->table_element_line; + $sql = "SELECT count(rowid) FROM ".$this->db->prefix().$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); if (!$renum) { - $sql .= ' AND rang = 0'; + $sql .= " AND " . $fieldposition . " = 0"; } if ($renum) { - $sql .= ' AND rang <> 0'; + $sql .= " AND " . $fieldposition . " <> 0"; } dol_syslog(get_class($this)."::line_order", LOG_DEBUG); @@ -2940,12 +3014,12 @@ abstract class CommonObject $rows = array(); // We first search all lines that are parent lines (for multilevel details lines) - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$this->table_element_line; + $sql = "SELECT rowid FROM ".$this->db->prefix().$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); if ($fk_parent_line) { $sql .= ' AND fk_parent_line IS NULL'; } - $sql .= " ORDER BY rang ASC, rowid ".$rowidorder; + $sql .= " ORDER BY " . $fieldposition . " ASC, rowid " . $rowidorder; dol_syslog(get_class($this)."::line_order search all parent lines", LOG_DEBUG); $resql = $this->db->query($sql); @@ -2986,12 +3060,17 @@ abstract class CommonObject */ public function getChildrenOfLine($id, $includealltree = 0) { + $fieldposition = 'rang'; // @todo Rename 'rang' into 'position' + if (in_array($this->table_element_line, array('bom_bomline', 'ecm_files', 'emailcollector_emailcollectoraction', 'product_attribute_value'))) { + $fieldposition = 'position'; + } + $rows = array(); - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$this->table_element_line; + $sql = "SELECT rowid FROM ".$this->db->prefix().$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); $sql .= ' AND fk_parent_line = '.((int) $id); - $sql .= ' ORDER BY rang ASC'; + $sql .= " ORDER BY " . $fieldposition . " ASC"; dol_syslog(get_class($this)."::getChildrenOfLine search children lines for line ".$id, LOG_DEBUG); $resql = $this->db->query($sql); @@ -3062,11 +3141,11 @@ abstract class CommonObject { global $hookmanager; $fieldposition = 'rang'; // @todo Rename 'rang' into 'position' - if (in_array($this->table_element_line, array('bom_bomline', 'ecm_files', 'emailcollector_emailcollectoraction'))) { + if (in_array($this->table_element_line, array('bom_bomline', 'ecm_files', 'emailcollector_emailcollectoraction', 'product_attribute_value'))) { $fieldposition = 'position'; } - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element_line." SET ".$fieldposition." = ".((int) $rang); + $sql = "UPDATE ".$this->db->prefix().$this->table_element_line." SET ".$fieldposition." = ".((int) $rang); $sql .= ' WHERE rowid = '.((int) $rowid); dol_syslog(get_class($this)."::updateRangOfLine", LOG_DEBUG); @@ -3108,15 +3187,15 @@ abstract class CommonObject { if ($rang > 1) { $fieldposition = 'rang'; - if (in_array($this->table_element_line, array('ecm_files', 'emailcollector_emailcollectoraction'))) { + if (in_array($this->table_element_line, array('ecm_files', 'emailcollector_emailcollectoraction', 'product_attribute_value'))) { $fieldposition = 'position'; } - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element_line." SET ".$fieldposition." = ".((int) $rang); + $sql = "UPDATE ".$this->db->prefix().$this->table_element_line." SET ".$fieldposition." = ".((int) $rang); $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); - $sql .= ' AND rang = '.((int) ($rang - 1)); + $sql .= " AND " . $fieldposition . " = " . ((int) ($rang - 1)); if ($this->db->query($sql)) { - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element_line." SET ".$fieldposition." = ".((int) ($rang - 1)); + $sql = "UPDATE ".$this->db->prefix().$this->table_element_line." SET ".$fieldposition." = ".((int) ($rang - 1)); $sql .= ' WHERE rowid = '.((int) $rowid); if (!$this->db->query($sql)) { dol_print_error($this->db); @@ -3139,15 +3218,15 @@ abstract class CommonObject { if ($rang < $max) { $fieldposition = 'rang'; - if (in_array($this->table_element_line, array('ecm_files', 'emailcollector_emailcollectoraction'))) { + if (in_array($this->table_element_line, array('ecm_files', 'emailcollector_emailcollectoraction', 'product_attribute_value'))) { $fieldposition = 'position'; } - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element_line." SET ".$fieldposition." = ".((int) $rang); + $sql = "UPDATE ".$this->db->prefix().$this->table_element_line." SET ".$fieldposition." = ".((int) $rang); $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); - $sql .= ' AND rang = '.((int) ($rang + 1)); + $sql .= " AND " . $fieldposition . " = " . ((int) ($rang + 1)); if ($this->db->query($sql)) { - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element_line." SET ".$fieldposition." = ".((int) ($rang + 1)); + $sql = "UPDATE ".$this->db->prefix().$this->table_element_line." SET ".$fieldposition." = ".((int) ($rang + 1)); $sql .= ' WHERE rowid = '.((int) $rowid); if (!$this->db->query($sql)) { dol_print_error($this->db); @@ -3166,7 +3245,12 @@ abstract class CommonObject */ public function getRangOfLine($rowid) { - $sql = "SELECT rang FROM ".MAIN_DB_PREFIX.$this->table_element_line; + $fieldposition = 'rang'; + if (in_array($this->table_element_line, array('ecm_files', 'emailcollector_emailcollectoraction', 'product_attribute_value'))) { + $fieldposition = 'position'; + } + + $sql = "SELECT " . $fieldposition . " FROM ".$this->db->prefix().$this->table_element_line; $sql .= " WHERE rowid = ".((int) $rowid); dol_syslog(get_class($this)."::getRangOfLine", LOG_DEBUG); @@ -3185,9 +3269,14 @@ abstract class CommonObject */ public function getIdOfLine($rang) { - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$this->table_element_line; + $fieldposition = 'rang'; + if (in_array($this->table_element_line, array('ecm_files', 'emailcollector_emailcollectoraction', 'product_attribute_value'))) { + $fieldposition = 'position'; + } + + $sql = "SELECT rowid FROM ".$this->db->prefix().$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); - $sql .= " AND rang = ".((int) $rang); + $sql .= " AND " . $fieldposition . " = ".((int) $rang); $resql = $this->db->query($sql); if ($resql) { $row = $this->db->fetch_row($resql); @@ -3206,13 +3295,13 @@ abstract class CommonObject { // phpcs:enable $positionfield = 'rang'; - if ($this->table_element == 'bom_bom') { + if (in_array($this->table_element, array('bom_bom', 'product_attribute'))) { $positionfield = 'position'; } // Search the last rang with fk_parent_line if ($fk_parent_line) { - $sql = "SELECT max(".$positionfield.") FROM ".MAIN_DB_PREFIX.$this->table_element_line; + $sql = "SELECT max(".$positionfield.") FROM ".$this->db->prefix().$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); $sql .= " AND fk_parent_line = ".((int) $fk_parent_line); @@ -3228,7 +3317,7 @@ abstract class CommonObject } } else { // If not, search the last rang of element - $sql = "SELECT max(".$positionfield.") FROM ".MAIN_DB_PREFIX.$this->table_element_line; + $sql = "SELECT max(".$positionfield.") FROM ".$this->db->prefix().$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); dol_syslog(get_class($this)."::line_max", LOG_DEBUG); @@ -3255,7 +3344,7 @@ abstract class CommonObject return -1; } - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql = "UPDATE ".$this->db->prefix().$this->table_element; $sql .= " SET ref_ext = '".$this->db->escape($ref_ext)."'"; $sql .= " WHERE ".(isset($this->table_rowid) ? $this->table_rowid : 'rowid')." = ".((int) $this->id); @@ -3306,7 +3395,7 @@ abstract class CommonObject } else { $fieldusermod = "fk_user_modif"; } - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql = "UPDATE ".$this->db->prefix().$this->table_element; $sql .= " SET note".$newsuffix." = ".(!empty($note) ? ("'".$this->db->escape($note)."'") : "NULL"); $sql .= ", ".$fieldusermod." = ".((int) $user->id); $sql .= " WHERE rowid = ".((int) $this->id); @@ -3349,9 +3438,9 @@ abstract class CommonObject * Must be called at end of methods addline or updateline. * * @param int $exclspec >0 = Exclude special product (product_type=9) - * @param string $roundingadjust 'none'=Do nothing, 'auto'=Use default method (MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND if defined, or '0'), '0'=Force mode total of rounding, '1'=Force mode rounding of total + * @param string $roundingadjust 'none'=Do nothing, 'auto'=Use default method (MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND if defined, or '0'), '0'=Force mode Total of rounding, '1'=Force mode Rounding of total * @param int $nodatabaseupdate 1=Do not update database. Update only properties of object. - * @param Societe $seller If roundingadjust is '0' or '1' or maybe 'auto', it means we recalculate total for lines before calculating total for object and for this, we need seller object. + * @param Societe $seller If roundingadjust is '0' or '1' or maybe 'auto', it means we recalculate total for lines before calculating total for object and for this, we need seller object (used to analyze lines to check corrupted data). * @return int <0 if KO, >0 if OK */ public function update_price($exclspec = 0, $roundingadjust = 'none', $nodatabaseupdate = 0, $seller = null) @@ -3375,7 +3464,7 @@ abstract class CommonObject $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_ORDER"; } elseif ($this->element == 'facture' || $this->element == 'invoice') { $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_INVOICE"; - } elseif ($this->element == 'facture_fourn' || $this->element == 'supplier_invoice' || $this->element == 'invoice_supplier') { + } elseif ($this->element == 'facture_fourn' || $this->element == 'supplier_invoice' || $this->element == 'invoice_supplier' || $this->element == 'invoice_supplier_rec') { $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_SUPPLIER_INVOICE"; } elseif ($this->element == 'order_supplier' || $this->element == 'supplier_order') { $MODULE = "MODULE_DISALLOW_UPDATE_PRICE_SUPPLIER_ORDER"; @@ -3420,6 +3509,9 @@ abstract class CommonObject $fieldtva = 'tva'; $fieldup = 'pu_ht'; } + if ($this->element == 'invoice_supplier_rec') { + $fieldup = 'pu_ht'; + } if ($this->element == 'expensereport') { $fieldup = 'value_unit'; } @@ -3430,7 +3522,7 @@ abstract class CommonObject $sql .= ', situation_percent'; } $sql .= ', multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc'; - $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element_line; + $sql .= " FROM ".$this->db->prefix().$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); if ($exclspec) { $product_field = 'product_type'; @@ -3478,7 +3570,7 @@ abstract class CommonObject //var_dump($diff_when_using_price_ht.' '.$diff_on_current_total); if ($diff_when_using_price_ht && $diff_on_current_total) { - $sqlfix = "UPDATE ".MAIN_DB_PREFIX.$this->table_element_line." SET ".$fieldtva." = ".price2num((float) $tmpcal[1]).", total_ttc = ".price2num((float) $tmpcal[2])." WHERE rowid = ".((int) $obj->rowid); + $sqlfix = "UPDATE ".$this->db->prefix().$this->table_element_line." SET ".$fieldtva." = ".price2num((float) $tmpcal[1]).", total_ttc = ".price2num((float) $tmpcal[2])." WHERE rowid = ".((int) $obj->rowid); dol_syslog('We found unconsistent data into detailed line (diff_when_using_price_ht = '.$diff_when_using_price_ht.' and diff_on_current_total = '.$diff_on_current_total.') for line rowid = '.$obj->rowid." (total vat of line calculated=".$tmpcal[1].", database=".$obj->total_tva."). We fix the total_vat and total_ttc of line by running sqlfix = ".$sqlfix, LOG_WARNING); $resqlfix = $this->db->query($sqlfix); if (!$resqlfix) { @@ -3522,7 +3614,7 @@ abstract class CommonObject dol_print_error('', $errmsg); exit; } - $sqlfix = "UPDATE ".MAIN_DB_PREFIX.$this->table_element_line." SET ".$fieldtva." = ".price2num($obj->total_tva - $diff).", total_ttc = ".price2num($obj->total_ttc - $diff)." WHERE rowid = ".((int) $obj->rowid); + $sqlfix = "UPDATE ".$this->db->prefix().$this->table_element_line." SET ".$fieldtva." = ".price2num($obj->total_tva - $diff).", total_ttc = ".price2num($obj->total_ttc - $diff)." WHERE rowid = ".((int) $obj->rowid); dol_syslog('We found a difference of '.$diff.' for line rowid = '.$obj->rowid.". We fix the total_vat and total_ttc of line by running sqlfix = ".$sqlfix); $resqlfix = $this->db->query($sqlfix); if (!$resqlfix) { @@ -3570,7 +3662,7 @@ abstract class CommonObject if ($this->element == 'facture' || $this->element == 'facturerec') { $fieldtva = 'total_tva'; } - if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') { + if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier' || $this->element == 'invoice_supplier_rec') { $fieldtva = 'total_tva'; } if ($this->element == 'propal') { @@ -3590,7 +3682,7 @@ abstract class CommonObject } if (empty($nodatabaseupdate)) { - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element.' SET'; + $sql = "UPDATE ".$this->db->prefix().$this->table_element.' SET'; $sql .= " ".$fieldht." = ".((float) price2num($this->total_ht)).","; $sql .= " ".$fieldtva." = ".((float) price2num($this->total_tva)).","; $sql .= " ".$fieldlocaltax1." = ".((float) price2num($this->total_localtax1)).","; @@ -3657,7 +3749,7 @@ abstract class CommonObject // Elements of the core modules which have `$module` property but may to which we don't want to prefix module part to the element name for finding the linked object in llx_element_element. // It's because an entry for this element may be exist in llx_element_element before this modification (version <=14.2) and ave named only with their element name in fk_source or fk_target. - $coremodule = array('knowledgemanagement', 'partnership', 'workstation', 'ticket', 'recruitment', 'eventorganization'); + $coremodule = array('knowledgemanagement', 'partnership', 'workstation', 'ticket', 'recruitment', 'eventorganization', 'asset'); // Add module part to target type if object has $module property and isn't in core modules. $targettype = ((!empty($this->module) && ! in_array($this->module, $coremodule)) ? $this->module.'_' : '').$this->element; @@ -3671,7 +3763,7 @@ abstract class CommonObject $this->db->begin(); $error = 0; - $sql = "INSERT INTO " . MAIN_DB_PREFIX . "element_element ("; + $sql = "INSERT INTO " . $this->db->prefix() . "element_element ("; $sql .= "fk_source"; $sql .= ", sourcetype"; $sql .= ", fk_target"; @@ -3735,6 +3827,12 @@ abstract class CommonObject { global $conf, $hookmanager, $action; + // Important for pdf generation time reduction + // This boolean is true if $this->linkedObjects has already been loaded with all objects linked without filter + if ($this->id > 0 && !empty($this->linkedObjectsFullLoaded[$this->id])) { + return 1; + } + $this->linkedObjectsIds = array(); $this->linkedObjects = array(); @@ -3778,8 +3876,8 @@ abstract class CommonObject }*/ // Links between objects are stored in table element_element - $sql = 'SELECT rowid, fk_source, sourcetype, fk_target, targettype'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'element_element'; + $sql = "SELECT rowid, fk_source, sourcetype, fk_target, targettype"; + $sql .= " FROM ".$this->db->prefix()."element_element"; $sql .= " WHERE "; if ($justsource || $justtarget) { if ($justsource) { @@ -3796,8 +3894,11 @@ abstract class CommonObject } else { $sql .= "(fk_source = ".((int) $sourceid)." AND sourcetype = '".$this->db->escape($sourcetype)."')"; $sql .= " ".$clause." (fk_target = ".((int) $targetid)." AND targettype = '".$this->db->escape($targettype)."')"; + if ($loadalsoobjects && $this->id > 0 && $sourceid == $this->id && $sourcetype == $this->element && $targetid == $this->id && $targettype == $this->element && $clause == 'OR') { + $this->linkedObjectsFullLoaded[$this->id] = true; + } } - $sql .= ' ORDER BY '.$orderby; + $sql .= " ORDER BY ".$orderby; dol_syslog(get_class($this)."::fetchObjectLink", LOG_DEBUG); $resql = $this->db->query($sql); @@ -3965,7 +4066,7 @@ abstract class CommonObject $this->db->begin(); $error = 0; - $sql = "UPDATE " . MAIN_DB_PREFIX . "element_element SET "; + $sql = "UPDATE " . $this->db->prefix() . "element_element SET "; if ($updatesource) { $sql .= "fk_source = " . ((int) $sourceid); $sql .= ", sourcetype = '" . $this->db->escape($sourcetype) . "'"; @@ -3986,7 +4087,7 @@ abstract class CommonObject $this->context['link_source_type'] = $sourcetype; $this->context['link_target_id'] = $targetid; $this->context['link_target_type'] = $targettype; - $result = $this->call_trigger('OBJECT_LINK_UPDATE', $f_user); + $result = $this->call_trigger('OBJECT_LINK_MODIFY', $f_user); if ($result < 0) { $error++; } @@ -4054,7 +4155,7 @@ abstract class CommonObject } if (!$error) { - $sql = "DELETE FROM " . MAIN_DB_PREFIX . "element_element"; + $sql = "DELETE FROM " . $this->db->prefix() . "element_element"; $sql .= " WHERE"; if ($rowid > 0) { $sql .= " rowid = " . ((int) $rowid); @@ -4106,7 +4207,7 @@ abstract class CommonObject global $db; - $sql = "SELECT ".$field_select." FROM ".MAIN_DB_PREFIX.$table_element." WHERE ".$field_where." = ".((int) $fk_object_where); + $sql = "SELECT ".$field_select." FROM ".$db->prefix().$table_element." WHERE ".$field_where." = ".((int) $fk_object_where); $resql = $db->query($sql); $TRes = array(); @@ -4135,7 +4236,7 @@ abstract class CommonObject global $db; - $sql = "DELETE FROM ".MAIN_DB_PREFIX.$table_element." WHERE ".$field_where." = ".((int) $fk_object_where); + $sql = "DELETE FROM ".$db->prefix().$table_element." WHERE ".$field_where." = ".((int) $fk_object_where); $resql = $db->query($sql); if (empty($resql)) { @@ -4188,7 +4289,7 @@ abstract class CommonObject $fieldstatus = 'status'; } - $sql = "UPDATE ".MAIN_DB_PREFIX.$elementTable; + $sql = "UPDATE ".$this->db->prefix().$elementTable; $sql .= " SET ".$fieldstatus." = ".((int) $status); // If status = 1 = validated, update also fk_user_valid // TODO Replace the test on $elementTable by doing a test on existence of the field in $this->fields @@ -4289,7 +4390,7 @@ abstract class CommonObject $ref = trim($ref); $sql = "SELECT rowid, canvas"; - $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " FROM ".$this->db->prefix().$this->table_element; $sql .= " WHERE entity IN (".getEntity($this->element).")"; if (!empty($id)) { $sql .= " AND rowid = ".((int) $id); @@ -4322,7 +4423,7 @@ abstract class CommonObject */ public function getSpecialCode($lineid) { - $sql = "SELECT special_code FROM ".MAIN_DB_PREFIX.$this->table_element_line; + $sql = "SELECT special_code FROM ".$this->db->prefix().$this->table_element_line; $sql .= " WHERE rowid = ".((int) $lineid); $resql = $this->db->query($sql); if ($resql) { @@ -4336,9 +4437,10 @@ abstract class CommonObject * Check is done into this->childtables. There is no check into llx_element_element. * * @param int $id Force id of object + * @param int $entity Force entity to check * @return int <0 if KO, 0 if not used, >0 if already used */ - public function isObjectUsed($id = 0) + public function isObjectUsed($id = 0, $entity = 0) { global $langs; @@ -4361,11 +4463,25 @@ abstract class CommonObject // Test if child exists $haschild = 0; - foreach ($arraytoscan as $table => $elementname) { + foreach ($arraytoscan as $table => $element) { //print $id.'-'.$table.'-'.$elementname.'
    '; - // Check if third party can be deleted - $sql = "SELECT COUNT(*) as nb from ".MAIN_DB_PREFIX.$table; - $sql .= " WHERE ".$this->fk_element." = ".((int) $id); + // Check if element can be deleted + $sql = "SELECT COUNT(*) as nb"; + $sql.= " FROM ".$this->db->prefix().$table." as c"; + if (!empty($element['parent']) && !empty($element['parentkey'])) { + $sql.= ", ".$this->db->prefix().$element['parent']." as p"; + } + $sql.= " WHERE c.".$this->fk_element." = ".((int) $id); + if (!empty($element['parent']) && !empty($element['parentkey'])) { + $sql.= " AND c.".$element['parentkey']." = p.rowid"; + } + if (!empty($entity)) { + if (!empty($element['parent']) && !empty($element['parentkey'])) { + $sql.= " AND p.entity = ".((int) $entity); + } else { + $sql.= " AND c.entity = ".((int) $entity); + } + } $resql = $this->db->query($sql); if ($resql) { $obj = $this->db->fetch_object($resql); @@ -4373,11 +4489,12 @@ abstract class CommonObject $langs->load("errors"); //print 'Found into table '.$table.', type '.$langs->transnoentitiesnoconv($elementname).', haschild='.$haschild; $haschild += $obj->nb; - if (is_numeric($elementname)) { // old usage - $this->errors[] = $langs->transnoentities("ErrorRecordHasAtLeastOneChildOfType", method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref, $table); - } else // new usage: $elementname=Translation key - { - $this->errors[] = $langs->transnoentities("ErrorRecordHasAtLeastOneChildOfType", method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref, $langs->transnoentitiesnoconv($elementname)); + if (is_numeric($element)) { // very old usage array('table1', 'table2', ...) + $this->errors[] = $langs->transnoentitiesnoconv("ErrorRecordHasAtLeastOneChildOfType", method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref, $table); + } elseif (is_string($element)) { // old usage array('table1' => 'TranslateKey1', 'table2' => 'TranslateKey2', ...) + $this->errors[] = $langs->transnoentitiesnoconv("ErrorRecordHasAtLeastOneChildOfType", method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref, $langs->transnoentitiesnoconv($element)); + } else { // new usage: $element['name']=Translation key + $this->errors[] = $langs->transnoentitiesnoconv("ErrorRecordHasAtLeastOneChildOfType", method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref, $langs->transnoentitiesnoconv($element['name'])); } break; // We found at least one, we stop here } @@ -4440,7 +4557,7 @@ abstract class CommonObject $total_discount = 0.00; $sql = "SELECT subprice as pu_ht, qty, remise_percent, total_ht"; - $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element_line; + $sql .= " FROM ".$this->db->prefix().$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); dol_syslog(get_class($this).'::getTotalDiscount', LOG_DEBUG); @@ -4580,7 +4697,7 @@ abstract class CommonObject $extraparams = (!empty($this->extraparams) ? json_encode($this->extraparams) : null); - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql = "UPDATE ".$this->db->prefix().$this->table_element; $sql .= " SET extraparams = ".(!empty($extraparams) ? "'".$this->db->escape($extraparams)."'" : "null"); $sql .= " WHERE rowid = ".((int) $this->id); @@ -4774,7 +4891,7 @@ abstract class CommonObject $product_static->fetch($line->fk_product); $product_static->ref = $line->ref; //can change ref in hook - $product_static->label = $line->label; //can change label in hook + $product_static->label = !empty($line->label) ? $line->label : ""; //can change label in hook $text = $product_static->getNomUrl(1); @@ -4810,7 +4927,7 @@ abstract class CommonObject $description .= (!empty($conf->global->PRODUIT_DESC_IN_FORM) ? '' : dol_htmlentitiesbr($line->description)); // Description is what to show on popup. We shown nothing if already into desc. } - $line->pu_ttc = price2num($line->subprice * (1 + ($line->tva_tx / 100)), 'MU'); + $line->pu_ttc = price2num((!empty($line->subprice) ? $line->subprice : 0) * (1 + ((!empty($line->tva_tx) ? $line->tva_tx : 0) / 100)), 'MU'); // Output template part (modules that overwrite templates must declare this into descriptor) // Use global variables + $dateSelector + $seller and $buyer @@ -4894,6 +5011,7 @@ abstract class CommonObject print ''.$langs->trans('Unit').''; } print ''.$langs->trans('ReductionShort').''; + print ''.$langs->trans('TotalHT').''; print ''.$form->showCheckAddButtons('checkforselect', 1).''; print ''; $i = 0; @@ -5024,6 +5142,7 @@ abstract class CommonObject } $this->tpl['price'] = price($line->subprice); + $this->tpl['total_ht'] = price($line->total_ht); $this->tpl['multicurrency_price'] = price($line->multicurrency_subprice); $this->tpl['qty'] = (($line->info_bits & 2) != 2) ? $line->qty : ' '; if (!empty($conf->global->PRODUCT_USE_UNITS)) { @@ -5075,7 +5194,7 @@ abstract class CommonObject // phpcs:enable $this->db->begin(); - $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_resources ("; + $sql = "INSERT INTO ".$this->db->prefix()."element_resources ("; $sql .= "resource_id"; $sql .= ", resource_type"; $sql .= ", element_id"; @@ -5118,7 +5237,7 @@ abstract class CommonObject $this->db->begin(); - $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_resources"; + $sql = "DELETE FROM ".$this->db->prefix()."element_resources"; $sql .= " WHERE rowid = ".((int) $rowid); dol_syslog(get_class($this)."::delete_resource", LOG_DEBUG); @@ -5326,16 +5445,20 @@ abstract class CommonObject return 1; } else { $outputlangs->charset_output = $sav_charset_output; - dol_print_error($this->db, "Error generating document for ".__CLASS__.". Error: ".$obj->error, $obj->errors); + $this->error = $obj->error; + $this->errors = $obj->errors; + dol_syslog("Error generating document for ".__CLASS__.". Error: ".$obj->error, LOG_ERR); return -1; } } else { if (!$filefound) { $this->error = $langs->trans("Error").' Failed to load doc generator with modelpaths='.$modelspath.' - modele='.$modele; - dol_print_error('', $this->error); + $this->errors[] = $this->error; + dol_syslog($this->error, LOG_ERR); } else { $this->error = $langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists", $filefound); - dol_print_error('', $this->error); + $this->errors[] = $this->error; + dol_syslog($this->error, LOG_ERR); } return -1; } @@ -5437,7 +5560,7 @@ abstract class CommonObject //var_dump($obj->update_main_doc_field);exit; if ($update_main_doc_field && !empty($this->table_element)) { - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET last_main_doc = '".$this->db->escape($ecmfile->filepath."/".$ecmfile->filename)."'"; + $sql = "UPDATE ".$this->db->prefix().$this->table_element." SET last_main_doc = '".$this->db->escape($ecmfile->filepath."/".$ecmfile->filename)."'"; $sql .= " WHERE rowid = ".((int) $this->id); $resql = $this->db->query($sql); @@ -5548,7 +5671,10 @@ abstract class CommonObject { // phpcs:enable global $langs, $conf; - + if (!empty(self::TRIGGER_PREFIX) && strpos($triggerName, self::TRIGGER_PREFIX . '_') !== 0) { + dol_print_error('', 'The trigger "' . $triggerName . '" does not start with "' . self::TRIGGER_PREFIX . '_" as required.'); + exit; + } if (!is_object($langs)) { // If lang was not defined, we set it. It is required by run_triggers. include_once DOL_DOCUMENT_ROOT.'/core/class/translate.class.php'; $langs = new Translate('', $conf); @@ -5601,7 +5727,7 @@ abstract class CommonObject // Request to get translation values for object $sql = "SELECT rowid, property, lang , value"; - $sql .= " FROM ".MAIN_DB_PREFIX."object_lang"; + $sql .= " FROM ".$this->db->prefix()."object_lang"; $sql .= " WHERE type_object = '".$this->db->escape($element)."'"; $sql .= " AND fk_object = ".((int) $this->id); @@ -5690,11 +5816,11 @@ abstract class CommonObject if (in_array($key_type, array('date'))) { // Clean parameters // TODO GMT date in memory must be GMT so we should add gm=true in parameters - $value_key = dol_mktime(0, 0, 0, $_POST[$postfieldkey."month"], $_POST[$postfieldkey."day"], $_POST[$postfieldkey."year"]); + $value_key = dol_mktime(0, 0, 0, GETPOST($postfieldkey."month", 'int'), GETPOST($postfieldkey."day", 'int'), GETPOST($postfieldkey."year", 'int')); } elseif (in_array($key_type, array('datetime'))) { // Clean parameters // TODO GMT date in memory must be GMT so we should add gm=true in parameters - $value_key = dol_mktime($_POST[$postfieldkey."hour"], $_POST[$postfieldkey."min"], 0, $_POST[$postfieldkey."month"], $_POST[$postfieldkey."day"], $_POST[$postfieldkey."year"]); + $value_key = dol_mktime(GETPOST($postfieldkey."hour", 'int'), GETPOST($postfieldkey."min", 'int'), 0, GETPOST($postfieldkey."month", 'int'), GETPOST($postfieldkey."day", 'int'), GETPOST($postfieldkey."year", 'int')); } elseif (in_array($key_type, array('checkbox', 'chkbxlst'))) { $value_arr = GETPOST($postfieldkey, 'array'); // check if an array if (!empty($value_arr)) { @@ -5806,7 +5932,7 @@ abstract class CommonObject $sql .= ", ".$name; } } - $sql .= " FROM ".MAIN_DB_PREFIX.$table_element."_extrafields"; + $sql .= " FROM ".$this->db->prefix().$table_element."_extrafields"; $sql .= " WHERE fk_object = ".((int) $rowid); //dol_syslog(get_class($this)."::fetch_optionals get extrafields data for ".$this->table_element, LOG_DEBUG); // Too verbose @@ -5880,7 +6006,7 @@ abstract class CommonObject dol_syslog(get_class($this)."::deleteExtraFields delete", LOG_DEBUG); - $sql_del = "DELETE FROM ".MAIN_DB_PREFIX.$table_element."_extrafields WHERE fk_object = ".((int) $this->id); + $sql_del = "DELETE FROM ".$this->db->prefix().$table_element."_extrafields WHERE fk_object = ".((int) $this->id); $resql = $this->db->query($sql_del); if (!$resql) { @@ -6087,10 +6213,10 @@ abstract class CommonObject dol_syslog(get_class($this)."::insertExtraFields delete then insert", LOG_DEBUG); - $sql_del = "DELETE FROM ".MAIN_DB_PREFIX.$table_element."_extrafields WHERE fk_object = ".((int) $this->id); + $sql_del = "DELETE FROM ".$this->db->prefix().$table_element."_extrafields WHERE fk_object = ".((int) $this->id); $this->db->query($sql_del); - $sql = "INSERT INTO ".MAIN_DB_PREFIX.$table_element."_extrafields (fk_object"; + $sql = "INSERT INTO ".$this->db->prefix().$table_element."_extrafields (fk_object"; foreach ($new_array_options as $key => $value) { $attributeKey = substr($key, 8); // Remove 'options_' prefix // Add field of attribut @@ -6238,13 +6364,13 @@ abstract class CommonObject foreach ($new_array_languages as $key => $langcodearray) { // $key = 'name', 'town', ... foreach ($langcodearray as $langcode => $value) { - $sql_del = "DELETE FROM ".MAIN_DB_PREFIX."object_lang"; + $sql_del = "DELETE FROM ".$this->db->prefix()."object_lang"; $sql_del .= " WHERE fk_object = ".((int) $this->id)." AND property = '".$this->db->escape($key)."' AND type_object = '".$this->db->escape($table_element)."'"; $sql_del .= " AND lang = '".$this->db->escape($langcode)."'"; $this->db->query($sql_del); if ($value !== '') { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."object_lang (fk_object, property, type_object, lang, value"; + $sql = "INSERT INTO ".$this->db->prefix()."object_lang (fk_object, property, type_object, lang, value"; $sql .= ") VALUES (".$this->id.", '".$this->db->escape($key)."', '".$this->db->escape($table_element)."', '".$this->db->escape($langcode)."', '".$this->db->escape($value)."'"; $sql .= ")"; @@ -6428,7 +6554,7 @@ abstract class CommonObject $linealreadyfound = 0; // Check if there is already a line for this object (in most cases, it is, but sometimes it is not, for example when extra field has been created after), so we must keep this overload) - $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX.$this->table_element."_extrafields WHERE fk_object = ".((int) $this->id); + $sql = "SELECT COUNT(rowid) as nb FROM ".$this->db->prefix().$this->table_element."_extrafields WHERE fk_object = ".((int) $this->id); $resql = $this->db->query($sql); if ($resql) { $tmpobj = $this->db->fetch_object($resql); @@ -6439,9 +6565,9 @@ abstract class CommonObject if ($linealreadyfound) { if ($this->array_options["options_".$key] === null) { - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element."_extrafields SET ".$key." = null"; + $sql = "UPDATE ".$this->db->prefix().$this->table_element."_extrafields SET ".$key." = null"; } else { - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element."_extrafields SET ".$key." = '".$this->db->escape($this->array_options["options_".$key])."'"; + $sql = "UPDATE ".$this->db->prefix().$this->table_element."_extrafields SET ".$key." = '".$this->db->escape($this->array_options["options_".$key])."'"; } $sql .= " WHERE fk_object = ".((int) $this->id); } else { @@ -6637,7 +6763,7 @@ abstract class CommonObject // Add validation state class if (!empty($validationClass)) { - $morecss.= ' '.$validationClass; + $morecss.= $validationClass; } if (in_array($type, array('date'))) { @@ -6686,7 +6812,7 @@ abstract class CommonObject if (!preg_match('/search_/', $keyprefix)) { // If keyprefix is search_ or search_options_, we must just use a simple text field require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $doleditor = new DolEditor($keyprefix.$key.$keysuffix, $value, '', 200, 'dolibarr_notes', 'In', false, false, !empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE, ROWS_5, '90%'); - $out = $doleditor->Create(1); + $out = $doleditor->Create(1, '', true, '', '', $moreparam, $morecss); } else { $out = ''; } @@ -6723,7 +6849,7 @@ abstract class CommonObject if ((string) $key == '') { continue; } - list($val, $parent) = explode('|', $val); + if (strpos($val, "|") !== false) list($val, $parent) = explode('|', $val); $out .= '